From 064e6c7e0866cd1a90ac5c02f07574a430f8766d Mon Sep 17 00:00:00 2001 From: dedene Date: Fri, 23 Nov 2018 20:35:32 +0100 Subject: [PATCH 1/4] Add support for builds using rescue mode --- builder/hcloud/config.go | 2 + builder/hcloud/step_create_server.go | 59 ++++++++++++++++++- .../docs/builders/hetzner-cloud.html.md | 2 + 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/builder/hcloud/config.go b/builder/hcloud/config.go index 3de43ab04..368eda258 100644 --- a/builder/hcloud/config.go +++ b/builder/hcloud/config.go @@ -35,6 +35,8 @@ type Config struct { UserDataFile string `mapstructure:"user_data_file"` SSHKeys []string `mapstructure:"ssh_keys"` + RescueMode string `mapstructure:"rescue"` + ctx interpolate.Context } diff --git a/builder/hcloud/step_create_server.go b/builder/hcloud/step_create_server.go index eca8d54ae..96d86d38a 100644 --- a/builder/hcloud/step_create_server.go +++ b/builder/hcloud/step_create_server.go @@ -68,11 +68,12 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu state.Put("server_id", serverCreateResult.Server.ID) _, errCh := client.Action.WatchProgress(context.TODO(), serverCreateResult.Action) +watch: for { select { case err1 := <-errCh: if err1 == nil { - return multistep.ActionContinue + break watch } else { err := fmt.Errorf("Error creating server: %s", err) state.Put("error", err) @@ -82,6 +83,17 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu } } + + if c.RescueMode != "" { + if err := setRescue(ctx, client, serverCreateResult.Server, c.RescueMode, sshKeys); err != nil { + err := fmt.Errorf("Error enabling rescue mode: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + return multistep.ActionContinue } func (s *stepCreateServer) Cleanup(state multistep.StateBag) { @@ -101,3 +113,48 @@ func (s *stepCreateServer) Cleanup(state multistep.StateBag) { "Error destroying server. Please destroy it manually: %s", err)) } } + +func setRescue(ctx context.Context, client *hcloud.Client, server *hcloud.Server, rescue string, sshKeys []*hcloud.SSHKey) error { + rescueChanged := false + if server.RescueEnabled { + rescueChanged = true + action, _, err := client.Server.DisableRescue(ctx, server) + if err != nil { + return err + } + if err := waitForServerAction(ctx, client, action, server); err != nil { + return err + } + } + if rescue != "" { + rescueChanged = true + res, _, err := client.Server.EnableRescue(ctx, server, hcloud.ServerEnableRescueOpts{ + Type: hcloud.ServerRescueType(rescue), + SSHKeys: sshKeys, + }) + if err != nil { + return err + } + if err := waitForServerAction(ctx, client, res.Action, server); err != nil { + return err + } + } + if rescueChanged { + action, _, err := client.Server.Reset(ctx, server) + if err != nil { + return err + } + if err := waitForServerAction(ctx, client, action, server); err != nil { + return err + } + } + return nil +} + +func waitForServerAction(ctx context.Context, client *hcloud.Client, action *hcloud.Action, server *hcloud.Server) error { + _, errCh := client.Action.WatchProgress(ctx, action) + if err := <-errCh; err != nil { + return err + } + return nil +} diff --git a/website/source/docs/builders/hetzner-cloud.html.md b/website/source/docs/builders/hetzner-cloud.html.md index 4b0ab5f5e..d18f5e761 100644 --- a/website/source/docs/builders/hetzner-cloud.html.md +++ b/website/source/docs/builders/hetzner-cloud.html.md @@ -72,6 +72,8 @@ builder. - `ssh_keys` (array of strings) - List of SSH keys by name or id to be added to image on launch. +- `rescue` (string) - Enable and boot in to the specified rescue system. This enables simple installation of custom operating systems. `linux64` `linux32` or `freebsd64` + ## Basic Example Here is a basic example. It is completely valid as soon as you enter your own From 0f3bfbf8e6bab3c15dc51d217426342addc7b1a3 Mon Sep 17 00:00:00 2001 From: dedene Date: Sat, 24 Nov 2018 17:56:09 +0100 Subject: [PATCH 2/4] Fix timing issues by updating to hcloud-go v1.11.0 --- builder/hcloud/step_create_server.go | 26 +++++++++---------- .../github.com/hetznercloud/hcloud-go/LICENSE | 0 .../hetznercloud/hcloud-go/hcloud/action.go | 2 +- .../hetznercloud/hcloud-go/hcloud/client.go | 0 .../hcloud-go/hcloud/datacenter.go | 7 ++--- .../hetznercloud/hcloud-go/hcloud/error.go | 0 .../hcloud-go/hcloud/floating_ip.go | 3 ++- .../hetznercloud/hcloud-go/hcloud/hcloud.go | 2 +- .../hetznercloud/hcloud-go/hcloud/helper.go | 0 .../hetznercloud/hcloud-go/hcloud/image.go | 7 ++--- .../hetznercloud/hcloud-go/hcloud/iso.go | 0 .../hetznercloud/hcloud-go/hcloud/location.go | 7 ++--- .../hetznercloud/hcloud-go/hcloud/pricing.go | 0 .../hetznercloud/hcloud-go/hcloud/schema.go | 9 +++++++ .../hcloud-go/hcloud/schema/action.go | 0 .../hcloud-go/hcloud/schema/datacenter.go | 0 .../hcloud-go/hcloud/schema/error.go | 0 .../hcloud-go/hcloud/schema/floating_ip.go | 0 .../hcloud-go/hcloud/schema/image.go | 0 .../hcloud-go/hcloud/schema/iso.go | 0 .../hcloud-go/hcloud/schema/location.go | 0 .../hcloud-go/hcloud/schema/meta.go | 0 .../hcloud-go/hcloud/schema/pricing.go | 0 .../hcloud-go/hcloud/schema/server.go | 7 ++--- .../hcloud-go/hcloud/schema/server_type.go | 0 .../hcloud-go/hcloud/schema/ssh_key.go | 0 .../hcloud-go/hcloud/schema/volume.go | 5 ++-- .../hetznercloud/hcloud-go/hcloud/server.go | 13 ++++++---- .../hcloud-go/hcloud/server_type.go | 7 ++--- .../hetznercloud/hcloud-go/hcloud/ssh_key.go | 9 ++++--- .../hetznercloud/hcloud-go/hcloud/volume.go | 18 +++++++------ 31 files changed, 71 insertions(+), 51 deletions(-) mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/LICENSE mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/helper.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/meta.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go mode change 100644 => 100755 vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go diff --git a/builder/hcloud/step_create_server.go b/builder/hcloud/step_create_server.go index 96d86d38a..e46d5f8ab 100644 --- a/builder/hcloud/step_create_server.go +++ b/builder/hcloud/step_create_server.go @@ -67,20 +67,18 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu // Store the server id for later state.Put("server_id", serverCreateResult.Server.ID) - _, errCh := client.Action.WatchProgress(context.TODO(), serverCreateResult.Action) -watch: - for { - select { - case err1 := <-errCh: - if err1 == nil { - break watch - } else { - err := fmt.Errorf("Error creating server: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - + if err := waitForServerAction(context.TODO(), client, serverCreateResult.Action, serverCreateResult.Server); err != nil { + err := fmt.Errorf("Error creating server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + for _, nextAction := range serverCreateResult.NextActions { + if err := waitForServerAction(context.TODO(), client, nextAction, serverCreateResult.Server); err != nil { + err := fmt.Errorf("Error creating server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } } diff --git a/vendor/github.com/hetznercloud/hcloud-go/LICENSE b/vendor/github.com/hetznercloud/hcloud-go/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go old mode 100644 new mode 100755 index c31af0ca4..a261891e2 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go @@ -74,7 +74,7 @@ type ActionClient struct { client *Client } -// GetByID retrieves an action by its ID. +// GetByID retrieves an action by its ID. If the action does not exist, nil is returned. func (c *ActionClient) GetByID(ctx context.Context, id int) (*Action, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/actions/%d", id), nil) if err != nil { diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go old mode 100644 new mode 100755 index 7b4429feb..b0717f942 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go @@ -29,7 +29,7 @@ type DatacenterClient struct { client *Client } -// GetByID retrieves a datacenter by its ID. +// GetByID retrieves a datacenter by its ID. If the datacenter does not exist, nil is returned. func (c *DatacenterClient) GetByID(ctx context.Context, id int) (*Datacenter, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/datacenters/%d", id), nil) if err != nil { @@ -47,7 +47,7 @@ func (c *DatacenterClient) GetByID(ctx context.Context, id int) (*Datacenter, *R return DatacenterFromSchema(body.Datacenter), resp, nil } -// GetByName retrieves an datacenter by its name. +// GetByName retrieves an datacenter by its name. If the datacenter does not exist, nil is returned. func (c *DatacenterClient) GetByName(ctx context.Context, name string) (*Datacenter, *Response, error) { path := "/datacenters?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -67,7 +67,8 @@ func (c *DatacenterClient) GetByName(ctx context.Context, name string) (*Datacen return DatacenterFromSchema(body.Datacenters[0]), resp, nil } -// Get retrieves a datacenter by its ID if the input can be parsed as an integer, otherwise it retrieves a datacenter by its name. +// Get retrieves a datacenter by its ID if the input can be parsed as an integer, otherwise it +// retrieves a datacenter by its name. If the datacenter does not exist, nil is returned. func (c *DatacenterClient) Get(ctx context.Context, idOrName string) (*Datacenter, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go old mode 100644 new mode 100755 index e1372db06..7fe2c55d0 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go @@ -50,7 +50,8 @@ type FloatingIPClient struct { client *Client } -// GetByID retrieves a Floating IP by its ID. +// GetByID retrieves a Floating IP by its ID. If the Floating IP does not exist, +// nil is returned. func (c *FloatingIPClient) GetByID(ctx context.Context, id int) (*FloatingIP, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/floating_ips/%d", id), nil) if err != nil { diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go old mode 100644 new mode 100755 index 8d3b398a3..032342ef4 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go @@ -2,4 +2,4 @@ package hcloud // Version is the library's version following Semantic Versioning. -const Version = "1.9.0" +const Version = "1.11.0" diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/helper.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/helper.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go old mode 100644 new mode 100755 index 7089facd3..4ebe4c3f5 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go @@ -71,7 +71,7 @@ type ImageClient struct { client *Client } -// GetByID retrieves an image by its ID. +// GetByID retrieves an image by its ID. If the image does not exist, nil is returned. func (c *ImageClient) GetByID(ctx context.Context, id int) (*Image, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/images/%d", id), nil) if err != nil { @@ -89,7 +89,7 @@ func (c *ImageClient) GetByID(ctx context.Context, id int) (*Image, *Response, e return ImageFromSchema(body.Image), resp, nil } -// GetByName retrieves an image by its name. +// GetByName retrieves an image by its name. If the image does not exist, nil is returned. func (c *ImageClient) GetByName(ctx context.Context, name string) (*Image, *Response, error) { path := "/images?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -109,7 +109,8 @@ func (c *ImageClient) GetByName(ctx context.Context, name string) (*Image, *Resp return ImageFromSchema(body.Images[0]), resp, nil } -// Get retrieves an image by its ID if the input can be parsed as an integer, otherwise it retrieves an image by its name. +// Get retrieves an image by its ID if the input can be parsed as an integer, otherwise it +// retrieves an image by its name. If the image does not exist, nil is returned. func (c *ImageClient) Get(ctx context.Context, idOrName string) (*Image, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go old mode 100644 new mode 100755 index 4ab55ef11..5269b7e76 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go @@ -25,7 +25,7 @@ type LocationClient struct { client *Client } -// GetByID retrieves a location by its ID. +// GetByID retrieves a location by its ID. If the location does not exist, nil is returned. func (c *LocationClient) GetByID(ctx context.Context, id int) (*Location, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/locations/%d", id), nil) if err != nil { @@ -43,7 +43,7 @@ func (c *LocationClient) GetByID(ctx context.Context, id int) (*Location, *Respo return LocationFromSchema(body.Location), resp, nil } -// GetByName retrieves an location by its name. +// GetByName retrieves an location by its name. If the location does not exist, nil is returned. func (c *LocationClient) GetByName(ctx context.Context, name string) (*Location, *Response, error) { path := "/locations?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -63,7 +63,8 @@ func (c *LocationClient) GetByName(ctx context.Context, name string) (*Location, return LocationFromSchema(body.Locations[0]), resp, nil } -// Get retrieves a location by its ID if the input can be parsed as an integer, otherwise it retrieves a location by its name. +// Get retrieves a location by its ID if the input can be parsed as an integer, otherwise it +// retrieves a location by its name. If the location does not exist, nil is returned. func (c *LocationClient) Get(ctx context.Context, idOrName string) (*Location, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go old mode 100644 new mode 100755 index 828033c4d..47a194f3a --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go @@ -35,6 +35,15 @@ func ActionFromSchema(s schema.Action) *Action { return action } +// ActionsFromSchema converts a slice of schema.Action to a slice of Action. +func ActionsFromSchema(s []schema.Action) []*Action { + var actions []*Action + for _, a := range s { + actions = append(actions, ActionFromSchema(a)) + } + return actions +} + // FloatingIPFromSchema converts a schema.FloatingIP to a FloatingIP. func FloatingIPFromSchema(s schema.FloatingIP) *FloatingIP { f := &FloatingIP{ diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/meta.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/meta.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go old mode 100644 new mode 100755 index f58e3b8ff..edaf54ce2 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go @@ -90,9 +90,10 @@ type ServerCreateRequest struct { // ServerCreateResponse defines the schema of the response when // creating a server. type ServerCreateResponse struct { - Server Server `json:"server"` - Action Action `json:"action"` - RootPassword *string `json:"root_password"` + Server Server `json:"server"` + Action Action `json:"action"` + RootPassword *string `json:"root_password"` + NextActions []Action `json:"next_actions"` } // ServerUpdateRequest defines the schema of the request to update a server. diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go old mode 100644 new mode 100755 diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go old mode 100644 new mode 100755 index aa6c699e9..a8aa79341 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go @@ -28,8 +28,9 @@ type VolumeCreateRequest struct { // VolumeCreateResponse defines the schema of the response // when creating a volume. type VolumeCreateResponse struct { - Volume Volume `json:"volume"` - Action *Action `json:"action"` + Volume Volume `json:"volume"` + Action *Action `json:"action"` + NextActions []Action `json:"next_actions"` } // VolumeListResponse defines the schema of the response diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go old mode 100644 new mode 100755 index b85861fc3..ad0b16e9d --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go @@ -97,7 +97,7 @@ type ServerClient struct { client *Client } -// GetByID retrieves a server by its ID. +// GetByID retrieves a server by its ID. If the server does not exist, nil is returned. func (c *ServerClient) GetByID(ctx context.Context, id int) (*Server, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/servers/%d", id), nil) if err != nil { @@ -115,7 +115,7 @@ func (c *ServerClient) GetByID(ctx context.Context, id int) (*Server, *Response, return ServerFromSchema(body.Server), resp, nil } -// GetByName retreives a server by its name. +// GetByName retreives a server by its name. If the server does not exist, nil is returned. func (c *ServerClient) GetByName(ctx context.Context, name string) (*Server, *Response, error) { path := "/servers?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -135,7 +135,8 @@ func (c *ServerClient) GetByName(ctx context.Context, name string) (*Server, *Re return ServerFromSchema(body.Servers[0]), resp, nil } -// Get retrieves a server by its ID if the input can be parsed as an integer, otherwise it retrieves a server by its name. +// Get retrieves a server by its ID if the input can be parsed as an integer, otherwise it +// retrieves a server by its name. If the server does not exist, nil is returned. func (c *ServerClient) Get(ctx context.Context, idOrName string) (*Server, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) @@ -228,6 +229,7 @@ type ServerCreateResult struct { Server *Server Action *Action RootPassword string + NextActions []*Action } // Create creates a new server. @@ -286,8 +288,9 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve return ServerCreateResult{}, resp, err } result := ServerCreateResult{ - Server: ServerFromSchema(respBody.Server), - Action: ActionFromSchema(respBody.Action), + Server: ServerFromSchema(respBody.Server), + Action: ActionFromSchema(respBody.Action), + NextActions: ActionsFromSchema(respBody.NextActions), } if respBody.RootPassword != nil { result.RootPassword = *respBody.RootPassword diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go old mode 100644 new mode 100755 index 8f4166c17..6f12bd680 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go @@ -49,7 +49,7 @@ type ServerTypeClient struct { client *Client } -// GetByID retrieves a server type by its ID. +// GetByID retrieves a server type by its ID. If the server type does not exist, nil is returned. func (c *ServerTypeClient) GetByID(ctx context.Context, id int) (*ServerType, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/server_types/%d", id), nil) if err != nil { @@ -67,7 +67,7 @@ func (c *ServerTypeClient) GetByID(ctx context.Context, id int) (*ServerType, *R return ServerTypeFromSchema(body.ServerType), resp, nil } -// GetByName retrieves a server type by its name. +// GetByName retrieves a server type by its name. If the server type does not exist, nil is returned. func (c *ServerTypeClient) GetByName(ctx context.Context, name string) (*ServerType, *Response, error) { path := "/server_types?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -87,7 +87,8 @@ func (c *ServerTypeClient) GetByName(ctx context.Context, name string) (*ServerT return ServerTypeFromSchema(body.ServerTypes[0]), resp, nil } -// Get retrieves a server type by its ID if the input can be parsed as an integer, otherwise it retrieves a server type by its name. +// Get retrieves a server type by its ID if the input can be parsed as an integer, otherwise it +// retrieves a server type by its name. If the server type does not exist, nil is returned. func (c *ServerTypeClient) Get(ctx context.Context, idOrName string) (*ServerType, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go old mode 100644 new mode 100755 index 2ab55bff6..7db8f0a9e --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go @@ -26,7 +26,7 @@ type SSHKeyClient struct { client *Client } -// GetByID retrieves a SSH key by its ID. +// GetByID retrieves a SSH key by its ID. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) GetByID(ctx context.Context, id int) (*SSHKey, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/ssh_keys/%d", id), nil) if err != nil { @@ -44,7 +44,7 @@ func (c *SSHKeyClient) GetByID(ctx context.Context, id int) (*SSHKey, *Response, return SSHKeyFromSchema(body.SSHKey), resp, nil } -// GetByName retrieves a SSH key by its name. +// GetByName retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) GetByName(ctx context.Context, name string) (*SSHKey, *Response, error) { path := "/ssh_keys?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -64,7 +64,7 @@ func (c *SSHKeyClient) GetByName(ctx context.Context, name string) (*SSHKey, *Re return SSHKeyFromSchema(body.SSHKeys[0]), resp, nil } -// GetByFingerprint retreives a SSH key by its fingerprint. +// GetByFingerprint retreives a SSH key by its fingerprint. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) GetByFingerprint(ctx context.Context, fingerprint string) (*SSHKey, *Response, error) { path := "/ssh_keys?fingerprint=" + url.QueryEscape(fingerprint) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -84,7 +84,8 @@ func (c *SSHKeyClient) GetByFingerprint(ctx context.Context, fingerprint string) return SSHKeyFromSchema(body.SSHKeys[0]), resp, nil } -// Get retrieves a SSH key by its ID if the input can be parsed as an integer, otherwise it retrieves a SSH key by its name. +// Get retrieves a SSH key by its ID if the input can be parsed as an integer, otherwise it +// retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) Get(ctx context.Context, idOrName string) (*SSHKey, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go old mode 100644 new mode 100755 index 4e5f4d0a9..735f3918b --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go +++ b/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go @@ -36,7 +36,7 @@ type VolumeClient struct { client *Client } -// GetByID retrieves a volume by its ID. +// GetByID retrieves a volume by its ID. If the volume does not exist, nil is returned. func (c *VolumeClient) GetByID(ctx context.Context, id int) (*Volume, *Response, error) { req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/volumes/%d", id), nil) if err != nil { @@ -54,7 +54,7 @@ func (c *VolumeClient) GetByID(ctx context.Context, id int) (*Volume, *Response, return VolumeFromSchema(body.Volume), resp, nil } -// GetByName retrieves a volume by its name. +// GetByName retrieves a volume by its name. If the volume does not exist, nil is returned. func (c *VolumeClient) GetByName(ctx context.Context, name string) (*Volume, *Response, error) { path := "/volumes?name=" + url.QueryEscape(name) req, err := c.client.NewRequest(ctx, "GET", path, nil) @@ -74,8 +74,8 @@ func (c *VolumeClient) GetByName(ctx context.Context, name string) (*Volume, *Re return VolumeFromSchema(body.Volumes[0]), resp, nil } -// Get retrieves a volume by its ID if the input can be parsed as an integer, -// otherwise it retrieves a volume by its name. +// Get retrieves a volume by its ID if the input can be parsed as an integer, otherwise it +// retrieves a volume by its name. If the volume does not exist, nil is returned. func (c *VolumeClient) Get(ctx context.Context, idOrName string) (*Volume, *Response, error) { if id, err := strconv.Atoi(idOrName); err == nil { return c.GetByID(ctx, int(id)) @@ -161,8 +161,9 @@ func (o VolumeCreateOpts) Validate() error { // VolumeCreateResult is the result of creating a volume. type VolumeCreateResult struct { - Volume *Volume - Action *Action + Volume *Volume + Action *Action + NextActions []*Action } // Create creates a new volume with the given options. @@ -209,8 +210,9 @@ func (c *VolumeClient) Create(ctx context.Context, opts VolumeCreateOpts) (Volum } return VolumeCreateResult{ - Volume: VolumeFromSchema(respBody.Volume), - Action: action, + Volume: VolumeFromSchema(respBody.Volume), + Action: action, + NextActions: ActionsFromSchema(respBody.NextActions), }, resp, nil } From 6589bfaaabc8d06cc6c4ae333be1c72677152d6d Mon Sep 17 00:00:00 2001 From: dedene Date: Mon, 26 Nov 2018 09:10:17 +0100 Subject: [PATCH 3/4] Small code improvements and fixes --- builder/hcloud/step_create_server.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/builder/hcloud/step_create_server.go b/builder/hcloud/step_create_server.go index e46d5f8ab..de81970fc 100644 --- a/builder/hcloud/step_create_server.go +++ b/builder/hcloud/step_create_server.go @@ -67,14 +67,14 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu // Store the server id for later state.Put("server_id", serverCreateResult.Server.ID) - if err := waitForServerAction(context.TODO(), client, serverCreateResult.Action, serverCreateResult.Server); err != nil { + if err := waitForAction(context.TODO(), client, serverCreateResult.Action); err != nil { err := fmt.Errorf("Error creating server: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } for _, nextAction := range serverCreateResult.NextActions { - if err := waitForServerAction(context.TODO(), client, nextAction, serverCreateResult.Server); err != nil { + if err := waitForAction(context.TODO(), client, nextAction); err != nil { err := fmt.Errorf("Error creating server: %s", err) state.Put("error", err) ui.Error(err.Error()) @@ -83,7 +83,7 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu } if c.RescueMode != "" { - if err := setRescue(ctx, client, serverCreateResult.Server, c.RescueMode, sshKeys); err != nil { + if err := setRescue(context.TODO(), client, serverCreateResult.Server, c.RescueMode, sshKeys); err != nil { err := fmt.Errorf("Error enabling rescue mode: %s", err) state.Put("error", err) ui.Error(err.Error()) @@ -120,7 +120,7 @@ func setRescue(ctx context.Context, client *hcloud.Client, server *hcloud.Server if err != nil { return err } - if err := waitForServerAction(ctx, client, action, server); err != nil { + if err := waitForAction(ctx, client, action); err != nil { return err } } @@ -133,23 +133,23 @@ func setRescue(ctx context.Context, client *hcloud.Client, server *hcloud.Server if err != nil { return err } - if err := waitForServerAction(ctx, client, res.Action, server); err != nil { + if err := waitForAction(ctx, client, res.Action); err != nil { return err } } if rescueChanged { - action, _, err := client.Server.Reset(ctx, server) + action, _, err := client.Server.Reboot(ctx, server) if err != nil { return err } - if err := waitForServerAction(ctx, client, action, server); err != nil { + if err := waitForAction(ctx, client, action); err != nil { return err } } return nil } -func waitForServerAction(ctx context.Context, client *hcloud.Client, action *hcloud.Action, server *hcloud.Server) error { +func waitForAction(ctx context.Context, client *hcloud.Client, action *hcloud.Action) error { _, errCh := client.Action.WatchProgress(ctx, action) if err := <-errCh; err != nil { return err From 1aaa998b02b8d1a39dfd315f8bc81c1fad0a7ad0 Mon Sep 17 00:00:00 2001 From: dedene Date: Mon, 26 Nov 2018 09:49:45 +0100 Subject: [PATCH 4/4] Revert back to reset server --- builder/hcloud/step_create_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hcloud/step_create_server.go b/builder/hcloud/step_create_server.go index de81970fc..89c80d88f 100644 --- a/builder/hcloud/step_create_server.go +++ b/builder/hcloud/step_create_server.go @@ -138,7 +138,7 @@ func setRescue(ctx context.Context, client *hcloud.Client, server *hcloud.Server } } if rescueChanged { - action, _, err := client.Server.Reboot(ctx, server) + action, _, err := client.Server.Reset(ctx, server) if err != nil { return err }