resources: Unify resource creation and kind setting
This removes the duplication of the kind string and cleans up things for resource creation.
This commit is contained in:
@@ -73,14 +73,13 @@ Init() error
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is called to initialize the resource. If something goes wrong, it should
|
This is called to initialize the resource. If something goes wrong, it should
|
||||||
return an error. It should set the resource `kind`, do any resource specific
|
return an error. It should do any resource specific work, and finish by calling
|
||||||
work, and finish by calling the `Init` method of the base resource.
|
the `Init` method of the base resource.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
```golang
|
```golang
|
||||||
// Init initializes the Foo resource.
|
// Init initializes the Foo resource.
|
||||||
func (obj *FooRes) Init() error {
|
func (obj *FooRes) Init() error {
|
||||||
obj.BaseRes.Kind = "foo" // must lower case resource kind
|
|
||||||
// run the resource specific initialization, and error if anything fails
|
// run the resource specific initialization, and error if anything fails
|
||||||
if some_error {
|
if some_error {
|
||||||
return err // something went wrong!
|
return err // something went wrong!
|
||||||
@@ -399,9 +398,9 @@ UnmarshalYAML(unmarshal func(interface{}) error) error // optional
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is optional, but recommended for any resource that will have a YAML
|
This is optional, but recommended for any resource that will have a YAML
|
||||||
accessible struct, and an entry in the `GraphConfig` struct. It is not required
|
accessible struct. It is not required because to do so would mean that
|
||||||
because to do so would mean that third-party or custom resources (such as those
|
third-party or custom resources (such as those someone writes to use with
|
||||||
someone writes to use with `libmgmt`) would have to implement this needlessly.
|
`libmgmt`) would have to implement this needlessly.
|
||||||
|
|
||||||
The signature intentionally matches what is required to satisfy the `go-yaml`
|
The signature intentionally matches what is required to satisfy the `go-yaml`
|
||||||
[Unmarshaler](https://godoc.org/gopkg.in/yaml.v2#Unmarshaler) interface.
|
[Unmarshaler](https://godoc.org/gopkg.in/yaml.v2#Unmarshaler) interface.
|
||||||
@@ -453,35 +452,15 @@ type FooRes struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### YAML
|
### Resource registration
|
||||||
In addition to labelling your resource struct with YAML fields, you must also
|
All resources must be registered with the engine so that they can be found. This
|
||||||
add an entry to the internal `GraphConfig` struct. It is a fairly straight
|
also ensures they can be encoded and decoded. Make sure to include the following
|
||||||
forward one line patch.
|
code snippet for this to work.
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type GraphConfig struct {
|
|
||||||
// [snip...]
|
|
||||||
Resources struct {
|
|
||||||
Noop []*resources.NoopRes `yaml:"noop"`
|
|
||||||
File []*resources.FileRes `yaml:"file"`
|
|
||||||
// [snip...]
|
|
||||||
Foo []*resources.FooRes `yaml:"foo"` // tada :)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
It's also recommended that you add the [UnmarshalYAML](#unmarshalyaml) method to
|
|
||||||
your resources so that unspecified values are given sane defaults.
|
|
||||||
|
|
||||||
### Gob registration
|
|
||||||
All resources must be registered with the `golang` _gob_ module so that they can
|
|
||||||
be encoded and decoded. Make sure to include the following code snippet for this
|
|
||||||
to work.
|
|
||||||
|
|
||||||
```golang
|
|
||||||
import "encoding/gob"
|
|
||||||
func init() { // special golang method that runs once
|
func init() { // special golang method that runs once
|
||||||
gob.Register(&FooRes{}) // substitude your resource here
|
// set your resource kind and struct here (the kind must be lower case)
|
||||||
|
RegisterResource("foo", func() Res { return &FooRes{} })
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ func GetResources(obj *EmbdEtcd, hostnameFilter, kindFilter []string) ([]resourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if obj, err := resources.B64ToRes(val); err == nil {
|
if obj, err := resources.B64ToRes(val); err == nil {
|
||||||
obj.SetKind(kind) // cheap init
|
|
||||||
log.Printf("Etcd: Get: (Hostname, Kind, Name): (%s, %s, %s)", hostname, kind, name)
|
log.Printf("Etcd: Get: (Hostname, Kind, Name): (%s, %s, %s)", hostname, kind, name)
|
||||||
resourceList = append(resourceList, obj)
|
resourceList = append(resourceList, obj)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -61,12 +61,12 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these are being specified temporarily until it's the default!
|
|
||||||
metaparams := resources.DefaultMetaParams
|
metaparams := resources.DefaultMetaParams
|
||||||
|
|
||||||
exec1 := &resources.ExecRes{
|
exec1 := &resources.ExecRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "exec1",
|
Name: "exec1",
|
||||||
|
Kind: "exec",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Cmd: "echo hello world && echo goodbye world 1>&2", // to stdout && stderr
|
Cmd: "echo hello world && echo goodbye world 1>&2", // to stdout && stderr
|
||||||
@@ -77,6 +77,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
output := &resources.FileRes{
|
output := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "output",
|
Name: "output",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
// send->recv!
|
// send->recv!
|
||||||
Recv: map[string]*resources.Send{
|
Recv: map[string]*resources.Send{
|
||||||
@@ -92,6 +93,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
stdout := &resources.FileRes{
|
stdout := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "stdout",
|
Name: "stdout",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
// send->recv!
|
// send->recv!
|
||||||
Recv: map[string]*resources.Send{
|
Recv: map[string]*resources.Send{
|
||||||
@@ -107,6 +109,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
stderr := &resources.FileRes{
|
stderr := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "stderr",
|
Name: "stderr",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
// send->recv!
|
// send->recv!
|
||||||
Recv: map[string]*resources.Send{
|
Recv: map[string]*resources.Send{
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ func (obj *MyGAPI) subGraph() (*pgraph.Graph, error) {
|
|||||||
f1 := &resources.FileRes{
|
f1 := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "file1",
|
Name: "file1",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Path: "/tmp/mgmt/sub1",
|
Path: "/tmp/mgmt/sub1",
|
||||||
@@ -74,6 +75,7 @@ func (obj *MyGAPI) subGraph() (*pgraph.Graph, error) {
|
|||||||
n1 := &resources.NoopRes{
|
n1 := &resources.NoopRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "noop1",
|
Name: "noop1",
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -93,7 +95,6 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these are being specified temporarily until it's the default!
|
|
||||||
metaparams := resources.DefaultMetaParams
|
metaparams := resources.DefaultMetaParams
|
||||||
|
|
||||||
content := "I created a subgraph!\n"
|
content := "I created a subgraph!\n"
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these are being specified temporarily until it's the default!
|
|
||||||
metaparams := resources.DefaultMetaParams
|
metaparams := resources.DefaultMetaParams
|
||||||
|
|
||||||
content := "I created a subgraph!\n"
|
content := "I created a subgraph!\n"
|
||||||
f0 := &resources.FileRes{
|
f0 := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "README",
|
Name: "README",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Path: "/tmp/mgmt/README",
|
Path: "/tmp/mgmt/README",
|
||||||
@@ -86,6 +86,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
f1 := &resources.FileRes{
|
f1 := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "file1",
|
Name: "file1",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Path: "/tmp/mgmt/sub1",
|
Path: "/tmp/mgmt/sub1",
|
||||||
@@ -97,6 +98,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
n1 := &resources.NoopRes{
|
n1 := &resources.NoopRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "noop1",
|
Name: "noop1",
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -110,6 +112,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
subGraphRes0 := &resources.GraphRes{ // TODO: should we name this SubGraphRes ?
|
subGraphRes0 := &resources.GraphRes{ // TODO: should we name this SubGraphRes ?
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "subgraph1",
|
Name: "subgraph1",
|
||||||
|
Kind: "graph",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Graph: subGraph,
|
Graph: subGraph,
|
||||||
|
|||||||
@@ -57,9 +57,11 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
return nil, fmt.Errorf("libmgmt: MyGAPI is not initialized")
|
return nil, fmt.Errorf("libmgmt: MyGAPI is not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this method of instantiation is deprecated, use: NewResource
|
||||||
n1 := &resources.NoopRes{
|
n1 := &resources.NoopRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "noop1",
|
Name: "noop1",
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: resources.DefaultMetaParams,
|
MetaParams: resources.DefaultMetaParams,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,12 +65,11 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
}
|
}
|
||||||
var vertex pgraph.Vertex
|
var vertex pgraph.Vertex
|
||||||
for i := uint(0); i < obj.Count; i++ {
|
for i := uint(0); i < obj.Count; i++ {
|
||||||
n := &resources.NoopRes{
|
n, err := resources.NewResource("noop")
|
||||||
BaseRes: resources.BaseRes{
|
if err != nil {
|
||||||
Name: fmt.Sprintf("noop%d", i),
|
return nil, err
|
||||||
MetaParams: resources.DefaultMetaParams,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
n.SetName(fmt.Sprintf("noop%d", i))
|
||||||
g.AddVertex(n)
|
g.AddVertex(n)
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
g.AddEdge(vertex, n, &resources.Edge{Name: fmt.Sprintf("e%d", i)})
|
g.AddEdge(vertex, n, &resources.Edge{Name: fmt.Sprintf("e%d", i)})
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these are being specified temporarily until it's the default!
|
|
||||||
metaparams := resources.DefaultMetaParams
|
metaparams := resources.DefaultMetaParams
|
||||||
|
|
||||||
content := "Delete me to trigger a notification!\n"
|
content := "Delete me to trigger a notification!\n"
|
||||||
f0 := &resources.FileRes{
|
f0 := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "README",
|
Name: "README",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Path: "/tmp/mgmt/README",
|
Path: "/tmp/mgmt/README",
|
||||||
@@ -80,6 +80,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
p1 := &resources.PasswordRes{
|
p1 := &resources.PasswordRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "password1",
|
Name: "password1",
|
||||||
|
Kind: "password",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
Length: 8, // generated string will have this many characters
|
Length: 8, // generated string will have this many characters
|
||||||
@@ -90,6 +91,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
f1 := &resources.FileRes{
|
f1 := &resources.FileRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "file1",
|
Name: "file1",
|
||||||
|
Kind: "file",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
// send->recv!
|
// send->recv!
|
||||||
Recv: map[string]*resources.Send{
|
Recv: map[string]*resources.Send{
|
||||||
@@ -106,6 +108,7 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
n1 := &resources.NoopRes{
|
n1 := &resources.NoopRes{
|
||||||
BaseRes: resources.BaseRes{
|
BaseRes: resources.BaseRes{
|
||||||
Name: "noop1",
|
Name: "noop1",
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: metaparams,
|
MetaParams: metaparams,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -39,7 +38,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(&AugeasRes{})
|
|
||||||
RegisterResource("augeas", func() Res { return &AugeasRes{} })
|
RegisterResource("augeas", func() Res { return &AugeasRes{} })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +92,6 @@ func (obj *AugeasRes) Validate() error {
|
|||||||
|
|
||||||
// Init initiates the resource.
|
// Init initiates the resource.
|
||||||
func (obj *AugeasRes) Init() error {
|
func (obj *AugeasRes) Init() error {
|
||||||
obj.BaseRes.Kind = "augeas"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ func NewNoopResTest(name string) *NoopResTest {
|
|||||||
NoopRes: NoopRes{
|
NoopRes: NoopRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: MetaParams{
|
MetaParams: MetaParams{
|
||||||
AutoGroup: true, // always autogroup
|
AutoGroup: true, // always autogroup
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package resources
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -34,7 +33,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(&ExecRes{})
|
|
||||||
RegisterResource("exec", func() Res { return &ExecRes{} })
|
RegisterResource("exec", func() Res { return &ExecRes{} })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +71,6 @@ func (obj *ExecRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *ExecRes) Init() error {
|
func (obj *ExecRes) Init() error {
|
||||||
obj.BaseRes.Kind = "exec"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ func TestExecSendRecv1(t *testing.T) {
|
|||||||
r1 := &ExecRes{
|
r1 := &ExecRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: "exec1",
|
Name: "exec1",
|
||||||
|
Kind: "exec",
|
||||||
//MetaParams: MetaParams,
|
//MetaParams: MetaParams,
|
||||||
},
|
},
|
||||||
Cmd: "echo hello world",
|
Cmd: "echo hello world",
|
||||||
@@ -71,6 +72,7 @@ func TestExecSendRecv2(t *testing.T) {
|
|||||||
r1 := &ExecRes{
|
r1 := &ExecRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: "exec1",
|
Name: "exec1",
|
||||||
|
Kind: "exec",
|
||||||
//MetaParams: MetaParams,
|
//MetaParams: MetaParams,
|
||||||
},
|
},
|
||||||
Cmd: "echo hello world 1>&2", // to stderr
|
Cmd: "echo hello world 1>&2", // to stderr
|
||||||
@@ -117,6 +119,7 @@ func TestExecSendRecv3(t *testing.T) {
|
|||||||
r1 := &ExecRes{
|
r1 := &ExecRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: "exec1",
|
Name: "exec1",
|
||||||
|
Kind: "exec",
|
||||||
//MetaParams: MetaParams,
|
//MetaParams: MetaParams,
|
||||||
},
|
},
|
||||||
Cmd: "echo hello world && echo goodbye world 1>&2", // to stdout && stderr
|
Cmd: "echo hello world && echo goodbye world 1>&2", // to stdout && stderr
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package resources
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/gob"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -41,7 +40,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(&FileRes{})
|
|
||||||
RegisterResource("file", func() Res { return &FileRes{} })
|
RegisterResource("file", func() Res { return &FileRes{} })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +146,6 @@ func (obj *FileRes) Init() error {
|
|||||||
obj.path = obj.GetPath() // compute once
|
obj.path = obj.GetPath() // compute once
|
||||||
obj.isDir = strings.HasSuffix(obj.path, "/") // dirs have trailing slashes
|
obj.isDir = strings.HasSuffix(obj.path, "/") // dirs have trailing slashes
|
||||||
|
|
||||||
obj.BaseRes.Kind = "file"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
@@ -29,7 +28,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("graph", func() Res { return &GraphRes{} })
|
RegisterResource("graph", func() Res { return &GraphRes{} })
|
||||||
gob.Register(&GraphRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphRes is a resource that recursively runs a sub graph of resources.
|
// GraphRes is a resource that recursively runs a sub graph of resources.
|
||||||
@@ -89,7 +87,6 @@ func (obj *GraphRes) Init() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.BaseRes.Kind = "graph"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -36,7 +35,6 @@ var ErrResourceInsufficientParameters = errors.New(
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("hostname", func() Res { return &HostnameRes{} })
|
RegisterResource("hostname", func() Res { return &HostnameRes{} })
|
||||||
gob.Register(&HostnameRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -88,7 +86,6 @@ func (obj *HostnameRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *HostnameRes) Init() error {
|
func (obj *HostnameRes) Init() error {
|
||||||
obj.BaseRes.Kind = "hostname"
|
|
||||||
if obj.PrettyHostname == "" {
|
if obj.PrettyHostname == "" {
|
||||||
obj.PrettyHostname = obj.Hostname
|
obj.PrettyHostname = obj.Hostname
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -28,7 +27,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("kv", func() Res { return &KVRes{} })
|
RegisterResource("kv", func() Res { return &KVRes{} })
|
||||||
gob.Register(&KVRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// KVResSkipCmpStyle represents the different styles of comparison when using SkipLessThan.
|
// KVResSkipCmpStyle represents the different styles of comparison when using SkipLessThan.
|
||||||
@@ -89,7 +87,6 @@ func (obj *KVRes) Validate() error {
|
|||||||
|
|
||||||
// Init initializes the resource.
|
// Init initializes the resource.
|
||||||
func (obj *KVRes) Init() error {
|
func (obj *KVRes) Init() error {
|
||||||
obj.BaseRes.Kind = "kv"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -29,7 +28,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("msg", func() Res { return &MsgRes{} })
|
RegisterResource("msg", func() Res { return &MsgRes{} })
|
||||||
gob.Register(&MsgRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgRes is a resource that writes messages to logs.
|
// MsgRes is a resource that writes messages to logs.
|
||||||
@@ -76,7 +74,6 @@ func (obj *MsgRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *MsgRes) Init() error {
|
func (obj *MsgRes) Init() error {
|
||||||
obj.BaseRes.Kind = "msg"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,12 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("noop", func() Res { return &NoopRes{} })
|
RegisterResource("noop", func() Res { return &NoopRes{} })
|
||||||
gob.Register(&NoopRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoopRes is a no-op resource that does nothing.
|
// NoopRes is a no-op resource that does nothing.
|
||||||
@@ -50,7 +48,6 @@ func (obj *NoopRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *NoopRes) Init() error {
|
func (obj *NoopRes) Init() error {
|
||||||
obj.BaseRes.Kind = "noop"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -42,7 +41,6 @@ const (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("nspawn", func() Res { return &NspawnRes{} })
|
RegisterResource("nspawn", func() Res { return &NspawnRes{} })
|
||||||
gob.Register(&NspawnRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NspawnRes is an nspawn container resource.
|
// NspawnRes is an nspawn container resource.
|
||||||
@@ -93,7 +91,6 @@ func (obj *NspawnRes) Init() error {
|
|||||||
if err := obj.svc.Init(); err != nil {
|
if err := obj.svc.Init(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
obj.BaseRes.Kind = "nspawn"
|
|
||||||
return obj.BaseRes.Init()
|
return obj.BaseRes.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package resources
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@@ -35,7 +34,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("password", func() Res { return &PasswordRes{} })
|
RegisterResource("password", func() Res { return &PasswordRes{} })
|
||||||
gob.Register(&PasswordRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -74,7 +72,6 @@ func (obj *PasswordRes) Validate() error {
|
|||||||
// Init generates a new password for this resource if one was not provided. It
|
// Init generates a new password for this resource if one was not provided. It
|
||||||
// will save this into a local file. It will load it back in from previous runs.
|
// will save this into a local file. It will load it back in from previous runs.
|
||||||
func (obj *PasswordRes) Init() error {
|
func (obj *PasswordRes) Init() error {
|
||||||
obj.BaseRes.Kind = "password" // must be set before using VarDir
|
|
||||||
|
|
||||||
dir, err := obj.VarDir("")
|
dir, err := obj.VarDir("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
@@ -32,7 +31,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("pkg", func() Res { return &PkgRes{} })
|
RegisterResource("pkg", func() Res { return &PkgRes{} })
|
||||||
gob.Register(&PkgRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PkgRes is a package resource for packagekit.
|
// PkgRes is a package resource for packagekit.
|
||||||
@@ -67,7 +65,6 @@ func (obj *PkgRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *PkgRes) Init() error {
|
func (obj *PkgRes) Init() error {
|
||||||
obj.BaseRes.Kind = "pkg"
|
|
||||||
if err := obj.BaseRes.Init(); err != nil { // call base init, b/c we're overriding
|
if err := obj.BaseRes.Init(); err != nil { // call base init, b/c we're overriding
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
@@ -43,18 +44,21 @@ var registeredResources = map[string]func() Res{}
|
|||||||
|
|
||||||
// RegisterResource registers a new resource by providing a constructor
|
// RegisterResource registers a new resource by providing a constructor
|
||||||
// function that returns a resource object ready to be unmarshalled from YAML.
|
// function that returns a resource object ready to be unmarshalled from YAML.
|
||||||
func RegisterResource(name string, creator func() Res) {
|
func RegisterResource(kind string, fn func() Res) {
|
||||||
registeredResources[name] = creator
|
gob.Register(fn())
|
||||||
|
registeredResources[kind] = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEmptyNamedResource returns an empty resource object from a registered
|
// NewResource returns an empty resource object from a registered kind.
|
||||||
// type, ready to be unmarshalled.
|
func NewResource(kind string) (Res, error) {
|
||||||
func NewEmptyNamedResource(name string) (Res, error) {
|
fn, ok := registeredResources[kind]
|
||||||
fn, ok := registeredResources[name]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("no resource named %s available", name)
|
return nil, fmt.Errorf("no resource kind `%s` available", kind)
|
||||||
}
|
}
|
||||||
return fn(), nil
|
res := fn().Default()
|
||||||
|
res.SetKind(kind)
|
||||||
|
//*res.Meta() = DefaultMetaParams // TODO: centralize this here?
|
||||||
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate stringer -type=ResState -output=resstate_stringer.go
|
//go:generate stringer -type=ResState -output=resstate_stringer.go
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ func TestCompare2(t *testing.T) {
|
|||||||
r1 := &NoopRes{
|
r1 := &NoopRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: "noop1",
|
Name: "noop1",
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: MetaParams{
|
MetaParams: MetaParams{
|
||||||
Noop: true,
|
Noop: true,
|
||||||
},
|
},
|
||||||
@@ -49,7 +50,8 @@ func TestCompare2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
r2 := &NoopRes{
|
r2 := &NoopRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: "noop1", // same nampe
|
Name: "noop1", // same name
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: MetaParams{
|
MetaParams: MetaParams{
|
||||||
Noop: false, // different noop
|
Noop: false, // different noop
|
||||||
},
|
},
|
||||||
@@ -111,12 +113,9 @@ func TestMiscEncodeDecode1(t *testing.T) {
|
|||||||
|
|
||||||
func TestMiscEncodeDecode2(t *testing.T) {
|
func TestMiscEncodeDecode2(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
//gob.Register( &NoopRes{} ) // happens in noop.go : init()
|
|
||||||
//gob.Register( &FileRes{} ) // happens in file.go : init()
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// encode
|
// encode
|
||||||
var input Res = &FileRes{}
|
input, _ := NewResource("file")
|
||||||
|
|
||||||
b64, err := ResToB64(input)
|
b64, err := ResToB64(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ func NewNoopResTestSema(name string, semas []string) *NoopResTest {
|
|||||||
NoopRes: NoopRes{
|
NoopRes: NoopRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Kind: "noop",
|
||||||
MetaParams: MetaParams{
|
MetaParams: MetaParams{
|
||||||
AutoGroup: true, // always autogroup
|
AutoGroup: true, // always autogroup
|
||||||
Sema: semas,
|
Sema: semas,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -34,7 +33,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("svc", func() Res { return &SvcRes{} })
|
RegisterResource("svc", func() Res { return &SvcRes{} })
|
||||||
gob.Register(&SvcRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SvcRes is a service resource for systemd units.
|
// SvcRes is a service resource for systemd units.
|
||||||
@@ -67,7 +65,6 @@ func (obj *SvcRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *SvcRes) Init() error {
|
func (obj *SvcRes) Init() error {
|
||||||
obj.BaseRes.Kind = "svc"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
@@ -26,7 +25,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("timer", func() Res { return &TimerRes{} })
|
RegisterResource("timer", func() Res { return &TimerRes{} })
|
||||||
gob.Register(&TimerRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimerRes is a timer resource for time based events.
|
// TimerRes is a timer resource for time based events.
|
||||||
@@ -59,7 +57,6 @@ func (obj *TimerRes) Validate() error {
|
|||||||
|
|
||||||
// Init runs some startup code for this resource.
|
// Init runs some startup code for this resource.
|
||||||
func (obj *TimerRes) Init() error {
|
func (obj *TimerRes) Init() error {
|
||||||
obj.BaseRes.Kind = "timer"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
return obj.BaseRes.Init() // call base init, b/c we're overrriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func B64ToRes(str string) (Res, error) {
|
|||||||
}
|
}
|
||||||
res, ok := output.(Res)
|
res, ok := output.(Res)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Output %v is not a Res", res)
|
return nil, fmt.Errorf("output `%v` is not a Res", output)
|
||||||
|
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package resources
|
package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -38,7 +37,6 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterResource("virt", func() Res { return &VirtRes{} })
|
RegisterResource("virt", func() Res { return &VirtRes{} })
|
||||||
gob.Register(&VirtRes{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -192,7 +190,6 @@ func (obj *VirtRes) Init() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj.wg = &sync.WaitGroup{}
|
obj.wg = &sync.WaitGroup{}
|
||||||
obj.BaseRes.Kind = "virt"
|
|
||||||
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
return obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,19 +55,18 @@ func (obj *MyGAPI) Graph() (*pgraph.Graph, error) {
|
|||||||
if !obj.initialized {
|
if !obj.initialized {
|
||||||
return nil, fmt.Errorf("%s: MyGAPI is not initialized", obj.Name)
|
return nil, fmt.Errorf("%s: MyGAPI is not initialized", obj.Name)
|
||||||
}
|
}
|
||||||
// FIXME: these are being specified temporarily until it's the default!
|
|
||||||
metaparams := resources.DefaultMetaParams
|
var err error
|
||||||
g, err := pgraph.NewGraph(obj.Name)
|
g, err := pgraph.NewGraph(obj.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
n0 := &resources.NoopRes{
|
n0, err := resources.NewResource("noop")
|
||||||
BaseRes: resources.BaseRes{
|
if err != nil {
|
||||||
Name: "noop1",
|
return nil, err
|
||||||
MetaParams: metaparams,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
n0.SetName("noop1")
|
||||||
g.AddVertex(n0)
|
g.AddVertex(n0)
|
||||||
|
|
||||||
//g, err := config.NewGraphFromConfig(obj.data.Hostname, obj.data.World, obj.data.Noop)
|
//g, err := config.NewGraphFromConfig(obj.data.Hostname, obj.data.World, obj.data.Noop)
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ func (r *Resource) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
// Decode is the second stage for unmarshaling of resources (knowing their
|
// Decode is the second stage for unmarshaling of resources (knowing their
|
||||||
// kind).
|
// kind).
|
||||||
func (r *Resource) Decode(kind string) (err error) {
|
func (r *Resource) Decode(kind string) (err error) {
|
||||||
r.resource, err = resources.NewEmptyNamedResource(kind)
|
r.resource, err = resources.NewResource(kind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,6 @@ func (r *Resource) Decode(kind string) (err error) {
|
|||||||
|
|
||||||
// Set resource name, meta and kind
|
// Set resource name, meta and kind
|
||||||
r.resource.SetName(r.Name)
|
r.resource.SetName(r.Name)
|
||||||
r.resource.SetKind(strings.ToLower(kind))
|
|
||||||
meta := r.resource.Meta()
|
meta := r.resource.Meta()
|
||||||
*meta = r.Meta
|
*meta = r.Meta
|
||||||
return
|
return
|
||||||
@@ -199,7 +198,6 @@ func (c *GraphConfig) NewGraphFromConfig(hostname string, world resources.World,
|
|||||||
} else if !noop { // do not export any resources if noop
|
} else if !noop { // do not export any resources if noop
|
||||||
// store for addition to backend storage...
|
// store for addition to backend storage...
|
||||||
res.SetName(res.GetName()[2:]) // slice off @@
|
res.SetName(res.GetName()[2:]) // slice off @@
|
||||||
res.SetKind(kind) // cheap init
|
|
||||||
resourceList = append(resourceList, res)
|
resourceList = append(resourceList, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user