package hcloud import ( "context" "fmt" "io/ioutil" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hetznercloud/hcloud-go/hcloud" ) type stepCreateServer struct { serverId int } func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("hcloudClient").(*hcloud.Client) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) sshKeyId := state.Get("ssh_key_id").(int) // Create the server based on configuration ui.Say("Creating server...") userData := c.UserData if c.UserDataFile != "" { contents, err := ioutil.ReadFile(c.UserDataFile) if err != nil { state.Put("error", fmt.Errorf("Problem reading user data file: %s", err)) return multistep.ActionHalt } userData = string(contents) } serverCreateResult, _, err := client.Server.Create(context.TODO(), hcloud.ServerCreateOpts{ Name: c.ServerName, ServerType: &hcloud.ServerType{Name: c.ServerType}, Image: &hcloud.Image{Name: c.Image}, SSHKeys: []*hcloud.SSHKey{{ID: sshKeyId}}, Location: &hcloud.Location{Name: c.Location}, UserData: userData, }) if err != nil { err := fmt.Errorf("Error creating server: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } state.Put("server_ip", serverCreateResult.Server.PublicNet.IPv4.IP.String()) // We use this in cleanup s.serverId = serverCreateResult.Server.ID // Store the server id for later state.Put("server_id", serverCreateResult.Server.ID) _, errCh := client.Action.WatchProgress(context.TODO(), serverCreateResult.Action) for { select { case err1 := <-errCh: if err1 == nil { return multistep.ActionContinue } else { err := fmt.Errorf("Error creating server: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } } } } func (s *stepCreateServer) Cleanup(state multistep.StateBag) { // If the serverID isn't there, we probably never created it if s.serverId == 0 { return } client := state.Get("hcloudClient").(*hcloud.Client) ui := state.Get("ui").(packer.Ui) // Destroy the server we just created ui.Say("Destroying server...") _, err := client.Server.Delete(context.TODO(), &hcloud.Server{ID: s.serverId}) if err != nil { ui.Error(fmt.Sprintf( "Error destroying server. Please destroy it manually: %s", err)) } }