Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add provider interface versioning #278

Merged
merged 4 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import (
// whatever programming language you wish, while still remaining compatible
// with garm.
type External struct {
// InterfaceVersion is the version of the interface that the external
// provider implements. This is used to ensure compatibility between
// the external provider and garm.
InterfaceVersion string `toml:"interface_version" json:"interface-version"`
// ConfigFile is the path on disk to a file which will be passed to
// the external binary as an environment variable: GARM_PROVIDER_CONFIG
// You can use this file for any configuration you need to do for the
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ toolchain go1.22.3
require (
github.com/BurntSushi/toml v1.3.2
github.com/bradleyfalzon/ghinstallation/v2 v2.10.0
github.com/cloudbase/garm-provider-common v0.1.3
github.com/cloudbase/garm-provider-common v0.1.4-0.20240821093055-dfdf8e2e4853
github.com/felixge/httpsnoop v1.0.4
github.com/go-openapi/errors v0.22.0
github.com/go-openapi/runtime v0.28.0
Expand All @@ -28,7 +28,7 @@ require (
github.com/prometheus/client_golang v1.19.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.9.0
golang.org/x/crypto v0.25.0
golang.org/x/crypto v0.26.0
golang.org/x/oauth2 v0.19.0
golang.org/x/sync v0.7.0
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0
Expand Down Expand Up @@ -85,8 +85,8 @@ require (
go.opentelemetry.io/otel v1.25.0 // indirect
go.opentelemetry.io/otel/metric v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sys v0.24.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/cloudbase/garm-provider-common v0.1.3 h1:8pHSRs2ljwLHgtDrge68dZ7ILUW97VF5h2ZA2fQubGQ=
github.com/cloudbase/garm-provider-common v0.1.3/go.mod h1:VIJzbcg5iwyD4ac99tnnwcActfwibn/VOt2MYOFjf2c=
github.com/cloudbase/garm-provider-common v0.1.4-0.20240821093055-dfdf8e2e4853 h1:eaWT9rcqYheM1IMQtHQJNKLwSQfVKhj6veX221rDkIU=
github.com/cloudbase/garm-provider-common v0.1.4-0.20240821093055-dfdf8e2e4853/go.mod h1:/N8rXH2iXCsqCcOODsI2DTR9afnijMhNp/vjR9wbzSg=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down Expand Up @@ -180,21 +180,21 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
Expand Down
15 changes: 8 additions & 7 deletions runner/common/mocks/Provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 88 additions & 0 deletions runner/common/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2022 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package common

import "github.com/cloudbase/garm/params"

// Constants used for the provider interface version.
const (
Version010 = "v0.1.0"
Version011 = "v0.1.1"
)

// Each struct is a wrapper for the actual parameters struct for a specific version.
// Version 0.1.0 doesn't have any specific parameters, so there is no need for a struct for it.
type CreateInstanceParams struct {
CreateInstanceV011 CreateInstanceV011Params
}

type DeleteInstanceParams struct {
DeleteInstanceV011 DeleteInstanceV011Params
}

type GetInstanceParams struct {
GetInstanceV011 GetInstanceV011Params
}

type ListInstancesParams struct {
ListInstancesV011 ListInstancesV011Params
}

type RemoveAllInstancesParams struct {
RemoveAllInstancesV011 RemoveAllInstancesV011Params
}

type StopParams struct {
StopV011 StopV011Params
}

type StartParams struct {
StartV011 StartV011Params
}

// Struct for the base provider parameters.
type ProviderBaseParams struct {
PoolInfo params.Pool
ControllerInfo params.ControllerInfo
}

// Structs for version v0.1.1.
type CreateInstanceV011Params struct {
ProviderBaseParams
}

type DeleteInstanceV011Params struct {
ProviderBaseParams
}

type GetInstanceV011Params struct {
ProviderBaseParams
}

type ListInstancesV011Params struct {
ProviderBaseParams
}

type RemoveAllInstancesV011Params struct {
ProviderBaseParams
}

type StopV011Params struct {
ProviderBaseParams
}

type StartV011Params struct {
ProviderBaseParams
}
14 changes: 7 additions & 7 deletions runner/common/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ import (
//go:generate mockery --all
type Provider interface {
// CreateInstance creates a new compute instance in the provider.
CreateInstance(ctx context.Context, bootstrapParams commonParams.BootstrapInstance) (commonParams.ProviderInstance, error)
CreateInstance(ctx context.Context, bootstrapParams commonParams.BootstrapInstance, createInstanceParams CreateInstanceParams) (commonParams.ProviderInstance, error)
// Delete instance will delete the instance in a provider.
DeleteInstance(ctx context.Context, instance string) error
DeleteInstance(ctx context.Context, instance string, deleteInstanceParams DeleteInstanceParams) error
// GetInstance will return details about one instance.
GetInstance(ctx context.Context, instance string) (commonParams.ProviderInstance, error)
GetInstance(ctx context.Context, instance string, getInstanceParams GetInstanceParams) (commonParams.ProviderInstance, error)
// ListInstances will list all instances for a provider.
ListInstances(ctx context.Context, poolID string) ([]commonParams.ProviderInstance, error)
ListInstances(ctx context.Context, poolID string, listInstancesParams ListInstancesParams) ([]commonParams.ProviderInstance, error)
// RemoveAllInstances will remove all instances created by this provider.
RemoveAllInstances(ctx context.Context) error
RemoveAllInstances(ctx context.Context, removeAllInstancesParams RemoveAllInstancesParams) error
// Stop shuts down the instance.
Stop(ctx context.Context, instance string) error
Stop(ctx context.Context, instance string, stopParams StopParams) error
// Start boots up an instance.
Start(ctx context.Context, instance string) error
Start(ctx context.Context, instance string, startParams StartParams) error
// DisableJITConfig tells us if the provider explicitly disables JIT configuration and
// forces runner registration tokens to be used. This may happen if a provider has not yet
// been updated to support JIT configuration.
Expand Down
45 changes: 40 additions & 5 deletions runner/pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ type basePoolManager struct {
keyMux *keyMutex
}

func (r *basePoolManager) getProviderBaseParams(pool params.Pool) common.ProviderBaseParams {
r.mux.Lock()
defer r.mux.Unlock()

return common.ProviderBaseParams{
PoolInfo: pool,
ControllerInfo: r.controllerInfo,
}
}

func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error {
if err := r.ValidateOwner(job); err != nil {
return errors.Wrap(err, "validating owner")
Expand Down Expand Up @@ -589,7 +599,12 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner)
slog.DebugContext(
r.ctx, "updating instances cache for pool",
"pool_id", pool.ID)
poolInstances, err = provider.ListInstances(r.ctx, pool.ID)
listInstancesParams := common.ListInstancesParams{
ListInstancesV011: common.ListInstancesV011Params{
ProviderBaseParams: r.getProviderBaseParams(pool),
},
}
poolInstances, err = provider.ListInstances(r.ctx, pool.ID, listInstancesParams)
if err != nil {
return errors.Wrapf(err, "fetching instances for pool %s", pool.ID)
}
Expand Down Expand Up @@ -654,7 +669,12 @@ func (r *basePoolManager) cleanupOrphanedGithubRunners(runners []*github.Runner)
r.ctx, "instance was found in stopped state; starting",
"runner_name", dbInstance.Name)

if err := provider.Start(r.ctx, dbInstance.ProviderID); err != nil {
startParams := common.StartParams{
StartV011: common.StartV011Params{
ProviderBaseParams: r.getProviderBaseParams(pool),
},
}
if err := provider.Start(r.ctx, dbInstance.ProviderID, startParams); err != nil {
return errors.Wrapf(err, "starting instance %s", dbInstance.ProviderID)
}
return nil
Expand Down Expand Up @@ -870,7 +890,12 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error

defer func() {
if instanceIDToDelete != "" {
if err := provider.DeleteInstance(r.ctx, instanceIDToDelete); err != nil {
deleteInstanceParams := common.DeleteInstanceParams{
DeleteInstanceV011: common.DeleteInstanceV011Params{
ProviderBaseParams: r.getProviderBaseParams(pool),
},
}
if err := provider.DeleteInstance(r.ctx, instanceIDToDelete, deleteInstanceParams); err != nil {
if !errors.Is(err, runnerErrors.ErrNotFound) {
slog.With(slog.Any("error", err)).ErrorContext(
r.ctx, "failed to cleanup instance",
Expand All @@ -880,7 +905,12 @@ func (r *basePoolManager) addInstanceToProvider(instance params.Instance) error
}
}()

providerInstance, err := provider.CreateInstance(r.ctx, bootstrapArgs)
createInstanceParams := common.CreateInstanceParams{
CreateInstanceV011: common.CreateInstanceV011Params{
ProviderBaseParams: r.getProviderBaseParams(pool),
},
}
providerInstance, err := provider.CreateInstance(r.ctx, bootstrapArgs, createInstanceParams)
if err != nil {
instanceIDToDelete = instance.Name
return errors.Wrap(err, "creating instance")
Expand Down Expand Up @@ -1316,7 +1346,12 @@ func (r *basePoolManager) deleteInstanceFromProvider(ctx context.Context, instan
"runner_name", instance.Name,
"provider_id", identifier)

if err := provider.DeleteInstance(ctx, identifier); err != nil {
deleteInstanceParams := common.DeleteInstanceParams{
DeleteInstanceV011: common.DeleteInstanceV011Params{
ProviderBaseParams: r.getProviderBaseParams(pool),
},
}
if err := provider.DeleteInstance(ctx, identifier, deleteInstanceParams); err != nil {
return errors.Wrap(err, "removing instance")
}

Expand Down
23 changes: 23 additions & 0 deletions runner/providers/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package common

import (
garmErrors "github.com/cloudbase/garm-provider-common/errors"
commonParams "github.com/cloudbase/garm-provider-common/params"
"github.com/cloudbase/garm/runner/providers/util"
)

func ValidateResult(inst commonParams.ProviderInstance) error {
if inst.ProviderID == "" {
return garmErrors.NewProviderError("missing provider ID")
}

if inst.Name == "" {
return garmErrors.NewProviderError("missing instance name")
}

if !util.IsValidProviderStatus(inst.Status) {
return garmErrors.NewProviderError("invalid status returned (%s)", inst.Status)
}

return nil
}
Loading
Loading