package chroot import ( "context" "fmt" "log" "sort" "time" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute" "github.com/Azure/go-autorest/autorest/to" "github.com/hashicorp/packer/builder/azure/common/client" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) type StepCreateSharedImageVersion struct { Destination SharedImageGalleryDestination OSDiskCacheType string DataDiskCacheType string Location string } func (s *StepCreateSharedImageVersion) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { azcli := state.Get("azureclient").(client.AzureClientSet) ui := state.Get("ui").(packer.Ui) snapshotset := state.Get(stateBagKey_Snapshotset).(Diskset) ui.Say(fmt.Sprintf("Creating image version %s\n using %q for os disk.", s.Destination.ResourceID(azcli.SubscriptionID()), snapshotset.OS())) var targetRegions []compute.TargetRegion // transform target regions to API objects for _, tr := range s.Destination.TargetRegions { apiObject := compute.TargetRegion{ Name: to.StringPtr(tr.Name), RegionalReplicaCount: to.Int32Ptr(tr.ReplicaCount), StorageAccountType: compute.StorageAccountType(tr.StorageAccountType), } targetRegions = append(targetRegions, apiObject) } imageVersion := compute.GalleryImageVersion{ Location: to.StringPtr(s.Location), GalleryImageVersionProperties: &compute.GalleryImageVersionProperties{ StorageProfile: &compute.GalleryImageVersionStorageProfile{ OsDiskImage: &compute.GalleryOSDiskImage{ Source: &compute.GalleryArtifactVersionSource{ID: to.StringPtr(snapshotset.OS().String())}, HostCaching: compute.HostCaching(s.OSDiskCacheType), }, }, PublishingProfile: &compute.GalleryImageVersionPublishingProfile{ TargetRegions: &targetRegions, ExcludeFromLatest: to.BoolPtr(s.Destination.ExcludeFromLatest), }, }, } var datadisks []compute.GalleryDataDiskImage for lun, resource := range snapshotset { if lun != -1 { ui.Say(fmt.Sprintf(" using %q for data disk (lun %d).", resource, lun)) datadisks = append(datadisks, compute.GalleryDataDiskImage{ Lun: to.Int32Ptr(lun), Source: &compute.GalleryArtifactVersionSource{ID: to.StringPtr(resource.String())}, HostCaching: compute.HostCaching(s.DataDiskCacheType), }) } } if datadisks != nil { // sort by lun sort.Slice(datadisks, func(i, j int) bool { return *datadisks[i].Lun < *datadisks[j].Lun }) imageVersion.GalleryImageVersionProperties.StorageProfile.DataDiskImages = &datadisks } f, err := azcli.GalleryImageVersionsClient().CreateOrUpdate( ctx, s.Destination.ResourceGroup, s.Destination.GalleryName, s.Destination.ImageName, s.Destination.ImageVersion, imageVersion) if err == nil { log.Println("Shared image version creation in process...") pollClient := azcli.PollClient() pollClient.PollingDelay = 10 * time.Second ctx, cancel := context.WithTimeout(ctx, time.Hour*12) defer cancel() err = f.WaitForCompletionRef(ctx, pollClient) } if err != nil { log.Printf("StepCreateSharedImageVersion.Run: error: %+v", err) err := fmt.Errorf( "error creating shared image version '%s': %v", s.Destination.ResourceID(azcli.SubscriptionID()), err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } log.Printf("Image creation complete: %s", f.Status()) return multistep.ActionContinue } func (*StepCreateSharedImageVersion) Cleanup(multistep.StateBag) {}