Skip to content
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
23 changes: 11 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
module github.com/linode/docker-machine-driver-linode

go 1.25.0
go 1.25.8

// This replacement is necessary to support Docker versions > v20.x.x
// which provide critical security fixes.
replace github.com/docker/machine => gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.43
replace github.com/docker/machine => gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.46

require (
github.com/docker/machine v0.16.2
github.com/google/go-cmp v0.7.0
github.com/linode/linodego v1.69.1
github.com/linode/linodego/v2 v2.4.2
github.com/stretchr/testify v1.11.1
golang.org/x/oauth2 v0.36.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-resty/resty/v2 v2.17.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.51.0 // indirect
golang.org/x/net v0.54.0 // indirect
golang.org/x/sys v0.44.0 // indirect
golang.org/x/term v0.43.0 // indirect
golang.org/x/text v0.37.0 // indirect
gopkg.in/ini.v1 v1.67.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
golang.org/x/crypto v0.53.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/term v0.44.0 // indirect
golang.org/x/text v0.40.0 // indirect
gopkg.in/ini.v1 v1.67.3 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
46 changes: 22 additions & 24 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
Expand All @@ -15,12 +14,13 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/linode/linodego v1.69.1 h1:f45N2MHR/oece2/ktTTCYmrlfse4//k3NgwcF5zbGZ0=
github.com/linode/linodego v1.69.1/go.mod h1:Fha0NYsQSx5VZK1HQNJY/z/dIxxkFp+vb5veawbmAUw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/linode/linodego/v2 v2.4.2 h1:hOgnvX2IywFz3L1OXND08UP4D/90kmTSEreMMQkHZuQ=
github.com/linode/linodego/v2 v2.4.2/go.mod h1:LRzvYK/LFaGNqFmDxg1fZBtrolZOPvIdX9bssjwy5BA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -30,27 +30,25 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.43 h1:3AOpTvIZHfvNnCEaPvmMTiX65gY3yYtpabcAZJUgsTE=
gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.43/go.mod h1:WDpNHYkfs5yjw3iwSBFrFrsGZRGf2hPjkLVCbCvJvj8=
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.46 h1:Pb99y+m41TyisYAuQUnDyU58Wjopw5jJs1iEFSBDmEw=
gitlab.com/gitlab-org/ci-cd/docker-machine v0.16.2-gitlab.46/go.mod h1:gtOdjxEWrDTXEkJA9bnG1nU/0+SUZuCZzQtN7CfJsqU=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss=
gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/ini.v1 v1.67.3 h1:iM9Lhz5MRSGhHVGGwCuzG9KO8PoirCXj/m/qTmOJJQw=
gopkg.in/ini.v1 v1.67.3/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
77 changes: 55 additions & 22 deletions pkg/drivers/linode/linode.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import (
"regexp"
"strconv"
"strings"
"time"

"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/ssh"
"github.com/docker/machine/libmachine/state"
"github.com/linode/linodego"
"github.com/linode/linodego/v2"
"golang.org/x/oauth2"
)

Expand Down Expand Up @@ -84,7 +85,7 @@ func NewDriver(hostName, storePath string) *Driver {
}

// getClient prepares the Linode APIv4 Client
func (d *Driver) getClient() *linodego.Client {
func (d *Driver) getClient() (*linodego.Client, error) {
if d.client == nil {
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: d.APIToken})

Expand All @@ -96,15 +97,18 @@ func (d *Driver) getClient() *linodego.Client {

ua := fmt.Sprintf("docker-machine-driver-%s/%s", d.DriverName(), VERSION)

client := linodego.NewClient(oauth2Client)
client, err := linodego.NewClient(oauth2Client)
if err != nil {
return nil, err
}
if len(d.UserAgentPrefix) > 0 {
ua = fmt.Sprintf("%s %s", d.UserAgentPrefix, ua)
}

client.SetUserAgent(ua)
d.client = &client
}
return d.client
return d.client, nil
}

// SetClient sets the Linode API client for the driver
Expand Down Expand Up @@ -328,11 +332,13 @@ func (d *Driver) PreCreateCheck() error {
// TODO(displague) linode-stackscript-file should be read and uploaded (private), then used for boot.
// RevNote could be sha256 of file so the file can be referenced instead of reuploaded.

client := d.getClient()
client, err := d.getClient()
if err != nil {
return err
}

if d.RootPassword == "" {
log.Info("Generating a secure disposable linode-root-pass...")
var err error
d.RootPassword, err = createRandomRootPassword()
if err != nil {
return err
Expand Down Expand Up @@ -396,7 +402,10 @@ func (d *Driver) Create() error {
return err
}

client := d.getClient()
client, err := d.getClient()
if err != nil {
return err
}
boolBooted := !d.CreatePrivateIP

// Create a linode
Expand Down Expand Up @@ -438,7 +447,7 @@ func (d *Driver) Create() error {
d.Region = linode.Region

for _, address := range linode.IPv4 {
if private := privateIP(*address); !private {
if private := privateIP(address); !private {
d.IPAddress = address.String()
} else if d.CreatePrivateIP {
d.PrivateIPAddress = address.String()
Expand Down Expand Up @@ -480,14 +489,18 @@ func (d *Driver) Create() error {
return err
}

if err := client.BootInstance(context.TODO(), linode.ID, configs[0].ID); err != nil {
if err := client.BootInstance(context.TODO(), linode.ID, linodego.InstanceBootOptions{
ConfigID: &configs[0].ID,
}); err != nil {
return err
}
}

log.Info("Waiting for Machine Running...")
if _, err := client.WaitForInstanceStatus(context.TODO(), d.InstanceID, linodego.InstanceRunning, 180); err != nil {
return fmt.Errorf("wait for machine running failed: %s", err)
waitContext, cancel := context.WithTimeout(context.Background(), 180*time.Second)
defer cancel()
if _, err := client.WaitForInstanceStatus(waitContext, d.InstanceID, linodego.InstanceRunning); err != nil {
return fmt.Errorf("wait for machine running failed: %w", err)
}

return nil
Expand All @@ -509,7 +522,12 @@ func (d *Driver) GetURL() (string, error) {

// GetState returns the state that the host is in (running, stopped, etc)
func (d *Driver) GetState() (state.State, error) {
linode, err := d.getClient().GetInstance(context.TODO(), d.InstanceID)
client, err := d.getClient()
if err != nil {
return state.Error, err
}

linode, err := client.GetInstance(context.TODO(), d.InstanceID)
if err != nil {
return state.Error, err
}
Expand Down Expand Up @@ -539,23 +557,32 @@ func (d *Driver) GetState() (state.State, error) {
// Start a host
func (d *Driver) Start() error {
log.Debug("Start...")
err := d.getClient().BootInstance(context.TODO(), d.InstanceID, 0)
return err
client, err := d.getClient()
if err != nil {
return err
}
return client.BootInstance(context.TODO(), d.InstanceID, linodego.InstanceBootOptions{})
}

// Stop a host gracefully
func (d *Driver) Stop() error {
log.Debug("Stop...")
err := d.getClient().ShutdownInstance(context.TODO(), d.InstanceID)
return err
client, err := d.getClient()
if err != nil {
return err
}
return client.ShutdownInstance(context.TODO(), d.InstanceID)
}

// Remove a host
func (d *Driver) Remove() error {
client := d.getClient()
client, err := d.getClient()
if err != nil {
return err
}
log.Infof("Removing linode: %d", d.InstanceID)
if err := client.DeleteInstance(context.TODO(), d.InstanceID); err != nil {
if apiErr, ok := err.(*linodego.Error); ok && apiErr.Code == 404 {
if linodego.IsNotFound(err) {
log.Debug("Linode was already removed")
return nil
}
Expand All @@ -569,15 +596,21 @@ func (d *Driver) Remove() error {
// have any special restart behaviour.
func (d *Driver) Restart() error {
log.Debug("Restarting...")
err := d.getClient().RebootInstance(context.TODO(), d.InstanceID, 0)
return err
client, err := d.getClient()
if err != nil {
return err
}
return client.RebootInstance(context.TODO(), d.InstanceID, linodego.InstanceRebootOptions{})
}

// Kill stops a host forcefully
func (d *Driver) Kill() error {
log.Debug("Killing...")
err := d.getClient().ShutdownInstance(context.TODO(), d.InstanceID)
return err
client, err := d.getClient()
if err != nil {
return err
}
return client.ShutdownInstance(context.TODO(), d.InstanceID)
}

func (d *Driver) createSSHKey() (string, error) {
Expand Down
Loading