From addc3dd6e795fdd353ced04f5e21fa1fc8073bcd Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 20 Aug 2020 18:33:02 -0500 Subject: [PATCH 1/5] refactor: change step_cleanup_volumes to new OSC SDK --- builder/osc/common/step_cleanup_volumes.go | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/builder/osc/common/step_cleanup_volumes.go b/builder/osc/common/step_cleanup_volumes.go index 79d3e123f..9cce3df59 100644 --- a/builder/osc/common/step_cleanup_volumes.go +++ b/builder/osc/common/step_cleanup_volumes.go @@ -5,25 +5,29 @@ import ( "fmt" "reflect" + "github.com/antihax/optional" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) -// stepCleanupVolumes cleans up any orphaned volumes that were not designated to +// StepCleanupVolumes cleans up any orphaned volumes that were not designated to // remain after termination of the vm. These volumes are typically ones // that are marked as "delete on terminate:false" in the source_ami of a build. type StepCleanupVolumes struct { BlockDevices BlockDevices } +//Run ... func (s *StepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // stepCleanupVolumes is for Cleanup only return multistep.ActionContinue } +// Cleanup ... func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { - oapiconn := state.Get("oapi").(*oapi.Client) + oscconn := state.Get("osc").(*osc.APIClient) vmRaw := state.Get("vm") var vm oapi.Vm if vmRaw != nil { @@ -50,10 +54,12 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { // Using the volume list from the cached Vm, check with Outscale for up to // date information on them - resp, err := oapiconn.POST_ReadVolumes(oapi.ReadVolumesRequest{ - Filters: oapi.FiltersVolume{ - VolumeIds: vl, - }, + resp, _, err := oscconn.VolumeApi.ReadVolumes(context.Background(), &osc.ReadVolumesOpts{ + ReadVolumesRequest: optional.NewInterface(osc.ReadVolumesRequest{ + Filters: osc.FiltersVolume{ + VolumeIds: vl, + }, + }), }) if err != nil { @@ -63,13 +69,13 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { // If any of the returned volumes are in a "deleting" stage or otherwise not // available, remove them from the list of volumes - for _, v := range resp.OK.Volumes { + for _, v := range resp.Volumes { if v.State != "" && v.State != "available" { delete(volList, v.VolumeId) } } - if len(resp.OK.Volumes) == 0 { + if len(resp.Volumes) == 0 { ui.Say("No volumes to clean up, skipping") return } @@ -87,10 +93,11 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { // Destroy remaining volumes for k := range volList { ui.Say(fmt.Sprintf("Destroying volume (%s)...", k)) - _, err := oapiconn.POST_DeleteVolume(oapi.DeleteVolumeRequest{VolumeId: k}) + _, _, err := oscconn.VolumeApi.DeleteVolume(context.Background(), &osc.DeleteVolumeOpts{ + DeleteVolumeRequest: optional.NewInterface(osc.DeleteVolumeRequest{VolumeId: k}), + }) if err != nil { ui.Say(fmt.Sprintf("Error deleting volume: %s", err)) } - } } From e5c14044fb125b4ded930444c75e1656cd70eccf Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 20 Aug 2020 19:12:38 -0500 Subject: [PATCH 2/5] refactor: change tags file to new OSC SDK --- builder/osc/common/tags.go | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/builder/osc/common/tags.go b/builder/osc/common/tags.go index c42d48db7..425bfbc1d 100644 --- a/builder/osc/common/tags.go +++ b/builder/osc/common/tags.go @@ -1,16 +1,20 @@ package common import ( + "context" "fmt" + "github.com/antihax/optional" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) type TagMap map[string]string type OAPITags []oapi.ResourceTag +type OSCTags []osc.ResourceTag func (t OAPITags) Report(ui packer.Ui) { for _, tag := range t { @@ -19,6 +23,13 @@ func (t OAPITags) Report(ui packer.Ui) { } } +func (t OSCTags) Report(ui packer.Ui) { + for _, tag := range t { + ui.Message(fmt.Sprintf("Adding tag: \"%s\": \"%s\"", + tag.Key, tag.Value)) + } +} + func (t TagMap) IsSet() bool { return len(t) > 0 } @@ -44,6 +55,27 @@ func (t TagMap) OAPITags(ctx interpolate.Context, region string, state multistep return oapiTags, nil } +func (t TagMap) OSCTags(ctx interpolate.Context, region string, state multistep.StateBag) (OSCTags, error) { + var oscTags []osc.ResourceTag + ctx.Data = extractBuildInfo(region, state) + + for key, value := range t { + interpolatedKey, err := interpolate.Render(key, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + interpolatedValue, err := interpolate.Render(value, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + oscTags = append(oscTags, osc.ResourceTag{ + Key: interpolatedKey, + Value: interpolatedValue, + }) + } + return oscTags, nil +} + func CreateTags(conn *oapi.Client, resourceID string, ui packer.Ui, tags OAPITags) error { tags.Report(ui) @@ -54,3 +86,16 @@ func CreateTags(conn *oapi.Client, resourceID string, ui packer.Ui, tags OAPITag return err } + +func CreateOSCTags(conn *osc.APIClient, resourceID string, ui packer.Ui, tags OSCTags) error { + tags.Report(ui) + + _, _, err := conn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{ + CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{ + ResourceIds: []string{resourceID}, + Tags: tags, + }), + }) + + return err +} From 6f0bb33c9a2a90f938159673b4388d7bede4f644 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 20 Aug 2020 20:35:51 -0500 Subject: [PATCH 3/5] refactor: change tags ssh file to new OSC SDK --- builder/osc/common/ssh.go | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/builder/osc/common/ssh.go b/builder/osc/common/ssh.go index 829165d0c..55e39289f 100644 --- a/builder/osc/common/ssh.go +++ b/builder/osc/common/ssh.go @@ -1,18 +1,27 @@ package common import ( + "context" "errors" "fmt" "time" + "net/http" + + "github.com/antihax/optional" "github.com/hashicorp/packer/helper/multistep" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) type oapiDescriber interface { POST_ReadVms(oapi.ReadVmsRequest) (*oapi.POST_ReadVmsResponses, error) } +type oscDescriber interface { + ReadVms(ctx context.Context, localVarOptionals *osc.ReadVmsOpts) (osc.ReadVmsResponse, *http.Response, error) +} + var ( // modified in tests sshHostSleepDuration = time.Second @@ -83,3 +92,72 @@ func SSHHost(e oapiDescriber, sshInterface string) func(multistep.StateBag) (str return "", errors.New("couldn't determine address for vm") } } + +// SSHHost returns a function that can be given to the SSH communicator +// for determining the SSH address based on the vm DNS name. +func OscSSHHost(e oscDescriber, sshInterface string) func(multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { + const tries = 2 + // <= with current structure to check result of describing `tries` times + for j := 0; j <= tries; j++ { + var host string + i := state.Get("vm").(osc.Vm) + + if sshInterface != "" { + switch sshInterface { + case "public_ip": + if i.PublicIp != "" { + host = i.PublicIp + } + case "public_dns": + if i.PublicDnsName != "" { + host = i.PublicDnsName + } + case "private_ip": + if i.PrivateIp != "" { + host = i.PrivateIp + } + case "private_dns": + if i.PrivateDnsName != "" { + host = i.PrivateDnsName + } + default: + panic(fmt.Sprintf("Unknown interface type: %s", sshInterface)) + } + } else if i.NetId != "" { + if i.PublicIp != "" { + host = i.PublicIp + } else if i.PrivateIp != "" { + host = i.PrivateIp + } + } else if i.PublicDnsName != "" { + host = i.PublicDnsName + } + + if host != "" { + return host, nil + } + + r, _, err := e.ReadVms(context.Background(), &osc.ReadVmsOpts{ + ReadVmsRequest: optional.NewInterface(osc.ReadVmsRequest{ + Filters: osc.FiltersVm{ + VmIds: []string{i.VmId}, + }, + }), + }) + + if err != nil { + return "", err + } + + if len(r.Vms) == 0 { + return "", fmt.Errorf("vm not found: %s", i.VmId) + } + + state.Put("vm", r.Vms[0]) + time.Sleep(sshHostSleepDuration) + } + + return "", errors.New("couldn't determine address for vm") + } +} From c58d6f9b33ec92a324a0699e424c1b5aa548bb5b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 20 Aug 2020 20:37:09 -0500 Subject: [PATCH 4/5] refactor: migrate run vm step to new SDK --- builder/osc/bsu/builder.go | 5 +- builder/osc/bsu/step_create_omi.go | 3 +- builder/osc/common/block_device.go | 51 ++++++++++++ builder/osc/common/ssh.go | 2 +- builder/osc/common/state.go | 46 +++++++++++ builder/osc/common/step_cleanup_volumes.go | 7 +- builder/osc/common/step_get_password.go | 3 +- builder/osc/common/step_run_source_vm.go | 81 +++++++++++-------- builder/osc/common/step_stop_bsu_backed_vm.go | 3 +- 9 files changed, 158 insertions(+), 43 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index dc2906244..e81c9d084 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -164,6 +164,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, VolumeTags: b.config.VolumeRunTags, + RawRegion: b.config.RawRegion, }, &osccommon.StepGetPassword{ Debug: b.config.PackerDebug, @@ -173,8 +174,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, - Host: osccommon.SSHHost( - oapiconn, + Host: osccommon.OscSSHHost( + oscConn.VmApi, b.config.SSHInterface), SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), }, diff --git a/builder/osc/bsu/step_create_omi.go b/builder/osc/bsu/step_create_omi.go index 2ccd538e3..cb935d89d 100644 --- a/builder/osc/bsu/step_create_omi.go +++ b/builder/osc/bsu/step_create_omi.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) type stepCreateOMI struct { @@ -18,7 +19,7 @@ type stepCreateOMI struct { func (s *stepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) oapiconn := state.Get("oapi").(*oapi.Client) - vm := state.Get("vm").(oapi.Vm) + vm := state.Get("vm").(osc.Vm) ui := state.Get("ui").(packer.Ui) // Create the image diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index 3f72076d5..7c0c90034 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/hashicorp/packer/template/interpolate" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) // BlockDevice @@ -123,6 +124,52 @@ func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCre return blockDevices } +func buildOscBlockDevicesVmCreation(b []BlockDevice) []osc.BlockDeviceMappingVmCreation { + log.Printf("[DEBUG] Launch Block Device %#v", b) + + var blockDevices []osc.BlockDeviceMappingVmCreation + + for _, blockDevice := range b { + mapping := osc.BlockDeviceMappingVmCreation{ + DeviceName: blockDevice.DeviceName, + } + + if blockDevice.NoDevice { + mapping.NoDevice = "" + } else if blockDevice.VirtualName != "" { + if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { + mapping.VirtualDeviceName = blockDevice.VirtualName + } + } else { + bsu := osc.BsuToCreate{ + DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + } + + if blockDevice.VolumeType != "" { + bsu.VolumeType = blockDevice.VolumeType + } + + if blockDevice.VolumeSize > 0 { + bsu.VolumeSize = int32(blockDevice.VolumeSize) + } + + // IOPS is only valid for io1 type + if blockDevice.VolumeType == "io1" { + bsu.Iops = int32(blockDevice.IOPS) + } + + if blockDevice.SnapshotId != "" { + bsu.SnapshotId = blockDevice.SnapshotId + } + + mapping.Bsu = bsu + } + + blockDevices = append(blockDevices, mapping) + } + return blockDevices +} + func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { if b.DeviceName == "" { return fmt.Errorf("The `device_name` must be specified " + @@ -152,3 +199,7 @@ func (b *OMIBlockDevices) BuildOMIDevices() []oapi.BlockDeviceMappingImage { func (b *LaunchBlockDevices) BuildLaunchDevices() []oapi.BlockDeviceMappingVmCreation { return buildBlockDevicesVmCreation(b.LaunchMappings) } + +func (b *LaunchBlockDevices) BuildOSCLaunchDevices() []osc.BlockDeviceMappingVmCreation { + return buildOscBlockDevicesVmCreation(b.LaunchMappings) +} diff --git a/builder/osc/common/ssh.go b/builder/osc/common/ssh.go index 55e39289f..f45473808 100644 --- a/builder/osc/common/ssh.go +++ b/builder/osc/common/ssh.go @@ -35,7 +35,7 @@ func SSHHost(e oapiDescriber, sshInterface string) func(multistep.StateBag) (str // <= with current structure to check result of describing `tries` times for j := 0; j <= tries; j++ { var host string - i := state.Get("vm").(oapi.Vm) + i := state.Get("vm").(osc.Vm) if sshInterface != "" { switch sshInterface { diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index b1d5bebaa..dd9ddc378 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -1,11 +1,14 @@ package common import ( + "context" "fmt" "log" + "github.com/antihax/optional" "github.com/hashicorp/packer/common" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) type stateRefreshFunc func() (string, error) @@ -24,12 +27,25 @@ func waitUntilForVmRunning(conn *oapi.Client, vmID string) error { return err } +func waitUntilForOscVmRunning(conn *osc.APIClient, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "running", waitUntilOscVmStateFunc(conn, vmID)) + err := <-errCh + return err +} + func waitUntilVmDeleted(conn *oapi.Client, vmID string) error { errCh := make(chan error, 1) go waitForState(errCh, "terminated", waitUntilVmStateFunc(conn, vmID)) return <-errCh } +func waitUntilOscVmDeleted(conn *osc.APIClient, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "terminated", waitUntilOscVmStateFunc(conn, vmID)) + return <-errCh +} + func waitUntilVmStopped(conn *oapi.Client, vmID string) error { errCh := make(chan error, 1) go waitForState(errCh, "stopped", waitUntilVmStateFunc(conn, vmID)) @@ -113,6 +129,36 @@ func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc { } } +func waitUntilOscVmStateFunc(conn *osc.APIClient, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Retrieving state for VM with id %s", id) + resp, _, err := conn.VmApi.ReadVms(context.Background(), &osc.ReadVmsOpts{ + ReadVmsRequest: optional.NewInterface(osc.ReadVmsRequest{ + Filters: osc.FiltersVm{ + VmIds: []string{id}, + }, + }), + }) + + log.Printf("[Debug] Read Response %+v", resp) + + if err != nil { + return "", err + } + + //TODO: check if needed + // if resp == nil { + // return "", fmt.Errorf("Vm with ID %s not Found", id) + // } + + if len(resp.Vms) == 0 { + return "pending", nil + } + + return resp.Vms[0].State, nil + } +} + func waitUntilVolumeLinkedStateFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if volume with id %s exists", id) diff --git a/builder/osc/common/step_cleanup_volumes.go b/builder/osc/common/step_cleanup_volumes.go index 9cce3df59..92bda011d 100644 --- a/builder/osc/common/step_cleanup_volumes.go +++ b/builder/osc/common/step_cleanup_volumes.go @@ -8,7 +8,6 @@ import ( "github.com/antihax/optional" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/outscale/osc-go/oapi" "github.com/outscale/osc-sdk-go/osc" ) @@ -29,9 +28,9 @@ func (s *StepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) mu func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { oscconn := state.Get("osc").(*osc.APIClient) vmRaw := state.Get("vm") - var vm oapi.Vm + var vm osc.Vm if vmRaw != nil { - vm = vmRaw.(oapi.Vm) + vm = vmRaw.(osc.Vm) } ui := state.Get("ui").(packer.Ui) if vm.VmId == "" { @@ -46,7 +45,7 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { var vl []string volList := make(map[string]string) for _, bdm := range vm.BlockDeviceMappings { - if !reflect.DeepEqual(bdm.Bsu, oapi.BsuCreated{}) { + if !reflect.DeepEqual(bdm.Bsu, osc.BsuCreated{}) { vl = append(vl, bdm.Bsu.VolumeId) volList[bdm.Bsu.VolumeId] = bdm.DeviceName } diff --git a/builder/osc/common/step_get_password.go b/builder/osc/common/step_get_password.go index 9971379d5..178babc8c 100644 --- a/builder/osc/common/step_get_password.go +++ b/builder/osc/common/step_get_password.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) // StepGetPassword reads the password from a Windows server and sets it @@ -103,7 +104,7 @@ func (s *StepGetPassword) Cleanup(multistep.StateBag) {} func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { oapiconn := state.Get("oapi").(*oapi.Client) - vm := state.Get("vm").(oapi.Vm) + vm := state.Get("vm").(osc.Vm) privateKey := s.Comm.SSHPrivateKey for { diff --git a/builder/osc/common/step_run_source_vm.go b/builder/osc/common/step_run_source_vm.go index 7777e913c..f4c13604f 100644 --- a/builder/osc/common/step_run_source_vm.go +++ b/builder/osc/common/step_run_source_vm.go @@ -8,6 +8,7 @@ import ( "log" "reflect" + "github.com/antihax/optional" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/outscale/osc-go/oapi" "github.com/outscale/osc-sdk-go/osc" @@ -40,13 +41,13 @@ type StepRunSourceVm struct { UserData string UserDataFile string VolumeTags TagMap + RawRegion string vmId string } func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - oapiconn := state.Get("oapi").(*oapi.Client) - + oscconn := state.Get("osc").(*osc.APIClient) securityGroupIds := state.Get("securityGroupIds").([]string) ui := state.Get("ui").(packer.Ui) @@ -90,7 +91,9 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul s.Tags["Name"] = "Packer Builder" } - oapiTags, err := s.Tags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + rawRegion := s.RawRegion + + oscTags, err := s.Tags.OSCTags(s.Ctx, rawRegion, state) if err != nil { err := fmt.Errorf("Error tagging source vm: %s", err) state.Put("error", err) @@ -98,7 +101,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul return multistep.ActionHalt } - volTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + volTags, err := s.VolumeTags.OSCTags(s.Ctx, rawRegion, state) if err != nil { err := fmt.Errorf("Error tagging volumes: %s", err) state.Put("error", err) @@ -107,15 +110,15 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } subregion := state.Get("subregion_name").(string) - runOpts := oapi.CreateVmsRequest{ + runOpts := osc.CreateVmsRequest{ ImageId: s.SourceOMI, VmType: s.VmType, UserData: userData, MaxVmsCount: 1, MinVmsCount: 1, - Placement: oapi.Placement{SubregionName: subregion}, + Placement: osc.Placement{SubregionName: subregion}, BsuOptimized: s.BsuOptimized, - BlockDeviceMappings: s.BlockDevices.BuildLaunchDevices(), + BlockDeviceMappings: s.BlockDevices.BuildOSCLaunchDevices(), //IamVmProfile: oapi.IamVmProfileSpecification{Name: &s.IamVmProfile}, } @@ -156,24 +159,27 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul runOpts.KeypairName = s.Comm.SSHKeyPairName } - subnetId := state.Get("subnet_id").(string) + subnetID := state.Get("subnet_id").(string) - runOpts.SubnetId = subnetId + runOpts.SubnetId = subnetID runOpts.SecurityGroupIds = securityGroupIds if s.ExpectedRootDevice == "bsu" { runOpts.VmInitiatedShutdownBehavior = s.VmInitiatedShutdownBehavior } - runResp, err := oapiconn.POST_CreateVms(runOpts) + runResp, _, err := oscconn.VmApi.CreateVms(context.Background(), &osc.CreateVmsOpts{ + CreateVmsRequest: optional.NewInterface(runOpts), + }) + if err != nil { err := fmt.Errorf("Error launching source vm: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - vmId = runResp.OK.Vms[0].VmId - volumeId := runResp.OK.Vms[0].BlockDeviceMappings[0].Bsu.VolumeId + vmId = runResp.Vms[0].VmId + volumeId := runResp.Vms[0].BlockDeviceMappings[0].Bsu.VolumeId // Set the vm ID so that the cleanup works properly s.vmId = vmId @@ -181,12 +187,12 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul ui.Message(fmt.Sprintf("Vm ID: %s", vmId)) ui.Say(fmt.Sprintf("Waiting for vm (%v) to become ready...", vmId)) - request := oapi.ReadVmsRequest{ - Filters: oapi.FiltersVm{ + request := osc.ReadVmsRequest{ + Filters: osc.FiltersVm{ VmIds: []string{vmId}, }, } - if err := waitUntilForVmRunning(oapiconn, vmId); err != nil { + if err := waitUntilForOscVmRunning(oscconn, vmId); err != nil { err := fmt.Errorf("Error waiting for vm (%s) to become ready: %s", vmId, err) state.Put("error", err) ui.Error(err.Error()) @@ -194,8 +200,8 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } //Set Vm tags and vollume tags - if len(oapiTags) > 0 { - if err := CreateTags(oapiconn, s.vmId, ui, oapiTags); err != nil { + if len(oscTags) > 0 { + if err := CreateOSCTags(oscconn, s.vmId, ui, oscTags); err != nil { err := fmt.Errorf("Error creating tags for vm (%s): %s", s.vmId, err) state.Put("error", err) ui.Error(err.Error()) @@ -204,7 +210,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } if len(volTags) > 0 { - if err := CreateTags(oapiconn, volumeId, ui, volTags); err != nil { + if err := CreateOSCTags(oscconn, volumeId, ui, volTags); err != nil { err := fmt.Errorf("Error creating tags for volume (%s): %s", volumeId, err) state.Put("error", err) ui.Error(err.Error()) @@ -214,7 +220,9 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul if publicip_id, ok := state.Get("publicip_id").(string); ok { ui.Say(fmt.Sprintf("Linking temporary PublicIp %s to instance %s", publicip_id, vmId)) - _, err := oapiconn.POST_LinkPublicIp(oapi.LinkPublicIpRequest{PublicIpId: publicip_id, VmId: vmId}) + _, _, err := oscconn.PublicIpApi.LinkPublicIp(context.Background(), &osc.LinkPublicIpOpts{ + LinkPublicIpRequest: optional.NewInterface(osc.LinkPublicIpRequest{PublicIpId: publicip_id, VmId: vmId}), + }) if err != nil { state.Put("error", fmt.Errorf("Error linking PublicIp to VM: %s", err)) ui.Error(err.Error()) @@ -222,9 +230,11 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } } - resp, err := oapiconn.POST_ReadVms(request) + resp, _, err := oscconn.VmApi.ReadVms(context.Background(), &osc.ReadVmsOpts{ + ReadVmsRequest: optional.NewInterface(request), + }) - r := resp.OK + r := resp if err != nil || len(r.Vms) == 0 { err := fmt.Errorf("Error finding source vm.") @@ -257,12 +267,14 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul // do that now. if s.IsRestricted { - oapiTags.Report(ui) + oscTags.Report(ui) // Retry creating tags for about 2.5 minutes err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { - _, err := oapiconn.POST_CreateTags(oapi.CreateTagsRequest{ - Tags: oapiTags, - ResourceIds: []string{vmId}, + _, _, err := oscconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{ + CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{ + Tags: oscTags, + ResourceIds: []string{vmId}, + }), }) if err == nil { return true, nil @@ -295,7 +307,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source BSU Volumes") - volumeTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + volumeTags, err := s.VolumeTags.OSCTags(s.Ctx, rawRegion, state) if err != nil { err := fmt.Errorf("Error tagging source BSU Volumes on %s: %s", vm.VmId, err) state.Put("error", err) @@ -304,9 +316,11 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } volumeTags.Report(ui) - _, err = oapiconn.POST_CreateTags(oapi.CreateTagsRequest{ - ResourceIds: volumeIds, - Tags: volumeTags, + _, _, err = oscconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{ + CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{ + ResourceIds: volumeIds, + Tags: volumeTags, + }), }) if err != nil { @@ -322,19 +336,20 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul } func (s *StepRunSourceVm) Cleanup(state multistep.StateBag) { - - oapiconn := state.Get("oapi").(*oapi.Client) + oscconn := state.Get("osc").(*osc.APIClient) ui := state.Get("ui").(packer.Ui) // Terminate the source vm if it exists if s.vmId != "" { ui.Say("Terminating the source OUTSCALE vm...") - if _, err := oapiconn.POST_DeleteVms(oapi.DeleteVmsRequest{VmIds: []string{s.vmId}}); err != nil { + if _, _, err := oscconn.VmApi.DeleteVms(context.Background(), &osc.DeleteVmsOpts{ + DeleteVmsRequest: optional.NewInterface(osc.DeleteVmsRequest{VmIds: []string{s.vmId}}), + }); err != nil { ui.Error(fmt.Sprintf("Error terminating vm, may still be around: %s", err)) return } - if err := waitUntilVmDeleted(oapiconn, s.vmId); err != nil { + if err := waitUntilOscVmDeleted(oscconn, s.vmId); err != nil { ui.Error(err.Error()) } } diff --git a/builder/osc/common/step_stop_bsu_backed_vm.go b/builder/osc/common/step_stop_bsu_backed_vm.go index 02076d35d..79bd693c8 100644 --- a/builder/osc/common/step_stop_bsu_backed_vm.go +++ b/builder/osc/common/step_stop_bsu_backed_vm.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/outscale/osc-go/oapi" + "github.com/outscale/osc-sdk-go/osc" ) type StepStopBSUBackedVm struct { @@ -18,7 +19,7 @@ type StepStopBSUBackedVm struct { func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { oapiconn := state.Get("oapi").(*oapi.Client) - vm := state.Get("vm").(oapi.Vm) + vm := state.Get("vm").(osc.Vm) ui := state.Get("ui").(packer.Ui) // Skip when it is a spot vm From 7a45e4c8b074600d9327f1dadf6ba7bdb5eef7ca Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 21 Aug 2020 10:40:14 -0500 Subject: [PATCH 5/5] refactor: change step tag bsu volumes to new OSC SDK --- builder/osc/common/state.go | 6 ++++++ builder/osc/common/step_stop_bsu_backed_vm.go | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index dd9ddc378..62e763043 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -52,6 +52,12 @@ func waitUntilVmStopped(conn *oapi.Client, vmID string) error { return <-errCh } +func waitUntilOscVmStopped(conn *osc.APIClient, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "stopped", waitUntilOscVmStateFunc(conn, vmID)) + return <-errCh +} + func WaitUntilSnapshotCompleted(conn *oapi.Client, id string) error { errCh := make(chan error, 1) go waitForState(errCh, "completed", waitUntilSnapshotStateFunc(conn, id)) diff --git a/builder/osc/common/step_stop_bsu_backed_vm.go b/builder/osc/common/step_stop_bsu_backed_vm.go index 79bd693c8..9c31a3c8b 100644 --- a/builder/osc/common/step_stop_bsu_backed_vm.go +++ b/builder/osc/common/step_stop_bsu_backed_vm.go @@ -4,11 +4,11 @@ import ( "context" "fmt" + "github.com/antihax/optional" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/outscale/osc-go/oapi" "github.com/outscale/osc-sdk-go/osc" ) @@ -18,7 +18,7 @@ type StepStopBSUBackedVm struct { } func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - oapiconn := state.Get("oapi").(*oapi.Client) + oscconn := state.Get("osc").(*osc.APIClient) vm := state.Get("vm").(osc.Vm) ui := state.Get("ui").(packer.Ui) @@ -44,8 +44,10 @@ func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) err := common.Retry(10, 60, 6, func(i uint) (bool, error) { ui.Message(fmt.Sprintf("Stopping vm, attempt %d", i+1)) - _, err = oapiconn.POST_StopVms(oapi.StopVmsRequest{ - VmIds: []string{vm.VmId}, + _, _, err = oscconn.VmApi.StopVms(context.Background(), &osc.StopVmsOpts{ + StopVmsRequest: optional.NewInterface(osc.StopVmsRequest{ + VmIds: []string{vm.VmId}, + }), }) if err == nil { @@ -79,7 +81,7 @@ func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) // Wait for the vm to actually stop ui.Say("Waiting for the vm to stop...") - err = waitUntilVmStopped(oapiconn, vm.VmId) + err = waitUntilOscVmStopped(oscconn, vm.VmId) if err != nil { err := fmt.Errorf("Error waiting for vm to stop: %s", err)