Skip to content
GitLab
Explore
Sign in
Commits on Source (6)
bugfix: Accept legacy default images (fix #116)
· 220e0777
JonasS
authored
Dec 05, 2023
220e0777
chore: Update dependencies, go
· c35acacd
JonasS
authored
Dec 13, 2023
c35acacd
chore: Update workflow steps, remove obsolete build file
· 7355d0a0
JonasS
authored
Dec 13, 2023
7355d0a0
Merge branch 'master' into chore/update-go-21
· 97012db2
JonasS
authored
Dec 13, 2023
97012db2
chore: Switch to std lib errors package
· c023dd14
JonasS
authored
Dec 15, 2023
c023dd14
bugfix: Wait on serve.NextActions to reduce poll count on initial startup (closes #119)
· d97bd3ba
JonasS
authored
Dec 15, 2023
d97bd3ba
Hide whitespace changes
Inline
Side-by-side
.github/workflows/go.yml
View file @
d97bd3ba
...
...
@@ -11,17 +11,17 @@ jobs:
name
:
lint
runs-on
:
ubuntu-22.04
steps
:
-
uses
:
actions/checkout@v
2
-
uses
:
actions/checkout@v
4
-
name
:
golangci-lint
uses
:
golangci/golangci-lint-action@v
2
uses
:
golangci/golangci-lint-action@v
3
build
:
runs-on
:
ubuntu-22.04
steps
:
-
uses
:
actions/checkout@v
2
-
uses
:
actions/checkout@v
4
-
name
:
Set up Go
uses
:
actions/setup-go@v
2
uses
:
actions/setup-go@v
5
with
:
go-version
:
1.1
8
go-version
:
1.
2
1
-
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@v
2
-
uses
:
actions/checkout@v
4
-
name
:
Set up Go
uses
:
actions/setup-go@v
2
uses
:
actions/setup-go@v
5
with
:
go-version
:
1.1
8
go-version
:
1.
2
1
-
name
:
Run GoReleaser
uses
:
goreleaser/goreleaser-action@v
2
uses
:
goreleaser/goreleaser-action@v
5
with
:
version
:
latest
args
:
release --rm-dist
...
...
.github/workflows/manual-build.yml
deleted
100644 → 0
View file @
54b321f1
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/*
driver/cleanup.go
View file @
d97bd3ba
...
...
@@ -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
)
}
}
...
...
driver/driver.go
View file @
d97bd3ba
...
...
@@ -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
(
"
N
o private network attached
.
"
)
return
fmt
.
Errorf
(
"
n
o 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
.
waitFor
RunningServer
(
)
err
=
d
.
waitFor
InitialStartup
(
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
)
...
...
driver/driver_test.go
View file @
d97bd3ba
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
{}{
...
...
driver/flag_failure.go
View file @
d97bd3ba
...
...
@@ -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
{
...
...
driver/flag_failure_debug.go
View file @
d97bd3ba
...
...
@@ -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
{
...
...
driver/flag_processing.go
View file @
d97bd3ba
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
]
}
...
...
driver/hetzner_query.go
View file @
d97bd3ba
...
...
@@ -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
.
Sprint
f
(
"could not get image by id %v"
,
d
.
ImageID
)
)
return
nil
,
fmt
.
Error
f
(
"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
.
Sprint
f
(
"could not get image by name %v"
,
d
.
Image
)
)
return
nil
,
fmt
.
Error
f
(
"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
}
driver/instrumentation_impl.go
View file @
d97bd3ba
...
...
@@ -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"
)
...
...
driver/networking.go
View file @
d97bd3ba
...
...
@@ -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
()
...
...
driver/placement_groups.go
View file @
d97bd3ba
...
...
@@ -3,6 +3,7 @@ package driver
import
(
"context"
"fmt"
"github.com/docker/machine/libmachine/log"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
...
...
driver/setup.go
View file @
d97bd3ba
...
...
@@ -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
)
}
...
...
driver/ssh_keys.go
View file @
d97bd3ba
...
...
@@ -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
()
{
...
...
go.mod
View file @
d97bd3ba
module
github.com/JonasProgrammer/docker-machine-driver-hetzner
go 1.1
8
go 1.
2
1
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.1
2
=> github.com/urfave/cli v1.22.1
2
replace
github.com/codegangsta/cli
v1.22.1
4
=> github.com/urfave/cli v1.22.1
4
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.1
2
// indirect
github.com/codegangsta/cli
v1.22.1
4
// 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.1
6
.0 // indirect
github.com/prometheus/client_model
v0.
3.0
// indirect
github.com/prometheus/common
v0.4
2
.0 // indirect
github.com/prometheus/procfs
v0.1
0
.1 // indirect
github.com/prometheus/client_golang
v1.1
7
.0 // indirect
github.com/prometheus/client_model
v0.
4.1-0.20230718164431-9a2bf3000d16
// indirect
github.com/prometheus/common
v0.4
4
.0 // indirect
github.com/prometheus/procfs
v0.1
1
.1 // indirect
github.com/russross/blackfriday/v2
v2.1.0 // indirect
golang.org/x/net
v0.1
2
.0 // indirect
golang.org/x/sys
v0.1
1
.0 // indirect
golang.org/x/term
v0.1
1
.0 // indirect
golang.org/x/text
v0.1
2
.0 // indirect
google.golang.org/protobuf
v1.3
0
.0 // indirect
golang.org/x/net
v0.1
9
.0 // indirect
golang.org/x/sys
v0.1
5
.0 // indirect
golang.org/x/term
v0.1
5
.0 // indirect
golang.org/x/text
v0.1
4
.0 // indirect
google.golang.org/protobuf
v1.3
1
.0 // indirect
)
go.sum
View file @
d97bd3ba
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.1
6
.0 h1:
yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8
=
github.com/prometheus/client_golang
v1.1
6
.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.4
2
.0 h1:
EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM
=
github.com/prometheus/common
v0.4
2
.0/go.mod h1:
xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc
=
github.com/prometheus/procfs
v0.1
0
.1 h1:
kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg
=
github.com/prometheus/procfs
v0.1
0
.1/go.mod h1:
nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM
=
github.com/prometheus/client_golang
v1.1
7
.0 h1:
rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q
=
github.com/prometheus/client_golang
v1.1
7
.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.4
4
.0 h1:
+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY
=
github.com/prometheus/common
v0.4
4
.0/go.mod h1:
ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY
=
github.com/prometheus/procfs
v0.1
1
.1 h1:
xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI
=
github.com/prometheus/procfs
v0.1
1
.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.1
1
.0 h1:
eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM
=
golang.org/x/sys
v0.1
1
.0/go.mod h1:
oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg
=
golang.org/x/term
v0.1
1
.0 h1:
F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0
=
golang.org/x/term
v0.1
1
.0/go.mod h1:
zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU
=
golang.org/x/text
v0.1
2
.0 h1:
k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc
=
golang.org/x/text
v0.1
2
.0/go.mod h1:
TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE
=
golang.org/x/sys
v0.1
5
.0 h1:
h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc
=
golang.org/x/sys
v0.1
5
.0/go.mod h1:
/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA
=
golang.org/x/term
v0.1
5
.0 h1:
y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4
=
golang.org/x/term
v0.1
5
.0/go.mod h1:
BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0
=
golang.org/x/text
v0.1
4
.0 h1:
ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ
=
golang.org/x/text
v0.1
4
.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.3
0
.0 h1:
kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng
=
google.golang.org/protobuf
v1.3
0
.0/go.mod h1:
HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf
v1.3
1
.0 h1:
g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8
=
google.golang.org/protobuf
v1.3
1
.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=
...
...