Skip to content
Commits on Source (6)
......@@ -11,17 +11,17 @@ jobs:
name: lint
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v3
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: 1.18
go-version: 1.21
- name: Build
run: go build -v ./...
release:
......@@ -29,13 +29,13 @@ jobs:
needs: [ lint, build ]
if: ${{ startsWith(github.ref, 'refs/tags/') && contains(fromJSON('["mxschmitt", "JonasProgrammer"]'), github.actor) }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: 1.18
go-version: 1.21
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
uses: goreleaser/goreleaser-action@v5
with:
version: latest
args: release --rm-dist
......
name: Manual-build
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --snapshot --skip-publish
- name: Upload assets
uses: actions/upload-artifact@v2
with:
name: manual-build
path: dist/*
......@@ -3,9 +3,9 @@ package driver
import (
"context"
"fmt"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
)
func (d *Driver) destroyDangling() {
......@@ -44,7 +44,7 @@ func (d *Driver) destroyServer() error {
srv, err := d.getServerHandleNullable()
if err != nil {
return errors.Wrap(err, "could not get server handle")
return fmt.Errorf("could not get server handle: %w", err)
}
if srv == nil {
......@@ -54,7 +54,7 @@ func (d *Driver) destroyServer() error {
res, _, err := d.getClient().Server.DeleteWithResult(context.Background(), srv)
if err != nil {
return errors.Wrap(err, "could not delete server")
return fmt.Errorf("could not delete server: %w", err)
}
// failure to remove a placement group is not a hard error
......@@ -64,7 +64,7 @@ func (d *Driver) destroyServer() error {
// wait for the server to actually be deleted
if err = d.waitForAction(res.Action); err != nil {
return errors.Wrap(err, "could not wait for deletion")
return fmt.Errorf("could not wait for deletion: %w", err)
}
}
......
......@@ -2,6 +2,7 @@ package driver
import (
"context"
"errors"
"fmt"
"net"
"strconv"
......@@ -12,7 +13,6 @@ import (
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
)
// Driver contains hetzner-specific data to implement [drivers.Driver]
......@@ -328,7 +328,7 @@ func flagI64(opts drivers.DriverOptions, key string) (int64, error) {
ret, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return 0, errors.Wrapf(err, "could not parse int64 for %v", key)
return 0, fmt.Errorf("could not parse int64 for %v: %w", key, err)
}
return ret, nil
......@@ -439,17 +439,17 @@ func (d *Driver) PreCreateCheck() error {
}
if serverType, err := d.getType(); err != nil {
return errors.Wrap(err, "could not get type")
return fmt.Errorf("could not get type: %w", err)
} else if d.ImageArch != "" && serverType.Architecture != d.ImageArch {
log.Warnf("supplied architecture %v differs from server architecture %v", d.ImageArch, serverType.Architecture)
}
if _, err := d.getImage(); err != nil {
return errors.Wrap(err, "could not get image")
return fmt.Errorf("could not get image: %w", err)
}
if _, err := d.getLocationNullable(); err != nil {
return errors.Wrap(err, "could not get location")
return fmt.Errorf("could not get location: %w", err)
}
if _, err := d.getPlacementGroup(); err != nil {
......@@ -465,7 +465,7 @@ func (d *Driver) PreCreateCheck() error {
}
if d.UsePrivateNetwork && len(d.Networks) == 0 {
return errors.Errorf("No private network attached.")
return fmt.Errorf("no private network attached")
}
return nil
......@@ -494,18 +494,18 @@ func (d *Driver) Create() error {
srv, _, err := d.getClient().Server.Create(context.Background(), instrumented(*srvopts))
if err != nil {
time.Sleep(time.Duration(d.WaitOnError) * time.Second)
return errors.Wrap(err, "could not create server")
return fmt.Errorf("could not create server: %w", err)
}
log.Infof(" -> Creating server %s[%d] in %s[%d]", srv.Server.Name, srv.Server.ID, srv.Action.Command, srv.Action.ID)
if err = d.waitForAction(srv.Action); err != nil {
return errors.Wrap(err, "could not wait for action")
return fmt.Errorf("could not wait for action: %w", err)
}
d.ServerID = srv.Server.ID
log.Infof(" -> Server %s[%d]: Waiting to come up...", srv.Server.Name, srv.Server.ID)
err = d.waitForRunningServer()
err = d.waitForInitialStartup(srv)
if err != nil {
return err
}
......@@ -530,12 +530,12 @@ func (d *Driver) GetSSHHostname() (string, error) {
// GetURL retrieves the URL of the docker daemon on the machine; see [drivers.Driver.GetURL]
func (d *Driver) GetURL() (string, error) {
if err := drivers.MustBeRunning(d); err != nil {
return "", errors.Wrap(err, "could not execute drivers.MustBeRunning")
return "", fmt.Errorf("could not execute drivers.MustBeRunning: %w", err)
}
ip, err := d.GetIP()
if err != nil {
return "", errors.Wrap(err, "could not get IP")
return "", fmt.Errorf("could not get IP: %w", err)
}
return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil
......@@ -545,7 +545,7 @@ func (d *Driver) GetURL() (string, error) {
func (d *Driver) GetState() (state.State, error) {
srv, _, err := d.getClient().Server.GetByID(context.Background(), d.ServerID)
if err != nil {
return state.None, errors.Wrap(err, "could not get server by ID")
return state.None, fmt.Errorf("could not get server by ID: %w", err)
}
if srv == nil {
return state.None, errors.New("server not found")
......@@ -588,7 +588,7 @@ func (d *Driver) Remove() error {
if !d.IsExistingKey && d.KeyID != 0 {
key, err := d.getKeyNullable()
if err != nil {
return errors.Wrap(err, "could not get ssh key")
return fmt.Errorf("could not get ssh key: %w", err)
}
if key == nil {
log.Infof(" -> SSH key does not exist anymore")
......@@ -598,7 +598,7 @@ func (d *Driver) Remove() error {
log.Infof(" -> Destroying SSHKey %s[%d]...", key.Name, key.ID)
if _, err := d.getClient().SSHKey.Delete(context.Background(), key); err != nil {
return errors.Wrap(err, "could not delete ssh key")
return fmt.Errorf("could not delete ssh key: %w", err)
}
}
......@@ -609,7 +609,7 @@ func (d *Driver) Remove() error {
func (d *Driver) Restart() error {
srv, err := d.getServerHandle()
if err != nil {
return errors.Wrap(err, "could not get server handle")
return fmt.Errorf("could not get server handle: %w", err)
}
if srv == nil {
return errors.New("server not found")
......@@ -617,7 +617,7 @@ func (d *Driver) Restart() error {
act, _, err := d.getClient().Server.Reboot(context.Background(), srv)
if err != nil {
return errors.Wrap(err, "could not reboot server")
return fmt.Errorf("could not reboot server: %w", err)
}
log.Infof(" -> Rebooting server %s[%d] in %s[%d]...", srv.Name, srv.ID, act.Command, act.ID)
......@@ -629,12 +629,12 @@ func (d *Driver) Restart() error {
func (d *Driver) Start() error {
srv, err := d.getServerHandle()
if err != nil {
return errors.Wrap(err, "could not get server handle")
return fmt.Errorf("could not get server handle: %w", err)
}
act, _, err := d.getClient().Server.Poweron(context.Background(), srv)
if err != nil {
return errors.Wrap(err, "could not power on server")
return fmt.Errorf("could not power on server: %w", err)
}
log.Infof(" -> Starting server %s[%d] in %s[%d]...", srv.Name, srv.ID, act.Command, act.ID)
......@@ -646,12 +646,12 @@ func (d *Driver) Start() error {
func (d *Driver) Stop() error {
srv, err := d.getServerHandle()
if err != nil {
return errors.Wrap(err, "could not get server handle")
return fmt.Errorf("could not get server handle: %w", err)
}
act, _, err := d.getClient().Server.Shutdown(context.Background(), srv)
if err != nil {
return errors.Wrap(err, "could not shutdown server")
return fmt.Errorf("could not shutdown server: %w", err)
}
log.Infof(" -> Shutting down server %s[%d] in %s[%d]...", srv.Name, srv.ID, act.Command, act.ID)
......@@ -663,12 +663,12 @@ func (d *Driver) Stop() error {
func (d *Driver) Kill() error {
srv, err := d.getServerHandle()
if err != nil {
return errors.Wrap(err, "could not get server handle")
return fmt.Errorf("could not get server handle: %w", err)
}
act, _, err := d.getClient().Server.Poweroff(context.Background(), srv)
if err != nil {
return errors.Wrap(err, "could not poweroff server")
return fmt.Errorf("could not poweroff server: %w", err)
}
log.Infof(" -> Powering off server %s[%d] in %s[%d]...", srv.Name, srv.ID, act.Command, act.ID)
......
package driver
import (
"github.com/docker/machine/commands/commandstest"
"github.com/docker/machine/libmachine/drivers"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"os"
"strconv"
"strings"
"testing"
"github.com/docker/machine/commands/commandstest"
"github.com/docker/machine/libmachine/drivers"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
var defaultFlags = map[string]interface{}{
......
......@@ -3,12 +3,13 @@
package driver
import (
"fmt"
"github.com/docker/machine/libmachine/drivers"
"github.com/pkg/errors"
)
func (d *Driver) flagFailure(format string, args ...interface{}) error {
return errors.Errorf(format, args...)
return fmt.Errorf(format, args...)
}
func (d *Driver) setConfigFromFlags(opts drivers.DriverOptions) error {
......
......@@ -7,7 +7,6 @@ import (
"fmt"
"github.com/docker/machine/libmachine/drivers"
"github.com/pkg/errors"
)
var lastOpts drivers.DriverOptions
......@@ -23,7 +22,7 @@ func (d *Driver) flagFailure(format string, args ...interface{}) error {
}
combined := append([]interface{}{line1, line2}, args...)
return errors.Errorf("%s\n%s\n"+format, combined...)
return fmt.Errorf("%s\n%s\n"+format, combined...)
}
func (d *Driver) setConfigFromFlags(opts drivers.DriverOptions) error {
......
package driver
import (
"fmt"
"strings"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
"strings"
)
var legacyDefaultImages = [...]string{
defaultImage,
"ubuntu-18.04",
"ubuntu-16.04",
"debian-9",
}
func isDefaultImageName(imageName string) bool {
for _, defaultImage := range legacyDefaultImages {
if imageName == defaultImage {
return true
}
}
return false
}
func (d *Driver) setImageArch(arch string) error {
switch arch {
case "":
......@@ -17,13 +34,13 @@ func (d *Driver) setImageArch(arch string) error {
case string(hcloud.ArchitectureX86):
d.ImageArch = hcloud.ArchitectureX86
default:
return errors.Errorf("unknown architecture %v", arch)
return fmt.Errorf("unknown architecture %v", arch)
}
return nil
}
func (d *Driver) verifyImageFlags() error {
if d.ImageID != 0 && d.Image != "" && d.Image != defaultImage /* support legacy behaviour */ {
if d.ImageID != 0 && d.Image != "" && !isDefaultImageName(d.Image) /* support legacy behaviour */ {
return d.flagFailure("--%v and --%v are mutually exclusive", flagImage, flagImageID)
} else if d.ImageID != 0 && d.ImageArch != "" {
return d.flagFailure("--%v and --%v are mutually exclusive", flagImageArch, flagImageID)
......@@ -96,7 +113,7 @@ func (d *Driver) setLabelsFromFlags(opts drivers.DriverOptions) error {
for _, label := range opts.StringSlice(flagKeyLabel) {
split := strings.SplitN(label, "=", 2)
if len(split) != 2 {
return errors.Errorf("key label %v is not in key=value format", label)
return fmt.Errorf("key label %v is not in key=value format", label)
}
d.keyLabels[split[0]] = split[1]
}
......
......@@ -2,12 +2,13 @@ package driver
import (
"context"
"errors"
"fmt"
"time"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
"time"
)
func (d *Driver) getClient() *hcloud.Client {
......@@ -32,7 +33,7 @@ func (d *Driver) getLocationNullable() (*hcloud.Location, error) {
location, _, err := d.getClient().Location.GetByName(context.Background(), d.Location)
if err != nil {
return nil, errors.Wrap(err, "could not get location by name")
return nil, fmt.Errorf("could not get location by name: %w", err)
}
if location == nil {
return nil, fmt.Errorf("unknown location: %v", d.Location)
......@@ -48,7 +49,7 @@ func (d *Driver) getType() (*hcloud.ServerType, error) {
stype, _, err := d.getClient().ServerType.GetByName(context.Background(), d.Type)
if err != nil {
return nil, errors.Wrap(err, "could not get type by name")
return nil, fmt.Errorf("could not get type by name: %w", err)
}
if stype == nil {
return nil, fmt.Errorf("unknown server type: %v", d.Type)
......@@ -68,7 +69,7 @@ func (d *Driver) getImage() (*hcloud.Image, error) {
if d.ImageID != 0 {
image, _, err = d.getClient().Image.GetByID(context.Background(), d.ImageID)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not get image by id %v", d.ImageID))
return nil, fmt.Errorf("could not get image by id %v: %w", d.ImageID, err)
}
if image == nil {
return nil, fmt.Errorf("image id not found: %v", d.ImageID)
......@@ -76,12 +77,12 @@ func (d *Driver) getImage() (*hcloud.Image, error) {
} else {
arch, err := d.getImageArchitectureForLookup()
if err != nil {
return nil, errors.Wrap(err, "could not determine image architecture")
return nil, fmt.Errorf("could not determine image architecture: %w", err)
}
image, _, err = d.getClient().Image.GetByNameAndArchitecture(context.Background(), d.Image, arch)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not get image by name %v", d.Image))
return nil, fmt.Errorf("could not get image by name %v: %w", d.Image, err)
}
if image == nil {
return nil, fmt.Errorf("image not found: %v[%v]", d.Image, arch)
......@@ -123,7 +124,7 @@ func (d *Driver) getKeyNullable() (*hcloud.SSHKey, error) {
key, _, err := d.getClient().SSHKey.GetByID(context.Background(), d.KeyID)
if err != nil {
return nil, errors.Wrap(err, "could not get sshkey by ID")
return nil, fmt.Errorf("could not get sshkey by ID: %w", err)
}
d.cachedKey = key
return instrumented(key), nil
......@@ -132,14 +133,14 @@ func (d *Driver) getKeyNullable() (*hcloud.SSHKey, error) {
func (d *Driver) getRemoteKeyWithSameFingerprintNullable(publicKeyBytes []byte) (*hcloud.SSHKey, error) {
publicKey, _, _, _, err := ssh.ParseAuthorizedKey(publicKeyBytes)
if err != nil {
return nil, errors.Wrap(err, "could not parse ssh public key")
return nil, fmt.Errorf("could not parse ssh public key: %w", err)
}
fp := ssh.FingerprintLegacyMD5(publicKey)
remoteKey, _, err := d.getClient().SSHKey.GetByFingerprint(context.Background(), fp)
if err != nil {
return remoteKey, errors.Wrap(err, "could not get sshkey by fingerprint")
return remoteKey, fmt.Errorf("could not get sshkey by fingerprint: %w", err)
}
return instrumented(remoteKey), nil
}
......@@ -166,7 +167,7 @@ func (d *Driver) getServerHandleNullable() (*hcloud.Server, error) {
srv, _, err := d.getClient().Server.GetByID(context.Background(), d.ServerID)
if err != nil {
return nil, errors.Wrap(err, "could not get client by ID")
return nil, fmt.Errorf("could not get client by ID: %w", err)
}
d.cachedServer = srv
......@@ -195,3 +196,30 @@ func (d *Driver) waitForAction(a *hcloud.Action) error {
return ret
}
func (d *Driver) waitForMultipleActions(step string, a []*hcloud.Action) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
progress, watchErr := d.getClient().Action.WatchOverallProgress(ctx, a)
running := true
var ret error
for running {
select {
case <-watchErr:
ret = errors.Join(ret, <-watchErr)
cancel()
case <-progress:
log.Debugf(" -> %s: %d %%", step, <-progress)
default:
running = false
}
}
if ret == nil {
log.Debugf(" -> finished %s", step)
}
return ret
}
......@@ -4,10 +4,11 @@ package driver
import (
"encoding/json"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"os"
"runtime/debug"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/docker/machine/libmachine/log"
)
......
......@@ -3,11 +3,11 @@ package driver
import (
"context"
"fmt"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
"net"
"time"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
func (d *Driver) getPrimaryIPv4() (*hcloud.PrimaryIP, error) {
......@@ -87,7 +87,7 @@ func (d *Driver) configureNetworkAccess(srv hcloud.ServerCreateResult) error {
log.Infof("Wait until private network attached ...")
server, _, err := d.getClient().Server.GetByID(context.Background(), srv.Server.ID)
if err != nil {
return errors.Wrapf(err, "could not get newly created server [%d]", srv.Server.ID)
return fmt.Errorf("could not get newly created server [%d]: %w", srv.Server.ID, err)
}
if server.PrivateNet != nil {
d.IPAddress = server.PrivateNet[0].IP.String()
......
......@@ -3,6 +3,7 @@ package driver
import (
"context"
"fmt"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
......
......@@ -2,11 +2,12 @@ package driver
import (
"context"
"github.com/docker/machine/libmachine/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
"fmt"
"os"
"time"
"github.com/docker/machine/libmachine/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
func (d *Driver) waitForRunningServer() error {
......@@ -14,7 +15,7 @@ func (d *Driver) waitForRunningServer() error {
for {
srvstate, err := d.GetState()
if err != nil {
return errors.Wrap(err, "could not get state")
return fmt.Errorf("could not get state: %w", err)
}
if srvstate == state.Running {
......@@ -23,7 +24,7 @@ func (d *Driver) waitForRunningServer() error {
elapsed_time := time.Since(start_time).Seconds()
if d.WaitForRunningTimeout > 0 && int(elapsed_time) > d.WaitForRunningTimeout {
return errors.Errorf("server exceeded wait-for-running-timeout.")
return fmt.Errorf("server exceeded wait-for-running-timeout")
}
time.Sleep(time.Duration(d.WaitOnPolling) * time.Second)
......@@ -31,6 +32,16 @@ func (d *Driver) waitForRunningServer() error {
return nil
}
func (d *Driver) waitForInitialStartup(srv hcloud.ServerCreateResult) error {
if srv.NextActions != nil && len(srv.NextActions) != 0 {
if err := d.waitForMultipleActions("server.NextActions", srv.NextActions); err != nil {
return fmt.Errorf("could not wait for NextActions: %w", err)
}
}
return d.waitForRunningServer()
}
func (d *Driver) makeCreateServerOptions() (*hcloud.ServerCreateOpts, error) {
pgrp, err := d.getPlacementGroup()
if err != nil {
......@@ -73,17 +84,17 @@ func (d *Driver) makeCreateServerOptions() (*hcloud.ServerCreateOpts, error) {
srvopts.Volumes = volumes
if srvopts.Location, err = d.getLocationNullable(); err != nil {
return nil, errors.Wrap(err, "could not get location")
return nil, fmt.Errorf("could not get location: %w", err)
}
if srvopts.ServerType, err = d.getType(); err != nil {
return nil, errors.Wrap(err, "could not get type")
return nil, fmt.Errorf("could not get type: %w", err)
}
if srvopts.Image, err = d.getImage(); err != nil {
return nil, errors.Wrap(err, "could not get image")
return nil, fmt.Errorf("could not get image: %w", err)
}
key, err := d.getKey()
if err != nil {
return nil, errors.Wrap(err, "could not get ssh key")
return nil, fmt.Errorf("could not get ssh key: %w", err)
}
srvopts.SSHKeys = append(d.cachedAdditionalKeys, key)
return &srvopts, nil
......@@ -107,10 +118,10 @@ func (d *Driver) createNetworks() ([]*hcloud.Network, error) {
for _, networkIDorName := range d.Networks {
network, _, err := d.getClient().Network.Get(context.Background(), networkIDorName)
if err != nil {
return nil, errors.Wrap(err, "could not get network by ID or name")
return nil, fmt.Errorf("could not get network by ID or name: %w", err)
}
if network == nil {
return nil, errors.Errorf("network '%s' not found", networkIDorName)
return nil, fmt.Errorf("network '%s' not found", networkIDorName)
}
networks = append(networks, network)
}
......@@ -122,10 +133,10 @@ func (d *Driver) createFirewalls() ([]*hcloud.ServerCreateFirewall, error) {
for _, firewallIDorName := range d.Firewalls {
firewall, _, err := d.getClient().Firewall.Get(context.Background(), firewallIDorName)
if err != nil {
return nil, errors.Wrap(err, "could not get firewall by ID or name")
return nil, fmt.Errorf("could not get firewall by ID or name: %w", err)
}
if firewall == nil {
return nil, errors.Errorf("firewall '%s' not found", firewallIDorName)
return nil, fmt.Errorf("firewall '%s' not found", firewallIDorName)
}
firewalls = append(firewalls, &hcloud.ServerCreateFirewall{Firewall: *firewall})
}
......@@ -137,10 +148,10 @@ func (d *Driver) createVolumes() ([]*hcloud.Volume, error) {
for _, volumeIDorName := range d.Volumes {
volume, _, err := d.getClient().Volume.Get(context.Background(), volumeIDorName)
if err != nil {
return nil, errors.Wrap(err, "could not get volume by ID or name")
return nil, fmt.Errorf("could not get volume by ID or name: %w", err)
}
if volume == nil {
return nil, errors.Errorf("volume '%s' not found", volumeIDorName)
return nil, fmt.Errorf("volume '%s' not found", volumeIDorName)
}
volumes = append(volumes, volume)
}
......
......@@ -3,13 +3,13 @@ package driver
import (
"context"
"fmt"
"os"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/mcnutils"
mcnssh "github.com/docker/machine/libmachine/ssh"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
"os"
)
func (d *Driver) setupExistingKey() error {
......@@ -23,23 +23,23 @@ func (d *Driver) setupExistingKey() error {
key, err := d.getKey()
if err != nil {
return errors.Wrap(err, "could not get key")
return fmt.Errorf("could not get key: %w", err)
}
buf, err := os.ReadFile(d.originalKey + ".pub")
if err != nil {
return errors.Wrap(err, "could not read public key")
return fmt.Errorf("could not read public key: %w", err)
}
// Will also parse `ssh-rsa w309jwf0e39jf asdf` public keys
pubk, _, _, _, err := ssh.ParseAuthorizedKey(buf)
if err != nil {
return errors.Wrap(err, "could not parse authorized key")
return fmt.Errorf("could not parse authorized key: %w", err)
}
if key.Fingerprint != ssh.FingerprintLegacyMD5(pubk) &&
key.Fingerprint != ssh.FingerprintSHA256(pubk) {
return errors.Errorf("remote key %d does not match local key %s", d.KeyID, d.originalKey)
return fmt.Errorf("remote key %d does not match local key %s", d.KeyID, d.originalKey)
}
return nil
......@@ -47,15 +47,15 @@ func (d *Driver) setupExistingKey() error {
func (d *Driver) copySSHKeyPair(src string) error {
if err := mcnutils.CopyFile(src, d.GetSSHKeyPath()); err != nil {
return errors.Wrap(err, "could not copy ssh key")
return fmt.Errorf("could not copy ssh key: %w", err)
}
if err := mcnutils.CopyFile(src+".pub", d.GetSSHKeyPath()+".pub"); err != nil {
return errors.Wrap(err, "could not copy ssh public key")
return fmt.Errorf("could not copy ssh public key: %w", err)
}
if err := os.Chmod(d.GetSSHKeyPath(), 0600); err != nil {
return errors.Wrap(err, "could not set permissions on the ssh key")
return fmt.Errorf("could not set permissions on the ssh key: %w", err)
}
return nil
......@@ -67,12 +67,12 @@ func (d *Driver) createRemoteKeys() error {
buf, err := os.ReadFile(d.GetSSHKeyPath() + ".pub")
if err != nil {
return errors.Wrap(err, "could not read ssh public key")
return fmt.Errorf("could not read ssh public key: %w", err)
}
key, err := d.getRemoteKeyWithSameFingerprintNullable(buf)
if err != nil {
return errors.Wrap(err, "error retrieving potentially existing key")
return fmt.Errorf("error retrieving potentially existing key: %w", err)
}
if key == nil {
log.Infof("SSH key not found in Hetzner. Uploading...")
......@@ -91,14 +91,14 @@ func (d *Driver) createRemoteKeys() error {
for i, pubkey := range d.AdditionalKeys {
key, err := d.getRemoteKeyWithSameFingerprintNullable([]byte(pubkey))
if err != nil {
return errors.Wrapf(err, "error checking for existing key for %v", pubkey)
return fmt.Errorf("error checking for existing key for %v: %w", pubkey, err)
}
if key == nil {
log.Infof("Creating new key for %v...", pubkey)
key, err = d.makeKey(fmt.Sprintf("%v-additional-%d", d.GetMachineName(), i), pubkey, d.keyLabels)
if err != nil {
return errors.Wrapf(err, "error creating new key for %v", pubkey)
return fmt.Errorf("error creating new key for %v: %w", pubkey, err)
}
log.Infof(" -> Created %v", key.ID)
......@@ -116,12 +116,12 @@ func (d *Driver) prepareLocalKey() error {
if d.originalKey != "" {
log.Debugf("Copying SSH key...")
if err := d.copySSHKeyPair(d.originalKey); err != nil {
return errors.Wrap(err, "could not copy ssh key pair")
return fmt.Errorf("could not copy ssh key pair: %w", err)
}
} else {
log.Debugf("Generating SSH key...")
if err := mcnssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
return errors.Wrap(err, "could not generate ssh key")
return fmt.Errorf("could not generate ssh key: %w", err)
}
}
return nil
......@@ -137,9 +137,9 @@ func (d *Driver) makeKey(name string, pubkey string, labels map[string]string) (
key, _, err := d.getClient().SSHKey.Create(context.Background(), instrumented(keyopts))
if err != nil {
return nil, errors.Wrap(err, "could not create ssh key")
return nil, fmt.Errorf("could not create ssh key: %w", err)
} else if key == nil {
return nil, errors.Errorf("key upload did not return an error, but key was nil")
return nil, fmt.Errorf("key upload did not return an error, but key was nil")
}
d.dangling = append(d.dangling, func() {
......
module github.com/JonasProgrammer/docker-machine-driver-hetzner
go 1.18
go 1.21
require (
github.com/docker/machine v0.16.2
github.com/hetznercloud/hcloud-go/v2 v2.2.0
github.com/pkg/errors v0.9.1
golang.org/x/crypto v0.12.0
github.com/hetznercloud/hcloud-go/v2 v2.5.1
golang.org/x/crypto v0.16.0
)
replace github.com/codegangsta/cli v1.22.12 => github.com/urfave/cli v1.22.12
replace github.com/codegangsta/cli v1.22.14 => github.com/urfave/cli v1.22.14
require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/codegangsta/cli v1.22.12 // indirect
github.com/codegangsta/cli v1.22.14 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/docker/docker v20.10.21+incompatible // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
......@@ -8,6 +8,7 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
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=
......@@ -16,30 +17,28 @@ github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05
github.com/docker/machine v0.16.2 h1:jyF9k3Zg+oIGxxSdYKPScyj3HqFZ6FjgA/3sblcASiU=
github.com/docker/machine v0.16.2/go.mod h1:I8mPNDeK1uH+JTcUU7X0ZW8KiYz0jyAgNaeSJ1rCfDI=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/hetznercloud/hcloud-go/v2 v2.2.0 h1:UzuqXXoy9+mMS2GKV9ZKF5BqvFkOJwW0XiSwEqGNxn0=
github.com/hetznercloud/hcloud-go/v2 v2.2.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hetznercloud/hcloud-go/v2 v2.5.1 h1:tJQxd+Qyd9CwGOFL0og80zZ3a4Z5p9+iIRTnUPlvOgc=
github.com/hetznercloud/hcloud-go/v2 v2.5.1/go.mod h1:y75vdFT0eNNnYyGWO55Qv0LI23kSgsQZl3Gyy0KMrI4=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
......@@ -47,27 +46,27 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
......