Merge pull request #9 from marinsalinas/bsusurrogate

Bsusurrogate sdk migration
This commit is contained in:
Marin Salinas
2020-09-30 10:35:26 -05:00
committed by GitHub
6 changed files with 104 additions and 45 deletions
+9 -5
View File
@@ -117,18 +117,21 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
oapiconn := oapi.NewClient(clientConfig, skipClient)
oscConn := b.config.NewOSCClient()
// Setup the state bag and initial state for the steps
state := new(multistep.BasicStateBag)
state.Put("config", &b.config)
state.Put("oapi", oapiconn)
state.Put("clientConfig", clientConfig)
state.Put("osc", oscConn)
state.Put("accessConfig", &b.config.AccessConfig)
state.Put("hook", hook)
state.Put("ui", ui)
//VMStep
omiDevices := b.config.BuildOMIDevices()
launchDevices := b.config.BuildLaunchDevices()
omiDevices := b.config.BuildOscOMIDevices()
launchOSCDevices := b.config.BuildOSCLaunchDevices()
steps := []multistep.Step{
&osccommon.StepPreValidate{
@@ -207,7 +210,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
DisableStopVm: b.config.DisableStopVm,
},
&StepSnapshotVolumes{
LaunchDevices: launchDevices,
LaunchDevices: launchOSCDevices,
},
&osccommon.StepDeregisterOMI{
AccessConfig: &b.config.AccessConfig,
@@ -219,7 +222,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&StepRegisterOMI{
RootDevice: b.config.RootDevice,
OMIDevices: omiDevices,
LaunchDevices: launchDevices,
LaunchDevices: launchOSCDevices,
RawRegion: b.config.RawRegion,
},
&osccommon.StepUpdateOMIAttributes{
AccountIds: b.config.OMIAccountIDs,
+1 -1
View File
@@ -24,7 +24,7 @@ const testBuilderAccBasic = `
"type": "test",
"region": "eu-west-2",
"vm_type": "t2.micro",
"source_omi": "ami-65efcc11",
"source_omi": "ami-abe953fa",
"ssh_username": "outscale",
"omi_name": "packer-test {{timestamp}}",
"omi_virtualization_type": "hvm",
+36 -24
View File
@@ -4,23 +4,27 @@ import (
"context"
"fmt"
"github.com/antihax/optional"
osccommon "github.com/hashicorp/packer/builder/osc/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"
)
// StepRegisterOMI creates the OMI.
type StepRegisterOMI struct {
RootDevice RootBlockDevice
OMIDevices []oapi.BlockDeviceMappingImage
LaunchDevices []oapi.BlockDeviceMappingVmCreation
image *oapi.Image
OMIDevices []osc.BlockDeviceMappingImage
LaunchDevices []osc.BlockDeviceMappingVmCreation
image *osc.Image
RawRegion string
}
func (s *StepRegisterOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
oapiconn := state.Get("oapi").(*oapi.Client)
oscconn := state.Get("osc").(*osc.APIClient)
snapshotIds := state.Get("snapshot_ids").(map[string]string)
ui := state.Get("ui").(packer.Ui)
@@ -28,14 +32,16 @@ func (s *StepRegisterOMI) Run(ctx context.Context, state multistep.StateBag) mul
blockDevices := s.combineDevices(snapshotIds)
registerOpts := oapi.CreateImageRequest{
registerOpts := osc.CreateImageRequest{
ImageName: config.OMIName,
Architecture: "x86_64",
RootDeviceName: s.RootDevice.DeviceName,
BlockDeviceMappings: blockDevices,
}
registerResp, err := oapiconn.POST_CreateImage(registerOpts)
registerResp, _, err := oscconn.ImageApi.CreateImage(context.Background(), &osc.CreateImageOpts{
CreateImageRequest: optional.NewInterface(registerOpts),
})
if err != nil {
state.Put("error", fmt.Errorf("Error registering OMI: %s", err))
ui.Error(state.Get("error").(error).Error())
@@ -43,24 +49,26 @@ func (s *StepRegisterOMI) Run(ctx context.Context, state multistep.StateBag) mul
}
// Set the OMI ID in the state
ui.Say(fmt.Sprintf("OMI: %s", registerResp.OK.Image.ImageId))
ui.Say(fmt.Sprintf("OMI: %s", registerResp.Image.ImageId))
omis := make(map[string]string)
omis[oapiconn.GetConfig().Region] = registerResp.OK.Image.ImageId
omis[oapiconn.GetConfig().Region] = registerResp.Image.ImageId
state.Put("omis", omis)
// Wait for the image to become ready
ui.Say("Waiting for OMI to become ready...")
if err := osccommon.WaitUntilImageAvailable(oapiconn, registerResp.OK.Image.ImageId); err != nil {
if err := osccommon.WaitUntilOscImageAvailable(oscconn, registerResp.Image.ImageId); err != nil {
err := fmt.Errorf("Error waiting for OMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
imagesResp, err := oapiconn.POST_ReadImages(oapi.ReadImagesRequest{
Filters: oapi.FiltersImage{
ImageIds: []string{registerResp.OK.Image.ImageId},
},
imagesResp, _, err := oscconn.ImageApi.ReadImages(context.Background(), &osc.ReadImagesOpts{
ReadImagesRequest: optional.NewInterface(osc.ReadImagesRequest{
Filters: osc.FiltersImage{
ImageIds: []string{registerResp.Image.ImageId},
},
}),
})
if err != nil {
@@ -69,12 +77,12 @@ func (s *StepRegisterOMI) Run(ctx context.Context, state multistep.StateBag) mul
ui.Error(err.Error())
return multistep.ActionHalt
}
s.image = &imagesResp.OK.Images[0]
s.image = &imagesResp.Images[0]
snapshots := make(map[string][]string)
for _, blockDeviceMapping := range imagesResp.OK.Images[0].BlockDeviceMappings {
for _, blockDeviceMapping := range imagesResp.Images[0].BlockDeviceMappings {
if blockDeviceMapping.Bsu.SnapshotId != "" {
snapshots[oapiconn.GetConfig().Region] = append(snapshots[oapiconn.GetConfig().Region], blockDeviceMapping.Bsu.SnapshotId)
snapshots[s.RawRegion] = append(snapshots[s.RawRegion], blockDeviceMapping.Bsu.SnapshotId)
}
}
state.Put("snapshots", snapshots)
@@ -93,19 +101,23 @@ func (s *StepRegisterOMI) Cleanup(state multistep.StateBag) {
return
}
oapiconn := state.Get("oapi").(*oapi.Client)
oscconn := state.Get("osc").(*osc.APIClient)
ui := state.Get("ui").(packer.Ui)
ui.Say("Deregistering the OMI because cancellation or error...")
deregisterOpts := oapi.DeleteImageRequest{ImageId: s.image.ImageId}
if _, err := oapiconn.POST_DeleteImage(deregisterOpts); err != nil {
deregisterOpts := osc.DeleteImageRequest{ImageId: s.image.ImageId}
_, _, err := oscconn.ImageApi.DeleteImage(context.Background(), &osc.DeleteImageOpts{
DeleteImageRequest: optional.NewInterface(deregisterOpts),
})
if err != nil {
ui.Error(fmt.Sprintf("Error deregistering OMI, may still be around: %s", err))
return
}
}
func (s *StepRegisterOMI) combineDevices(snapshotIds map[string]string) []oapi.BlockDeviceMappingImage {
devices := map[string]oapi.BlockDeviceMappingImage{}
func (s *StepRegisterOMI) combineDevices(snapshotIds map[string]string) []osc.BlockDeviceMappingImage {
devices := map[string]osc.BlockDeviceMappingImage{}
for _, device := range s.OMIDevices {
devices[device.DeviceName] = device
@@ -125,18 +137,18 @@ func (s *StepRegisterOMI) combineDevices(snapshotIds map[string]string) []oapi.B
devices[device.DeviceName] = copyToDeviceMappingImage(device)
}
blockDevices := []oapi.BlockDeviceMappingImage{}
blockDevices := []osc.BlockDeviceMappingImage{}
for _, device := range devices {
blockDevices = append(blockDevices, device)
}
return blockDevices
}
func copyToDeviceMappingImage(device oapi.BlockDeviceMappingVmCreation) oapi.BlockDeviceMappingImage {
deviceImage := oapi.BlockDeviceMappingImage{
func copyToDeviceMappingImage(device osc.BlockDeviceMappingVmCreation) osc.BlockDeviceMappingImage {
deviceImage := osc.BlockDeviceMappingImage{
DeviceName: device.DeviceName,
VirtualDeviceName: device.VirtualDeviceName,
Bsu: oapi.BsuToCreate{
Bsu: osc.BsuToCreate{
DeleteOnVmDeletion: device.Bsu.DeleteOnVmDeletion,
Iops: device.Bsu.Iops,
SnapshotId: device.Bsu.SnapshotId,
@@ -6,11 +6,12 @@ import (
"sync"
"time"
"github.com/antihax/optional"
multierror "github.com/hashicorp/go-multierror"
osccommon "github.com/hashicorp/packer/builder/osc/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"
)
// StepSnapshotVolumes creates snapshots of the created volumes.
@@ -18,14 +19,14 @@ import (
// Produces:
// snapshot_ids map[string]string - IDs of the created snapshots
type StepSnapshotVolumes struct {
LaunchDevices []oapi.BlockDeviceMappingVmCreation
LaunchDevices []osc.BlockDeviceMappingVmCreation
snapshotIds map[string]string
}
func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName string, state multistep.StateBag) error {
oapiconn := state.Get("oapi").(*oapi.Client)
oscconn := state.Get("osc").(*osc.APIClient)
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(oapi.Vm)
vm := state.Get("vm").(osc.Vm)
var volumeId string
for _, volume := range vm.BlockDeviceMappings {
@@ -40,19 +41,21 @@ func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName str
ui.Say(fmt.Sprintf("Creating snapshot of EBS Volume %s...", volumeId))
description := fmt.Sprintf("Packer: %s", time.Now().String())
createSnapResp, err := oapiconn.POST_CreateSnapshot(oapi.CreateSnapshotRequest{
VolumeId: volumeId,
Description: description,
createSnapResp, _, err := oscconn.SnapshotApi.CreateSnapshot(context.Background(), &osc.CreateSnapshotOpts{
CreateSnapshotRequest: optional.NewInterface(osc.CreateSnapshotRequest{
VolumeId: volumeId,
Description: description,
}),
})
if err != nil {
return err
}
// Set the snapshot ID so we can delete it later
s.snapshotIds[deviceName] = createSnapResp.OK.Snapshot.SnapshotId
s.snapshotIds[deviceName] = createSnapResp.Snapshot.SnapshotId
// Wait for snapshot to be created
err = osccommon.WaitUntilSnapshotCompleted(oapiconn, createSnapResp.OK.Snapshot.SnapshotId)
err = osccommon.WaitUntilOscSnapshotCompleted(oscconn, createSnapResp.Snapshot.SnapshotId)
return err
}
@@ -65,7 +68,7 @@ func (s *StepSnapshotVolumes) Run(ctx context.Context, state multistep.StateBag)
var errs *multierror.Error
for _, device := range s.LaunchDevices {
wg.Add(1)
go func(device oapi.BlockDeviceMappingVmCreation) {
go func(device osc.BlockDeviceMappingVmCreation) {
defer wg.Done()
if err := s.snapshotVolume(ctx, device.DeviceName, state); err != nil {
errs = multierror.Append(errs, err)
@@ -94,11 +97,13 @@ func (s *StepSnapshotVolumes) Cleanup(state multistep.StateBag) {
_, halted := state.GetOk(multistep.StateHalted)
if cancelled || halted {
oapiconn := state.Get("oapi").(*oapi.Client)
oscconn := state.Get("osc").(*osc.APIClient)
ui := state.Get("ui").(packer.Ui)
ui.Say("Removing snapshots since we cancelled or halted...")
for _, snapshotId := range s.snapshotIds {
_, err := oapiconn.POST_DeleteSnapshot(oapi.DeleteSnapshotRequest{SnapshotId: snapshotId})
for _, snapshotID := range s.snapshotIds {
_, _, err := oscconn.SnapshotApi.DeleteSnapshot(context.Background(), &osc.DeleteSnapshotOpts{
DeleteSnapshotRequest: optional.NewInterface(osc.DeleteSnapshotRequest{SnapshotId: snapshotID}),
})
if err != nil {
ui.Error(fmt.Sprintf("Error: %s", err))
}
+2 -1
View File
@@ -103,7 +103,8 @@ func (c *AccessConfig) GetRegion() string {
func (c *AccessConfig) NewOSCClientByRegion(region string) *osc.APIClient {
skipClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
TLSClientConfig: &tls.Config{InsecureSkipVerify: c.InsecureSkipTLSVerify},
Proxy: http.ProxyFromEnvironment,
},
}
+38 -1
View File
@@ -64,6 +64,12 @@ func WaitUntilSnapshotCompleted(conn *oapi.Client, id string) error {
return <-errCh
}
func WaitUntilOscSnapshotCompleted(conn *osc.APIClient, id string) error {
errCh := make(chan error, 1)
go waitForState(errCh, "completed", waitUntilOscSnapshotStateFunc(conn, id))
return <-errCh
}
func WaitUntilImageAvailable(conn *oapi.Client, imageID string) error {
errCh := make(chan error, 1)
go waitForState(errCh, "available", waitUntilImageStateFunc(conn, imageID))
@@ -260,6 +266,36 @@ func waitUntilSnapshotStateFunc(conn *oapi.Client, id string) stateRefreshFunc {
}
}
func waitUntilOscSnapshotStateFunc(conn *osc.APIClient, id string) stateRefreshFunc {
return func() (string, error) {
log.Printf("[Debug] Check if Snapshot with id %s exists", id)
resp, _, err := conn.SnapshotApi.ReadSnapshots(context.Background(), &osc.ReadSnapshotsOpts{
ReadSnapshotsRequest: optional.NewInterface(osc.ReadSnapshotsRequest{
Filters: osc.FiltersSnapshot{
SnapshotIds: []string{id},
},
}),
})
log.Printf("[Debug] Read Response %+v", resp)
if err != nil {
return "", err
}
//TODO: check if needed
// if resp.OK == nil {
// return "", fmt.Errorf("Vm with ID %s. Not Found", id)
// }
if len(resp.Snapshots) == 0 {
return "pending", nil
}
return resp.Snapshots[0].State, nil
}
}
func waitUntilImageStateFunc(conn *oapi.Client, id string) stateRefreshFunc {
return func() (string, error) {
log.Printf("[Debug] Check if Image with id %s exists", id)
@@ -308,7 +344,8 @@ func waitUntilOscImageStateFunc(conn *osc.APIClient, id string) stateRefreshFunc
return "", err
}
// if resp.Images[] == "" {
//TODO: check if needed
// if resp.OK == nil {
// return "", fmt.Errorf("Vm with ID %s. Not Found", id)
// }