func (s *StepCreateImage) Cleanup(state multistep.StateBag) {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)

	var err error
	var res int

	if res = state.Get(constants.VmExists).(int); res == 1 { //VM was not removed at image creation step
		return
	}

	// Since VM was successfully removed - remove it's media as well

	if res = state.Get(constants.DiskExists).(int); res == 1 {
		ui.Message("Removing Temporary Azure Disk...")
		errorMsg := "Error Removing Temporary Azure Disk: %s"

		diskName, ok := state.Get(constants.HardDiskName).(string)
		if ok {
			if len(diskName) == 0 {
				err := fmt.Errorf(errorMsg, err)
				ui.Error(err.Error())
				return
			}

			if err := retry.ExecuteOperation(func() error {
				return vmdisk.NewClient(client).DeleteDisk(diskName, true)
			}, retry.ConstantBackoffRule("busy", func(err management.AzureError) bool {
				return strings.Contains(err.Message, "is currently performing an operation on deployment") ||
					strings.Contains(err.Message, "is currently in use by virtual machine")
			}, 30*time.Second, 10)); err != nil {
				err := fmt.Errorf(errorMsg, err)
				ui.Error(err.Error())
				return
			}

			state.Put(constants.DiskExists, 0)
		}
	}
}
예제 #2
0
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact /*keep*/, bool, error) {
	ui.Say("Validating artifact")
	if artifact.BuilderId() != azure.BuilderId {
		return nil, false, fmt.Errorf(
			"Unknown artifact type: %s\nCan only import from Azure builder artifacts (%s).",
			artifact.BuilderId(), azure.BuilderId)
	}

	publishSettingsPath, ok := artifact.State("publishSettingsPath").(string)
	if !ok || publishSettingsPath == "" {
		return nil, false, fmt.Errorf(stateError, "publishSettingsPath")
	}
	subscriptionID, ok := artifact.State("subscriptionID").(string)
	if !ok || subscriptionID == "" {
		return nil, false, fmt.Errorf(stateError, "subscriptionID")
	}

	name := artifact.Id()

	ui.Message("Creating Azure Service Management client...")
	client, err := management.ClientFromPublishSettingsFile(publishSettingsPath, subscriptionID)
	if err != nil {
		return nil, false, fmt.Errorf("Error creating new Azure client: %v", err)
	}
	client = azure.GetLoggedClient(client)
	vmic := virtualmachineimage.NewClient(client)

	ui.Message("Retrieving VM image...")
	var image virtualmachineimage.VMImage
	if err = retry.ExecuteOperation(func() error {
		imageList, err := vmic.ListVirtualMachineImages(
			virtualmachineimage.ListParameters{
				Category: virtualmachineimage.CategoryUser,
			})
		if err != nil {
			return err
		}

		for _, i := range imageList.VMImages {
			if i.Name == name {
				image = i
				break
			}
		}
		return nil
	}); err != nil {
		log.Printf("VM image client returned error: %s", err)
		return nil, false, err
	}
	if image.Name != name {
		return nil, false, fmt.Errorf("Could not find image: %s", name)
	}

	ui.Message(fmt.Sprintf("Deleting VM image (keeping VHDs) %s: %s...", image.Name, image.Label))
	err = retry.ExecuteOperation(func() error { return vmic.DeleteVirtualMachineImage(image.Name, false) })
	if err != nil {
		log.Printf("Error deleting VM image: %s", err)
		return nil, false, err
	}

	blobs := VMBlobListArtifact{
		OSDisk:    image.OSDiskConfiguration.MediaLink,
		DataDisks: make([]string, len(image.DataDiskConfigurations))}

	for i, ddc := range image.DataDiskConfigurations {
		blobs.DataDisks[i] = ddc.MediaLink
	}

	return blobs, false, nil
}