diff --git a/runner/providers/common/common.go b/runner/providers/common/common.go index 41b50027..dfa49f0d 100644 --- a/runner/providers/common/common.go +++ b/runner/providers/common/common.go @@ -35,6 +35,7 @@ const ( RunnerActive RunnerStatus = "active" ) +// IsValidStatus checks if the given status is valid. func IsValidStatus(status InstanceStatus) bool { switch status { case InstanceRunning, InstanceError, InstancePendingCreate, @@ -46,3 +47,17 @@ func IsValidStatus(status InstanceStatus) bool { return false } } + +// IsProviderValidStatus checks if the given status is valid for the provider. +// A provider should only return a status indicating that the instance is in a +// lifecycle state that it can influence. The sole purpose of a provider is to +// manage the lifecycle of an instance. Statuses that indicate an instance should +// be created or removed, will be set by the controller. +func IsValidProviderStatus(status InstanceStatus) bool { + switch status { + case InstanceRunning, InstanceError, InstanceStopped: + return true + default: + return false + } +} diff --git a/runner/providers/external/external.go b/runner/providers/external/external.go index c8054da9..1c2ec1f2 100644 --- a/runner/providers/external/external.go +++ b/runner/providers/external/external.go @@ -44,21 +44,21 @@ type external struct { execPath string } -func (e *external) validateCreateResult(inst params.Instance) error { +func (e *external) validateResult(inst params.Instance) error { if inst.ProviderID == "" { - return garmErrors.NewProviderError("missing provider ID after create call") + return garmErrors.NewProviderError("missing provider ID") } if inst.Name == "" { - return garmErrors.NewProviderError("missing instance name after create call") + return garmErrors.NewProviderError("missing instance name") } if inst.OSName == "" || inst.OSArch == "" || inst.OSType == "" { // we can still function without this info (I think) - log.Printf("WARNING: missing OS information after create call") + log.Printf("WARNING: missing OS information") } - if !providerCommon.IsValidStatus(inst.Status) { - return garmErrors.NewProviderError("invalid status returned (%s) after create call", inst.Status) + if !providerCommon.IsValidProviderStatus(inst.Status) { + return garmErrors.NewProviderError("invalid status returned (%s)", inst.Status) } return nil @@ -88,7 +88,7 @@ func (e *external) CreateInstance(ctx context.Context, bootstrapParams params.Bo return params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err) } - if err := e.validateCreateResult(param); err != nil { + if err := e.validateResult(param); err != nil { return params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err) } @@ -137,6 +137,11 @@ func (e *external) GetInstance(ctx context.Context, instance string) (params.Ins if err := json.Unmarshal(out, ¶m); err != nil { return params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err) } + + if err := e.validateResult(param); err != nil { + return params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err) + } + return param, nil } @@ -158,6 +163,12 @@ func (e *external) ListInstances(ctx context.Context, poolID string) ([]params.I if err := json.Unmarshal(out, ¶m); err != nil { return []params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err) } + + for _, inst := range param { + if err := e.validateResult(inst); err != nil { + return []params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err) + } + } return param, nil } diff --git a/scripts/build-static.sh b/scripts/build-static.sh index 70cc4114..debcd5e4 100755 --- a/scripts/build-static.sh +++ b/scripts/build-static.sh @@ -11,11 +11,11 @@ USER_ID=${USER_ID:-$UID} USER_GROUP=${USER_GROUP:-$(id -g)} cd $GARM_SOURCE/cmd/garm -go build -mod vendor -o $BIN_DIR/garm -tags osusergo,netgo,sqlite_omit_load_extension -ldflags "-linkmode external -extldflags '-static' -s -w -X main.Version=$(git describe --always --dirty)" . +go build -mod vendor -o $BIN_DIR/garm -tags osusergo,netgo,sqlite_omit_load_extension -ldflags "-linkmode external -extldflags '-static' -s -w -X main.Version=$(git describe --tags --match='v[0-9]*' --dirty --always)" . # GOOS=windows CC=x86_64-w64-mingw32-cc go build -mod vendor -o $BIN_DIR/garm.exe -tags osusergo,netgo,sqlite_omit_load_extension -ldflags "-s -w -X main.Version=$(git describe --always --dirty)" . cd $GARM_SOURCE/cmd/garm-cli -go build -mod vendor -o $BIN_DIR/garm-cli -tags osusergo,netgo -ldflags "-linkmode external -extldflags '-static' -s -w -X garm/cmd/garm-cli/cmd.Version=$(git describe --always --dirty)" . +go build -mod vendor -o $BIN_DIR/garm-cli -tags osusergo,netgo -ldflags "-linkmode external -extldflags '-static' -s -w -X garm/cmd/garm-cli/cmd.Version=$(git describe --tags --match='v[0-9]*' --dirty --always)" . # GOOS=windows CGO_ENABLED=0 go build -mod vendor -o $BIN_DIR/garm-cli.exe -ldflags "-s -w -X garm/cmd/garm-cli/cmd.Version=$(git describe --always --dirty)" . chown $USER_ID:$USER_GROUP -R "$BIN_DIR"