packer-cn/builder/azure/arm/step_publish_to_shared_image_gallery.go
Paul Meyer 89f3aa0bd6
[builder/azure-arm] Use VM/build location for image location (#9068)
* [builder/azure-arm] Use VM/build location for image locationThe builder was using the location of the containing resource group asthe image location, but the API call can only create images in the samelocation as the source VM that is being captured.
2020-04-17 05:43:03 -04:00

159 lines
6.6 KiB
Go

package arm
import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute"
"github.com/Azure/go-autorest/autorest/date"
"github.com/hashicorp/packer/builder/azure/common/constants"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type StepPublishToSharedImageGallery struct {
client *AzureClient
publish func(ctx context.Context, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion string, miSigReplicationRegions []string, miSGImageVersionEndOfLifeDate string, miSGImageVersionExcludeFromLatest bool, miSigReplicaCount int32, location string, tags map[string]*string) (string, error)
say func(message string)
error func(e error)
toSIG func() bool
}
func NewStepPublishToSharedImageGallery(client *AzureClient, ui packer.Ui, config *Config) *StepPublishToSharedImageGallery {
var step = &StepPublishToSharedImageGallery{
client: client,
say: func(message string) {
ui.Say(message)
},
error: func(e error) {
ui.Error(e.Error())
},
toSIG: func() bool {
return config.isManagedImage() && config.SharedGalleryDestination.SigDestinationGalleryName != ""
},
}
step.publish = step.publishToSig
return step
}
func (s *StepPublishToSharedImageGallery) publishToSig(ctx context.Context, mdiID string, miSigPubRg string, miSIGalleryName string, miSGImageName string, miSGImageVersion string, miSigReplicationRegions []string, miSGImageVersionEndOfLifeDate string, miSGImageVersionExcludeFromLatest bool, miSigReplicaCount int32, location string, tags map[string]*string) (string, error) {
replicationRegions := make([]compute.TargetRegion, len(miSigReplicationRegions))
for i, v := range miSigReplicationRegions {
regionName := v
replicationRegions[i] = compute.TargetRegion{Name: &regionName}
}
var endOfLifeDate *date.Time
if miSGImageVersionEndOfLifeDate != "" {
parseDate, err := date.ParseTime("2006-01-02T15:04:05.99Z", miSGImageVersionEndOfLifeDate)
if err != nil {
s.say(fmt.Sprintf("Error parsing date from shared_gallery_image_version_end_of_life_date: %s", err))
return "", err
}
endOfLifeDate = &date.Time{Time: parseDate}
} else {
endOfLifeDate = (*date.Time)(nil)
}
galleryImageVersion := compute.GalleryImageVersion{
Location: &location,
Tags: tags,
GalleryImageVersionProperties: &compute.GalleryImageVersionProperties{
PublishingProfile: &compute.GalleryImageVersionPublishingProfile{
Source: &compute.GalleryArtifactSource{
ManagedImage: &compute.ManagedArtifact{
ID: &mdiID,
},
},
TargetRegions: &replicationRegions,
EndOfLifeDate: endOfLifeDate,
ExcludeFromLatest: &miSGImageVersionExcludeFromLatest,
ReplicaCount: &miSigReplicaCount,
},
},
}
f, err := s.client.GalleryImageVersionsClient.CreateOrUpdate(ctx, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion, galleryImageVersion)
if err != nil {
s.say(s.client.LastError.Error())
return "", err
}
err = f.WaitForCompletionRef(ctx, s.client.GalleryImageVersionsClient.Client)
if err != nil {
s.say(s.client.LastError.Error())
return "", err
}
createdSGImageVersion, err := f.Result(s.client.GalleryImageVersionsClient)
if err != nil {
s.say(s.client.LastError.Error())
return "", err
}
s.say(fmt.Sprintf(" -> Shared Gallery Image Version ID : '%s'", *(createdSGImageVersion.ID)))
return *(createdSGImageVersion.ID), nil
}
func (s *StepPublishToSharedImageGallery) Run(ctx context.Context, stateBag multistep.StateBag) multistep.StepAction {
if !s.toSIG() {
return multistep.ActionContinue
}
s.say("Publishing to Shared Image Gallery ...")
location := stateBag.Get(constants.ArmLocation).(string)
miSigPubRg := stateBag.Get(constants.ArmManagedImageSigPublishResourceGroup).(string)
miSIGalleryName := stateBag.Get(constants.ArmManagedImageSharedGalleryName).(string)
miSGImageName := stateBag.Get(constants.ArmManagedImageSharedGalleryImageName).(string)
miSGImageVersion := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersion).(string)
miSigReplicationRegions := stateBag.Get(constants.ArmManagedImageSharedGalleryReplicationRegions).([]string)
tags := stateBag.Get(constants.ArmTags).(map[string]*string)
targetManagedImageResourceGroupName := stateBag.Get(constants.ArmManagedImageResourceGroupName).(string)
targetManagedImageName := stateBag.Get(constants.ArmManagedImageName).(string)
managedImageSubscription := stateBag.Get(constants.ArmManagedImageSubscription).(string)
mdiID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/images/%s", managedImageSubscription, targetManagedImageResourceGroupName, targetManagedImageName)
miSGImageVersionEndOfLifeDate, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionEndOfLifeDate).(string)
miSGImageVersionExcludeFromLatest, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionExcludeFromLatest).(bool)
miSigReplicaCount, _ := stateBag.Get(constants.ArmManagedImageSharedGalleryImageVersionReplicaCount).(int32)
// Replica count must be between 1 and 10 inclusive.
if miSigReplicaCount <= 0 {
miSigReplicaCount = constants.SharedImageGalleryImageVersionDefaultMinReplicaCount
} else if miSigReplicaCount > 10 {
miSigReplicaCount = constants.SharedImageGalleryImageVersionDefaultMaxReplicaCount
}
s.say(fmt.Sprintf(" -> MDI ID used for SIG publish : '%s'", mdiID))
s.say(fmt.Sprintf(" -> SIG publish resource group : '%s'", miSigPubRg))
s.say(fmt.Sprintf(" -> SIG gallery name : '%s'", miSIGalleryName))
s.say(fmt.Sprintf(" -> SIG image name : '%s'", miSGImageName))
s.say(fmt.Sprintf(" -> SIG image version : '%s'", miSGImageVersion))
s.say(fmt.Sprintf(" -> SIG replication regions : '%v'", miSigReplicationRegions))
s.say(fmt.Sprintf(" -> SIG image version endoflife date : '%s'", miSGImageVersionEndOfLifeDate))
s.say(fmt.Sprintf(" -> SIG image version exclude from latest : '%t'", miSGImageVersionExcludeFromLatest))
s.say(fmt.Sprintf(" -> SIG replica count [1, 10] : '%d'", miSigReplicaCount))
createdGalleryImageVersionID, err := s.publish(ctx, mdiID, miSigPubRg, miSIGalleryName, miSGImageName, miSGImageVersion, miSigReplicationRegions, miSGImageVersionEndOfLifeDate, miSGImageVersionExcludeFromLatest, miSigReplicaCount, location, tags)
if err != nil {
stateBag.Put(constants.Error, err)
s.error(err)
return multistep.ActionHalt
}
stateBag.Put(constants.ArmManagedImageSharedGalleryId, createdGalleryImageVersionID)
return multistep.ActionContinue
}
func (*StepPublishToSharedImageGallery) Cleanup(multistep.StateBag) {
}