diff --git a/README.md b/README.md index f02ee1bb4c4647e5375d90cf42449d941656f599..58b5571de9105b1365ff8de45d51a883d9626601 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ You can find sources and pre-compiled binaries [here](https://github.com/JonasPr ```bash # Download the binary (this example downloads the binary for linux amd64) -$ wget https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases/download/3.13.0/docker-machine-driver-hetzner_3.13.0_linux_amd64.tar.gz -$ tar -xvf docker-machine-driver-hetzner_3.13.0_linux_amd64.tar.gz +$ wget https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases/download/4.1.0/docker-machine-driver-hetzner_4.1.0_linux_amd64.tar.gz +$ tar -xvf docker-machine-driver-hetzner_4.1.0_linux_amd64.tar.gz # Make it executable and copy the binary in a directory accessible with your $PATH $ chmod +x docker-machine-driver-hetzner @@ -115,6 +115,8 @@ $ docker-machine create \ - `--hetzner-ssh-port`: Change the default SSH-Port - `--hetzner-primary-ipv4/6`: Sets an existing primary IP (v4 or v6 respectively) for the server, as documented in [Networking](#networking) - `--hetzner-wait-on-error`: Amount of seconds to wait on server creation failure (0/no wait by default) +- `--hetzner-wait-on-polling`: Amount of seconds to wait between requests when waiting for some state to change. (Default: 1 second) +- `--hetzner-wait-for-running-timeout`: Max amount of seconds to wait until a machine is running. (Default: 0/no timeout) #### Image selection @@ -145,35 +147,37 @@ was used during creation. #### Environment variables and default values -| CLI option | Environment variable | Default | -|---------------------------------|-------------------------------|----------------------------| -| **`--hetzner-api-token`** | `HETZNER_API_TOKEN` | | -| `--hetzner-image` | `HETZNER_IMAGE` | `ubuntu-20.04` as fallback | -| `--hetzner-image-arch` | `HETZNER_IMAGE_ARCH` | *(infer from server)* | -| `--hetzner-image-id` | `HETZNER_IMAGE_ID` | | -| `--hetzner-server-type` | `HETZNER_TYPE` | `cx11` | -| `--hetzner-server-location` | `HETZNER_LOCATION` | *(let Hetzner choose)* | -| `--hetzner-existing-key-path` | `HETZNER_EXISTING_KEY_PATH` | *(generate new keypair)* | -| `--hetzner-existing-key-id` | `HETZNER_EXISTING_KEY_ID` | 0 *(upload new key)* | -| `--hetzner-additional-key` | `HETZNER_ADDITIONAL_KEYS` | | -| `--hetzner-user-data` | `HETZNER_USER_DATA` | | -| `--hetzner-user-data-file` | `HETZNER_USER_DATA_FILE` | | -| `--hetzner-networks` | `HETZNER_NETWORKS` | | -| `--hetzner-firewalls` | `HETZNER_FIREWALLS` | | -| `--hetzner-volumes` | `HETZNER_VOLUMES` | | -| `--hetzner-use-private-network` | `HETZNER_USE_PRIVATE_NETWORK` | false | -| `--hetzner-disable-public-ipv4` | `HETZNER_DISABLE_PUBLIC_IPV4` | false | -| `--hetzner-disable-public-ipv6` | `HETZNER_DISABLE_PUBLIC_IPV6` | false | -| `--hetzner-disable-public` | `HETZNER_DISABLE_PUBLIC` | false | -| `--hetzner-server-label` | (inoperative) | `[]` | -| `--hetzner-key-label` | (inoperative) | `[]` | -| `--hetzner-placement-group` | `HETZNER_PLACEMENT_GROUP` | | -| `--hetzner-auto-spread` | `HETZNER_AUTO_SPREAD` | false | -| `--hetzner-ssh-user` | `HETZNER_SSH_USER` | root | -| `--hetzner-ssh-port` | `HETZNER_SSH_PORT` | 22 | -| `--hetzner-primary-ipv4` | `HETZNER_PRIMARY_IPV4` | | -| `--hetzner-primary-ipv6` | `HETZNER_PRIMARY_IPV6` | | -| `--hetzner-wait-on-error` | `HETZNER_WAIT_ON_ERROR` | 0 | +| CLI option | Environment variable | Default | +|--------------------------------------|------------------------------------|----------------------------| +| **`--hetzner-api-token`** | `HETZNER_API_TOKEN` | | +| `--hetzner-image` | `HETZNER_IMAGE` | `ubuntu-20.04` as fallback | +| `--hetzner-image-arch` | `HETZNER_IMAGE_ARCH` | *(infer from server)* | +| `--hetzner-image-id` | `HETZNER_IMAGE_ID` | | +| `--hetzner-server-type` | `HETZNER_TYPE` | `cx11` | +| `--hetzner-server-location` | `HETZNER_LOCATION` | *(let Hetzner choose)* | +| `--hetzner-existing-key-path` | `HETZNER_EXISTING_KEY_PATH` | *(generate new keypair)* | +| `--hetzner-existing-key-id` | `HETZNER_EXISTING_KEY_ID` | 0 *(upload new key)* | +| `--hetzner-additional-key` | `HETZNER_ADDITIONAL_KEYS` | | +| `--hetzner-user-data` | `HETZNER_USER_DATA` | | +| `--hetzner-user-data-file` | `HETZNER_USER_DATA_FILE` | | +| `--hetzner-networks` | `HETZNER_NETWORKS` | | +| `--hetzner-firewalls` | `HETZNER_FIREWALLS` | | +| `--hetzner-volumes` | `HETZNER_VOLUMES` | | +| `--hetzner-use-private-network` | `HETZNER_USE_PRIVATE_NETWORK` | false | +| `--hetzner-disable-public-ipv4` | `HETZNER_DISABLE_PUBLIC_IPV4` | false | +| `--hetzner-disable-public-ipv6` | `HETZNER_DISABLE_PUBLIC_IPV6` | false | +| `--hetzner-disable-public` | `HETZNER_DISABLE_PUBLIC` | false | +| `--hetzner-server-label` | (inoperative) | `[]` | +| `--hetzner-key-label` | (inoperative) | `[]` | +| `--hetzner-placement-group` | `HETZNER_PLACEMENT_GROUP` | | +| `--hetzner-auto-spread` | `HETZNER_AUTO_SPREAD` | false | +| `--hetzner-ssh-user` | `HETZNER_SSH_USER` | root | +| `--hetzner-ssh-port` | `HETZNER_SSH_PORT` | 22 | +| `--hetzner-primary-ipv4` | `HETZNER_PRIMARY_IPV4` | | +| `--hetzner-primary-ipv6` | `HETZNER_PRIMARY_IPV6` | | +| `--hetzner-wait-on-error` | `HETZNER_WAIT_ON_ERROR` | 0 | +| `--hetzner-wait-on-polling` | `HETZNER_WAIT_ON_POLLING` | 1 | +| `--hetzner-wait-for-running-timeout` | `HETZNER_WAIT_FOR_RUNNING_TIMEOUT` | 0 | #### Networking diff --git a/driver/driver.go b/driver/driver.go index 9a074b493d7480c7bf9f5f2912a44f0193e3a624..14180fd16f2c3f3591651f958963ce21f6df72b0 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -56,6 +56,8 @@ type Driver struct { cachedAdditionalKeys []*hcloud.SSHKey WaitOnError int + WaitOnPolling int + WaitForRunningTimeout int // internal housekeeping version string @@ -97,8 +99,12 @@ const ( defaultSSHPort = 22 defaultSSHUser = "root" - flagWaitOnError = "hetzner-wait-on-error" - defaultWaitOnError = 0 + flagWaitOnError = "hetzner-wait-on-error" + defaultWaitOnError = 0 + flagWaitOnPolling = "hetzner-wait-on-polling" + defaultWaitOnPolling = 1 + flagWaitForRunningTimeout = "hetzner-wait-for-running-timeout" + defaultWaitForRunningTimeout = 0 legacyFlagUserDataFromFile = "hetzner-user-data-from-file" legacyFlagDisablePublic4 = "hetzner-disable-public-4" @@ -298,6 +304,18 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag { Usage: "Wait if an error happens while creating the server", Value: defaultWaitOnError, }, + mcnflag.IntFlag{ + EnvVar: "HETZNER_WAIT_ON_POLLING", + Name: flagWaitOnPolling, + Usage: "Period for waiting between requests when waiting for some state to change", + Value: defaultWaitOnPolling, + }, + mcnflag.IntFlag{ + EnvVar: "HETZNER_WAIT_FOR_RUNNING_TIMEOUT", + Name: flagWaitForRunningTimeout, + Usage: "Period for waiting for a machine to be running before failing", + Value: defaultWaitForRunningTimeout, + }, } } @@ -339,6 +357,8 @@ func (d *Driver) setConfigFromFlagsImpl(opts drivers.DriverOptions) error { d.SSHPort = opts.Int(flagSshPort) d.WaitOnError = opts.Int(flagWaitOnError) + d.WaitOnPolling = opts.Int(flagWaitOnPolling) + d.WaitForRunningTimeout = opts.Int(flagWaitForRunningTimeout) d.placementGroup = opts.String(flagPlacementGroup) if opts.Bool(flagAutoSpread) { diff --git a/driver/hetzner_query.go b/driver/hetzner_query.go index 1064574268a67ac724852a0eb2a98f4e8c1ad078..4b2b87b5fea88eb0033ee7df8b50829981816caf 100644 --- a/driver/hetzner_query.go +++ b/driver/hetzner_query.go @@ -144,7 +144,7 @@ func (d *Driver) waitForAction(a *hcloud.Action) error { return act.Error() } - time.Sleep(1 * time.Second) + time.Sleep(time.Duration(d.WaitOnPolling) * time.Second) } return nil } diff --git a/driver/networking.go b/driver/networking.go index 41777b8716f77df261ba6188b911255d512ac051..acc4e066ec6b550257a9f84dc5cae23156df62a4 100644 --- a/driver/networking.go +++ b/driver/networking.go @@ -93,7 +93,7 @@ func (d *Driver) configureNetworkAccess(srv hcloud.ServerCreateResult) error { d.IPAddress = server.PrivateNet[0].IP.String() break } - time.Sleep(1 * time.Second) + time.Sleep(time.Duration(d.WaitOnPolling) * time.Second) } } else if d.DisablePublic4 { log.Infof("Using public IPv6 network ...") diff --git a/driver/setup.go b/driver/setup.go index f66e2c2c2f4adea881dcf9fab371f51734e4e21a..cabfa00f167a1d4bccf1d1f131df852e86020e90 100644 --- a/driver/setup.go +++ b/driver/setup.go @@ -10,6 +10,7 @@ import ( ) func (d *Driver) waitForRunningServer() error { + start_time := time.Now() for { srvstate, err := d.GetState() if err != nil { @@ -20,7 +21,12 @@ func (d *Driver) waitForRunningServer() error { break } - time.Sleep(1 * time.Second) + 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.") + } + + time.Sleep(time.Duration(d.WaitOnPolling) * time.Second) } return nil }