From ccc00f913d08a64446bedb10b677e274dda54a62 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Tue, 27 Sep 2016 05:15:28 -0400 Subject: [PATCH] Resources: Update interface to support errors This was an early interface mistake I made and is now corrected. We'll plumb in checking the error state of Init() and running Validate() later on. --- resources/exec.go | 14 +++++++------- resources/file.go | 4 ++-- resources/noop.go | 8 ++++---- resources/pkg.go | 29 +++++++++++++---------------- resources/resources.go | 7 ++++--- resources/svc.go | 12 ++++++------ resources/timer.go | 8 ++++---- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/resources/exec.go b/resources/exec.go index 8406d58d..a1938088 100644 --- a/resources/exec.go +++ b/resources/exec.go @@ -71,24 +71,24 @@ func NewExecRes(name, cmd, shell string, timeout int, watchcmd, watchshell, ifcm } // Init runs some startup code for this resource. -func (obj *ExecRes) Init() { +func (obj *ExecRes) Init() error { obj.BaseRes.kind = "Exec" - obj.BaseRes.Init() // call base init, b/c we're overriding + return obj.BaseRes.Init() // call base init, b/c we're overriding } -// validate if the params passed in are valid data +// Validate if the params passed in are valid data. // FIXME: where should this get called ? -func (obj *ExecRes) Validate() bool { +func (obj *ExecRes) Validate() error { if obj.Cmd == "" { // this is the only thing that is really required - return false + return fmt.Errorf("Command can't be empty!") } // if we have a watch command, then we don't poll with the if command! if obj.WatchCmd != "" && obj.PollInt > 0 { - return false + return fmt.Errorf("Don't poll when we have a watch command.") } - return true + return nil } // wraps the scanner output in a channel diff --git a/resources/file.go b/resources/file.go index 7346d6c9..fc55392a 100644 --- a/resources/file.go +++ b/resources/file.go @@ -84,7 +84,7 @@ func NewFileRes(name, path, dirname, basename, content, source, state string, re } // Init runs some startup code for this resource. -func (obj *FileRes) Init() { +func (obj *FileRes) Init() error { obj.sha256sum = "" obj.watches = make(map[string]struct{}) if obj.Path == "" { // use the name as the path default if missing @@ -94,7 +94,7 @@ func (obj *FileRes) Init() { obj.isDir = strings.HasSuffix(obj.path, "/") // dirs have trailing slashes obj.BaseRes.kind = "File" - obj.BaseRes.Init() // call base init, b/c we're overriding + return obj.BaseRes.Init() // call base init, b/c we're overriding } // GetPath returns the actual path to use for this resource. It computes this diff --git a/resources/noop.go b/resources/noop.go index 6cc51df4..7ff3f1cc 100644 --- a/resources/noop.go +++ b/resources/noop.go @@ -48,15 +48,15 @@ func NewNoopRes(name string) *NoopRes { } // Init runs some startup code for this resource. -func (obj *NoopRes) Init() { +func (obj *NoopRes) Init() error { obj.BaseRes.kind = "Noop" - obj.BaseRes.Init() // call base init, b/c we're overriding + return obj.BaseRes.Init() // call base init, b/c we're overriding } // validate if the params passed in are valid data // FIXME: where should this get called ? -func (obj *NoopRes) Validate() bool { - return true +func (obj *NoopRes) Validate() error { + return nil } // Watch is the primary listener for this resource and it outputs events. diff --git a/resources/pkg.go b/resources/pkg.go index c112fe77..ea5d3a1b 100644 --- a/resources/pkg.go +++ b/resources/pkg.go @@ -58,55 +58,52 @@ func NewPkgRes(name, state string, allowuntrusted, allownonfree, allowunsupporte AllowNonFree: allownonfree, AllowUnsupported: allowunsupported, } - obj.Init() + obj.Init() // XXX: on error return nil, or separate error return? return obj } // Init runs some startup code for this resource. -func (obj *PkgRes) Init() { +func (obj *PkgRes) Init() error { obj.BaseRes.kind = "Pkg" - obj.BaseRes.Init() // 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 + } bus := packagekit.NewBus() if bus == nil { - log.Fatal("Can't connect to PackageKit bus.") + return fmt.Errorf("Can't connect to PackageKit bus.") } defer bus.Close() result, err := obj.pkgMappingHelper(bus) if err != nil { - // FIXME: return error? - log.Fatalf("The pkgMappingHelper failed with: %v.", err) - return + return fmt.Errorf("The pkgMappingHelper failed with: %v.", err) } data, ok := result[obj.Name] // lookup single package (init does just one) // package doesn't exist, this is an error! if !ok || !data.Found { - // FIXME: return error? - log.Fatalf("Can't find package named '%s'.", obj.Name) - return + return fmt.Errorf("Can't find package named '%s'.", obj.Name) } packageIDs := []string{data.PackageID} // just one for now filesMap, err := bus.GetFilesByPackageID(packageIDs) if err != nil { - // FIXME: return error? - log.Fatalf("Can't run GetFilesByPackageID: %v", err) - return + return fmt.Errorf("Can't run GetFilesByPackageID: %v", err) } if files, ok := filesMap[data.PackageID]; ok { obj.fileList = util.DirifyFileList(files, false) } + return nil } // Validate checks if the resource data structure was populated correctly. -func (obj *PkgRes) Validate() bool { +func (obj *PkgRes) Validate() error { if obj.State == "" { - return false + return fmt.Errorf("State cannot be empty!") } - return true + return nil } // Watch is the primary listener for this resource and it outputs events. diff --git a/resources/resources.go b/resources/resources.go index ff956d99..2d57a709 100644 --- a/resources/resources.go +++ b/resources/resources.go @@ -104,8 +104,8 @@ type Base interface { // Res is the minimum interface you need to implement to define a new resource. type Res interface { Base // include everything from the Base interface - Init() - //Validate() bool // TODO: this might one day be added + Init() error + //Validate() error // TODO: this might one day be added GetUUIDs() []ResUUID // most resources only return one Watch(chan event.Event) error // send on channel to signal process() events CheckApply(bool) (bool, error) @@ -170,8 +170,9 @@ func (obj *BaseUUID) Reversed() bool { } // Init initializes structures like channels if created without New constructor. -func (obj *BaseRes) Init() { +func (obj *BaseRes) Init() error { obj.events = make(chan event.Event) // unbuffered chan size to avoid stale events + return nil } // GetName is used by all the resources to Get the name. diff --git a/resources/svc.go b/resources/svc.go index ca28d541..37b3c76e 100644 --- a/resources/svc.go +++ b/resources/svc.go @@ -59,20 +59,20 @@ func NewSvcRes(name, state, startup string) *SvcRes { } // Init runs some startup code for this resource. -func (obj *SvcRes) Init() { +func (obj *SvcRes) Init() error { obj.BaseRes.kind = "Svc" - obj.BaseRes.Init() // call base init, b/c we're overriding + return obj.BaseRes.Init() // call base init, b/c we're overriding } // Validate checks if the resource data structure was populated correctly. -func (obj *SvcRes) Validate() bool { +func (obj *SvcRes) Validate() error { if obj.State != "running" && obj.State != "stopped" && obj.State != "" { - return false + return fmt.Errorf("State must be either `running` or `stopped` or undefined.") } if obj.Startup != "enabled" && obj.Startup != "disabled" && obj.Startup != "" { - return false + return fmt.Errorf("Startup must be either `enabled` or `disabled` or undefined.") } - return true + return nil } // Watch is the primary listener for this resource and it outputs events. diff --git a/resources/timer.go b/resources/timer.go index 89c9dbc6..829e9dfb 100644 --- a/resources/timer.go +++ b/resources/timer.go @@ -54,16 +54,16 @@ func NewTimerRes(name string, interval int) *TimerRes { } // Init runs some startup code for this resource. -func (obj *TimerRes) Init() { +func (obj *TimerRes) Init() error { obj.BaseRes.kind = "Timer" - obj.BaseRes.Init() // call base init, b/c we're overrriding + return obj.BaseRes.Init() // call base init, b/c we're overrriding } // Validate the params that are passed to TimerRes // Currently we are getting only an interval in seconds // which gets validated by go compiler -func (obj *TimerRes) Validate() bool { - return true +func (obj *TimerRes) Validate() error { + return nil } // Watch is the primary listener for this resource and it outputs events.