diff --git a/driver/hetzner_query.go b/driver/hetzner_query.go index dabc7c5..9d9ca7e 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 c5d5d5b..52b8002 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 c4e3029..f438ff9 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 +}