diff --git a/driver/hetzner_query.go b/driver/hetzner_query.go index dabc7c5e51ff1d66cf9ddd4dba1d08f3aff4bc05..9d9ca7e5390b8413f668c6cedcb43ed3d980a2f1 100644 --- a/driver/hetzner_query.go +++ b/driver/hetzner_query.go @@ -11,7 +11,15 @@ import ( ) func (d *Driver) getClient() *hcloud.Client { - return hcloud.NewClient(hcloud.WithToken(d.AccessToken), hcloud.WithApplication("docker-machine-driver", d.version)) + opts := []hcloud.ClientOption{ + hcloud.WithToken(d.AccessToken), + hcloud.WithApplication("docker-machine-driver", d.version), + hcloud.WithPollBackoffFunc(hcloud.ConstantBackoff(time.Duration(d.WaitOnPolling) * time.Second)), + } + + opts = d.setupClientInstrumentation(opts) + + return hcloud.NewClient(opts...) } func (d *Driver) getLocationNullable() (*hcloud.Location, error) { @@ -166,25 +174,24 @@ func (d *Driver) getServerHandleNullable() (*hcloud.Server, error) { } func (d *Driver) waitForAction(a *hcloud.Action) error { - for { - act, _, err := d.getClient().Action.GetByID(context.Background(), a.ID) - if err != nil { - return errors.Wrap(err, "could not get client by ID") - } - if act == nil { - return fmt.Errorf("action not found: %v", a.ID) - } - - if act.Status == hcloud.ActionStatusSuccess { - log.Debugf(" -> finished %s[%d]", act.Command, act.ID) - break - } else if act.Status == hcloud.ActionStatusRunning { - log.Debugf(" -> %s[%d]: %d %%", act.Command, act.ID, act.Progress) - } else if act.Status == hcloud.ActionStatusError { - return act.Error() + progress, done := d.getClient().Action.WatchProgress(context.Background(), a) + + running := true + var ret error + + for running { + select { + case <-done: + ret = <-done + running = false + case <-progress: + log.Debugf(" -> %s[%d]: %d %%", a.Command, a.ID, <-progress) } + } - time.Sleep(time.Duration(d.WaitOnPolling) * time.Second) + if ret == nil { + log.Debugf(" -> finished %s[%d]", a.Command, a.ID) } - return nil + + return ret } diff --git a/driver/instrumentation_impl.go b/driver/instrumentation_impl.go index c5d5d5b82d4eb8377066ae0fd733c0a4ceb3fa77..52b8002bd761440d9ab319203022a2f61234ab77 100644 --- a/driver/instrumentation_impl.go +++ b/driver/instrumentation_impl.go @@ -4,6 +4,8 @@ package driver import ( "encoding/json" + "github.com/hetznercloud/hcloud-go/v2/hcloud" + "os" "runtime/debug" "github.com/docker/machine/libmachine/log" @@ -20,3 +22,18 @@ func instrumented[T any](input T) T { log.Debugf("%v\n%v\n", string(debug.Stack()), string(j)) return input } + +type debugLogWriter struct { +} + +func (x debugLogWriter) Write(data []byte) (int, error) { + log.Debug(string(data)) + return len(data), nil +} + +func (d *Driver) setupClientInstrumentation(opts []hcloud.ClientOption) []hcloud.ClientOption { + if os.Getenv("HETZNER_DRIVER_HTTP_DEBUG") == "42" { + opts = append(opts, hcloud.WithDebugWriter(debugLogWriter{})) + } + return opts +} diff --git a/driver/instrumentation_stub.go b/driver/instrumentation_stub.go index c4e3029fc28091f1da8e10716abad4681b147840..f438ff9ed17f48b31b90dda7859e99bf17028cdf 100644 --- a/driver/instrumentation_stub.go +++ b/driver/instrumentation_stub.go @@ -2,8 +2,16 @@ package driver +import ( + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + const runningInstrumented = false func instrumented[T any](input T) T { return input } + +func (d *Driver) setupClientInstrumentation(opts []hcloud.ClientOption) []hcloud.ClientOption { + return opts +}