2020-03-25 17:55:37 -04:00
|
|
|
package chroot
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
|
2020-04-23 05:03:17 -04:00
|
|
|
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
|
2020-03-25 17:55:37 -04:00
|
|
|
"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"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ multistep.Step = &StepVerifySharedImageDestination{}
|
|
|
|
|
|
|
|
// StepVerifySharedImageDestination verifies that the shared image location matches the Location field in the step.
|
|
|
|
// Also verifies that the OS Type is Linux.
|
|
|
|
type StepVerifySharedImageDestination struct {
|
|
|
|
Image SharedImageGalleryDestination
|
|
|
|
Location string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run retrieves the image metadata from Azure and compares the location to Location. Verifies the OS Type.
|
|
|
|
func (s *StepVerifySharedImageDestination) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
|
|
|
azcli := state.Get("azureclient").(client.AzureClientSet)
|
|
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
|
|
|
|
errorMessage := func(message string, parameters ...interface{}) multistep.StepAction {
|
|
|
|
err := fmt.Errorf(message, parameters...)
|
|
|
|
log.Printf("StepVerifySharedImageDestination.Run: error: %+v", err)
|
|
|
|
state.Put("error", err)
|
|
|
|
ui.Error(err.Error())
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
2020-04-08 17:05:26 -04:00
|
|
|
imageURI := fmt.Sprintf("/subscriptions/%s/resourcegroup/%s/providers/Microsoft.Compute/galleries/%s/images/%s",
|
|
|
|
azcli.SubscriptionID(),
|
2020-03-25 17:55:37 -04:00
|
|
|
s.Image.ResourceGroup,
|
|
|
|
s.Image.GalleryName,
|
|
|
|
s.Image.ImageName,
|
|
|
|
)
|
|
|
|
|
|
|
|
ui.Say(fmt.Sprintf("Validating that shared image %s exists",
|
|
|
|
imageURI))
|
|
|
|
|
|
|
|
image, err := azcli.GalleryImagesClient().Get(ctx,
|
|
|
|
s.Image.ResourceGroup,
|
|
|
|
s.Image.GalleryName,
|
|
|
|
s.Image.ImageName)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return errorMessage("Error retrieving shared image %q: %+v ", imageURI, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if image.ID == nil || *image.ID == "" {
|
|
|
|
return errorMessage("Error retrieving shared image %q: ID field in response is empty", imageURI)
|
|
|
|
}
|
|
|
|
if image.GalleryImageProperties == nil {
|
|
|
|
return errorMessage("Could not retrieve shared image properties for image %q.", to.String(image.ID))
|
|
|
|
}
|
|
|
|
|
|
|
|
location := to.String(image.Location)
|
|
|
|
|
|
|
|
log.Printf("StepVerifySharedImageDestination:Run: Image %q, Location: %q, HvGen: %q, osState: %q",
|
|
|
|
to.String(image.ID),
|
|
|
|
location,
|
|
|
|
image.GalleryImageProperties.HyperVGeneration,
|
|
|
|
image.GalleryImageProperties.OsState)
|
|
|
|
|
|
|
|
if !strings.EqualFold(location, s.Location) {
|
|
|
|
return errorMessage("Destination shared image resource %q is in a different location (%q) than this VM (%q). "+
|
|
|
|
"Packer does not know how to handle that.",
|
|
|
|
to.String(image.ID),
|
|
|
|
location,
|
|
|
|
s.Location)
|
|
|
|
}
|
|
|
|
|
|
|
|
if image.GalleryImageProperties.OsType != compute.Linux {
|
|
|
|
return errorMessage("The shared image (%q) is not a Linux image (found %q). Currently only Linux images are supported.",
|
|
|
|
to.String(image.ID),
|
|
|
|
image.GalleryImageProperties.OsType)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Say(fmt.Sprintf("Found image %s in location %s",
|
|
|
|
to.String(image.ID),
|
|
|
|
to.String(image.Location)))
|
|
|
|
|
|
|
|
versions, err := azcli.GalleryImageVersionsClient().ListByGalleryImageComplete(ctx,
|
|
|
|
s.Image.ResourceGroup,
|
|
|
|
s.Image.GalleryName,
|
|
|
|
s.Image.ImageName)
|
|
|
|
|
2020-04-23 04:53:13 -04:00
|
|
|
if err != nil {
|
|
|
|
return errorMessage("Could not ListByGalleryImageComplete group:%v gallery:%v image:%v",
|
|
|
|
s.Image.ResourceGroup, s.Image.GalleryName, s.Image.ImageName)
|
|
|
|
}
|
|
|
|
|
2020-03-25 17:55:37 -04:00
|
|
|
for versions.NotDone() {
|
|
|
|
version := versions.Value()
|
|
|
|
|
|
|
|
if version.Name == nil {
|
|
|
|
return errorMessage("Could not retrieve versions for image %q: unexpected nil name", to.String(image.ID))
|
|
|
|
}
|
|
|
|
if *version.Name == s.Image.ImageVersion {
|
2020-04-09 16:55:10 -04:00
|
|
|
return errorMessage("Shared image version %q already exists for image %q.", s.Image.ImageVersion, to.String(image.ID))
|
2020-03-25 17:55:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
err := versions.NextWithContext(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return errorMessage("Could not retrieve versions for image %q: %+v", to.String(image.ID), err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return multistep.ActionContinue
|
|
|
|
}
|
|
|
|
|
|
|
|
func (*StepVerifySharedImageDestination) Cleanup(multistep.StateBag) {}
|