func GetVMImage(
	t *testing.T,
	client management.Client,
	filter func(vmimage.VMImage) bool) vmimage.VMImage {
	t.Log("Selecting VM image")
	allimages, err := vmimage.NewClient(client).ListVirtualMachineImages(vmimage.ListParameters{})
	if err != nil {
		t.Fatal(err)
	}
	filtered := []vmimage.VMImage{}
	for _, im := range allimages.VMImages {
		if filter(im) {
			filtered = append(filtered, im)
		}
	}
	if len(filtered) == 0 {
		t.Fatal("Filter too restrictive, no images left?")
	}

	image := filtered[0]
	for _, im := range filtered {
		if im.PublishedDate > image.PublishedDate {
			image = im
		}
	}

	t.Logf("Selecting image '%s'", image.Name)
	return image
}
func (s *StepCreateImage) Run(state multistep.StateBag) multistep.StepAction {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)

	errorMsg := "Error Creating Azure Image: %s"

	ui.Say("Creating Azure Image. If Successful, This Will Remove the Temporary VM...")

	description := "packer made image"
	imageFamily := "PackerMade"

	if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
		return vmi.NewClient(client).Capture(s.TmpServiceName, s.TmpVmName, s.TmpVmName,
			s.UserImageName, s.UserImageLabel, vmi.OSStateGeneralized, vmi.CaptureParameters{
				Description:       description,
				ImageFamily:       imageFamily,
				RecommendedVMSize: s.RecommendedVMSize,
			})
	}); err != nil {
		err := fmt.Errorf(errorMsg, err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	// CatpureVMImage removes the VM
	state.Put(constants.ImageCreated, 1)
	state.Put(constants.VmExists, 0)

	return multistep.ActionContinue
}
Example #3
0
// NewClientFromSettingsFile returns a new Azure management
// client created using a publish settings file.
func (c *Config) NewClientFromSettingsFile() (*Client, error) {
	if _, err := os.Stat(c.SettingsFile); os.IsNotExist(err) {
		return nil, fmt.Errorf("Publish Settings file %q does not exist!", c.SettingsFile)
	}

	mc, err := management.ClientFromPublishSettingsFile(c.SettingsFile, c.SubscriptionID)
	if err != nil {
		return nil, nil
	}

	return &Client{
		mgmtClient:           mc,
		affinityGroupClient:  affinitygroup.NewClient(mc),
		hostedServiceClient:  hostedservice.NewClient(mc),
		secGroupClient:       networksecuritygroup.NewClient(mc),
		osImageClient:        osimage.NewClient(mc),
		sqlClient:            sql.NewClient(mc),
		storageServiceClient: storageservice.NewClient(mc),
		vmClient:             virtualmachine.NewClient(mc),
		vmDiskClient:         virtualmachinedisk.NewClient(mc),
		vmImageClient:        virtualmachineimage.NewClient(mc),
		vnetClient:           virtualnetwork.NewClient(mc),
		mutex:                &sync.Mutex{},
	}, nil
}
func TestVMImageList(t *testing.T) {
	client := testutils.GetTestClient(t)
	vmic := vmimage.NewClient(client)
	il, _ := vmic.ListVirtualMachineImages(vmimage.ListParameters{})
	for _, im := range il.VMImages {
		t.Logf("%s -%s", im.Name, im.Description)
	}
}
Example #5
0
func (b *Builder) validateAzureOptions(ui packer.Ui, state *multistep.BasicStateBag) error {

	var err error

	// Check Storage account (& container)
	ui.Message("Checking Storage Account...")
	availabilityResponse, err := storageservice.NewClient(b.client).CheckStorageAccountNameAvailability(b.config.StorageAccount)
	if err != nil {
		return err
	}

	if availabilityResponse.Result {
		return fmt.Errorf("Can't Find Storage Account '%s'", b.config.StorageAccount)
	}

	// Check image exists
	imageList, err := osimage.NewClient(b.client).ListOSImages()
	if err != nil {
		log.Printf("OS image client returned error: %s", err)
		return err
	}

	if osImage, found := FindOSImage(imageList.OSImages, b.config.OSImageLabel, b.config.Location); found {
		state.Put(constants.OSImageName, osImage.Name)
		state.Put(constants.IsOSImage, true)
		return nil
	} else {
		imageList, err := vmimage.NewClient(b.client).ListVirtualMachineImages()
		if err != nil {
			log.Printf("VM image client returned error: %s", err)
			return err
		}

		if vmImage, found := FindVmImage(imageList.VMImages, "", b.config.OSImageLabel, b.config.Location); found {
			state.Put(constants.OSImageName, vmImage.Name)
			state.Put(constants.IsOSImage, false)
			return nil
		} else {
			return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", b.config.OSImageLabel, b.config.Location)
		}
	}
}
Example #6
0
func (c *Config) NewClientFromSettingsData() (*Client, error) {
	mc, err := management.ClientFromPublishSettingsData(c.Settings, c.SubscriptionID)
	if err != nil {
		return nil, nil
	}

	return &Client{
		mgmtClient:           mc,
		affinityGroupClient:  affinitygroup.NewClient(mc),
		hostedServiceClient:  hostedservice.NewClient(mc),
		secGroupClient:       networksecuritygroup.NewClient(mc),
		osImageClient:        osimage.NewClient(mc),
		sqlClient:            sql.NewClient(mc),
		storageServiceClient: storageservice.NewClient(mc),
		vmClient:             virtualmachine.NewClient(mc),
		vmDiskClient:         virtualmachinedisk.NewClient(mc),
		vmImageClient:        virtualmachineimage.NewClient(mc),
		vnetClient:           virtualnetwork.NewClient(mc),
		mutex:                &sync.Mutex{},
	}, nil
}
Example #7
0
// Run executes a Packer build and returns a packer.Artifact representing
// a Azure VM image.
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	ui.Say("Preparing builder...")

	ui.Message("Creating Azure Service Management client...")
	subscriptionID, err := findSubscriptionID(b.config.PublishSettingsPath, b.config.SubscriptionName)
	if err != nil {
		return nil, fmt.Errorf("Error creating new Azure client: %v", err)
	}
	b.client, err = management.ClientFromPublishSettingsFile(b.config.PublishSettingsPath, subscriptionID)
	if err != nil {
		return nil, fmt.Errorf("Error creating new Azure client: %v", err)
	}

	// add logger if appropriate
	b.client = GetLoggedClient(b.client)

	// Set up the state.
	state := new(multistep.BasicStateBag)
	state.Put(constants.Config, b.config)
	state.Put(constants.RequestManager, b.client)
	state.Put("hook", hook)
	state.Put(constants.Ui, ui)

	// complete flags
	state.Put(constants.SrvExists, 0)
	state.Put(constants.CertInstalled, 0)
	state.Put(constants.CertUploaded, 0)
	state.Put(constants.VmExists, 0)
	state.Put(constants.DiskExists, 0)
	state.Put(constants.VmRunning, 0)
	state.Put(constants.ImageCreated, 0)

	var steps []multistep.Step

	if b.config.OSType == constants.Target_Linux {
		steps = []multistep.Step{
			&lin.StepCreateCert{
				TmpServiceName: b.config.tmpServiceName,
			},
			new(StepValidate),
			&StepCreateService{
				Location:       b.config.Location,
				TmpServiceName: b.config.tmpServiceName,
			},
			&StepUploadCertificate{
				TmpServiceName: b.config.tmpServiceName,
			},
			new(StepCreateVm),
			&StepPollStatus{
				TmpServiceName: b.config.tmpServiceName,
				TmpVmName:      b.config.tmpVmName,
				OSType:         b.config.OSType,
			},

			&communicator.StepConnectSSH{
				Config:    &b.config.Comm,
				Host:      lin.SSHHost,
				SSHConfig: lin.SSHConfig(b.config.UserName),
			},
			&common.StepProvision{},

			&lin.StepGeneralizeOS{
				Command: "sudo /usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync",
			},
			&StepStopVm{
				TmpVmName:      b.config.tmpVmName,
				TmpServiceName: b.config.tmpServiceName,
			},
			&StepCreateImage{
				TmpServiceName:    b.config.tmpServiceName,
				TmpVmName:         b.config.tmpVmName,
				UserImageName:     b.config.userImageName,
				UserImageLabel:    b.config.UserImageLabel,
				RecommendedVMSize: b.config.InstanceSize,
			},
		}
	} else if b.config.OSType == constants.Target_Windows {
		steps = []multistep.Step{
			new(StepValidate),
			&StepCreateService{
				Location:       b.config.Location,
				TmpServiceName: b.config.tmpServiceName,
			},
			new(StepCreateVm),
			&StepPollStatus{
				TmpServiceName: b.config.tmpServiceName,
				TmpVmName:      b.config.tmpVmName,
				OSType:         b.config.OSType,
			},
			&win.StepSetProvisionInfrastructure{
				VmName:                    b.config.tmpVmName,
				ServiceName:               b.config.tmpServiceName,
				StorageAccountName:        b.config.StorageAccount,
				TempContainerName:         b.config.tmpContainerName,
				ProvisionTimeoutInMinutes: b.config.ProvisionTimeoutInMinutes,
			},
			&common.StepProvision{},
			&StepStopVm{
				TmpVmName:      b.config.tmpVmName,
				TmpServiceName: b.config.tmpServiceName,
			},
			&StepCreateImage{
				TmpServiceName:    b.config.tmpServiceName,
				TmpVmName:         b.config.tmpVmName,
				UserImageName:     b.config.userImageName,
				UserImageLabel:    b.config.UserImageLabel,
				RecommendedVMSize: b.config.InstanceSize,
			},
		}

	} else {
		return nil, fmt.Errorf("Unkonwn OS type: %s", b.config.OSType)
	}

	// Run the steps.
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}
	b.runner.Run(state)

	// Report any errors.
	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If we were interrupted or cancelled, then just exit.
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
		return nil, errors.New("Build was cancelled.")
	}

	if _, ok := state.GetOk(multistep.StateHalted); ok {
		return nil, errors.New("Build was halted.")
	}

	vmImageList, err := vmimage.NewClient(b.client).ListVirtualMachineImages(
		vmimage.ListParameters{
			Location: b.config.Location,
		})
	if err != nil {
		log.Printf("VM image client returned error: %s", err)
		return nil, fmt.Errorf("Can't create artifact")
	}

	if userImage, found := FindVmImage(vmImageList.VMImages, b.config.userImageName, b.config.UserImageLabel); found {
		return &artifact{
			imageLabel:    userImage.Label,
			imageName:     userImage.Name,
			mediaLocation: userImage.OSDiskConfiguration.MediaLink,

			publishSettingsPath: b.config.PublishSettingsPath,
			subscriptionID:      subscriptionID,
		}, nil
	} else {
		log.Printf("could not find image %s", b.config.userImageName)
		return nil, fmt.Errorf("Can't create artifact")
	}
}
func TestDeployPlatformVMImageCaptureRedeploy(t *testing.T) {
	client := testutils.GetTestClient(t)
	vmname := GenerateName()
	sa := GetTestStorageAccount(t, client)
	location := sa.StorageServiceProperties.Location

	role := NewVMConfiguration(vmname, "Standard_D3")
	ConfigureDeploymentFromPlatformImage(&role,
		GetLinuxTestImage(t, client).Name,
		fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
		GenerateName())
	ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
	ConfigureWithPublicSSH(&role)

	t.Logf("Deploying VM: %s", vmname)
	createRoleConfiguration(t, client, role, location)

	t.Logf("Wait for deployment to enter running state")
	vmc := vm.NewClient(client)
	status := vm.DeploymentStatusDeploying
	for status != vm.DeploymentStatusRunning {
		deployment, err := vmc.GetDeployment(vmname, vmname)
		if err != nil {
			t.Error(err)
			break
		}
		status = deployment.Status
	}

	t.Logf("Shutting down VM: %s", vmname)
	if err := Await(client, func() (management.OperationID, error) {
		return vmc.ShutdownRole(vmname, vmname, vmname, vm.PostShutdownActionStopped)
	}); err != nil {
		t.Error(err)
	}

	if err := WaitForDeploymentInstanceStatus(client, vmname, vmname, vm.InstanceStatusStoppedVM); err != nil {
		t.Fatal(err)
	}

	imagename := GenerateName()
	t.Logf("Capturing VMImage: %s", imagename)
	if err := Await(client, func() (management.OperationID, error) {
		return vmimage.NewClient(client).Capture(vmname, vmname, vmname, imagename, imagename, vmimage.OSStateGeneralized, vmimage.CaptureParameters{})
	}); err != nil {
		t.Error(err)
	}

	im := GetUserVMImage(t, client, imagename)
	t.Logf("Found image: %+v", im)

	newvmname := GenerateName()
	role = NewVMConfiguration(newvmname, "Standard_D3")
	ConfigureDeploymentFromUserVMImage(&role, im.Name)
	ConfigureForLinux(&role, newvmname, "azureuser", GeneratePassword())
	ConfigureWithPublicSSH(&role)

	t.Logf("Deploying new VM from freshly captured VM image: %s", newvmname)
	if err := Await(client, func() (management.OperationID, error) {
		return vmc.CreateDeployment(role, vmname, vm.CreateDeploymentOptions{})
	}); err != nil {
		t.Error(err)
	}

	deleteHostedService(t, client, vmname)
}
Example #9
0
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)
	config := state.Get(constants.Config).(*Config)

	ui.Say("Validating Azure options...")

	role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)

	ui.Message("Checking Storage Account...")
	destinationVhd, err := validateStorageAccount(config, client)
	if err != nil {
		err = fmt.Errorf("Error checking storage account: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))

	if err := func() error {
		if config.RemoteSourceImageLink != "" {
			ui.Message("Checking remote image source link...")
			response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
			if response != nil && response.Body != nil {
				defer response.Body.Close()
			}
			if err != nil {
				log.Printf("HTTP client returned error: %s", err)
				return fmt.Errorf("error checking remote image source link: %v", err)
			}
			if response.StatusCode != 200 {
				return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
			}
			size := float64(response.ContentLength) / 1024 / 1024 / 1024
			ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))

			vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
			if config.ResizeOSVhdGB != nil {
				if float64(*config.ResizeOSVhdGB) < size {
					return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, size)
				}
				ui.Say(fmt.Sprintf("Remote image will be resized to %d GiB", *config.ResizeOSVhdGB))
				role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
			}

		} else {
			ui.Message("Checking image source...")
			imageList, err := osimage.NewClient(client).ListOSImages()
			if err != nil {
				log.Printf("OS image client returned error: %s", err)
				return err
			}

			if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
				vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
				ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
				if osImage.OS != config.OSType {
					return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
				}
				if config.ResizeOSVhdGB != nil {
					if float64(*config.ResizeOSVhdGB) < osImage.LogicalSizeInGB {
						return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, osImage.LogicalSizeInGB)
					}
					ui.Say(fmt.Sprintf("OS image will be resized to %d GiB", *config.ResizeOSVhdGB))
					role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
				}
			} else {
				imageList, err := vmimage.NewClient(client).ListVirtualMachineImages(
					vmimage.ListParameters{
						Location: config.Location,
					})
				if err != nil {
					log.Printf("VM image client returned error: %s", err)
					return err
				}

				if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel); found {
					if config.ResizeOSVhdGB != nil {
						return fmt.Errorf("Packer cannot resize VM images")
					}
					if vmImage.OSDiskConfiguration.OSState != vmimage.OSStateGeneralized {
						return fmt.Errorf("Packer can only use VM user images with a generalized OS so that it can be reprovisioned. The specified image OS is not in a generalized state.")
					}

					if vmImage.Category == vmimage.CategoryUser {
						//vmutils.ConfigureDeploymentFromUserVMImage(&role, vmImage.Name)
						role.VMImageName = vmImage.Name
					} else {
						vmutils.ConfigureDeploymentFromPublishedVMImage(&role, vmImage.Name, destinationVhd, true)
					}

					ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
					if vmImage.OSDiskConfiguration.OS != config.OSType {
						return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
					}
				} else {
					return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
				}
			}
		}
		return nil
	}(); err != nil {
		err = fmt.Errorf("Error determining deployment source: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	if config.OSType == constants.Target_Linux {
		certThumbprint := state.Get(constants.Thumbprint).(string)
		if len(certThumbprint) == 0 {
			err := fmt.Errorf("Certificate Thumbprint is empty")
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)

		// disallowing password login is irreversible on some images, see https://github.com/Azure/packer-azure/issues/62
		for i, _ := range role.ConfigurationSets {
			if role.ConfigurationSets[i].ConfigurationSetType == vm.ConfigurationSetTypeLinuxProvisioning {
				role.ConfigurationSets[i].DisableSSHPasswordAuthentication = "false"
			}
		}

		vmutils.ConfigureWithPublicSSH(&role)
	} else if config.OSType == constants.Target_Windows {
		password := common.RandomPassword()
		state.Put("password", password)
		vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
		vmutils.ConfigureWithPublicRDP(&role)
		vmutils.ConfigureWithPublicPowerShell(&role)
	}

	if config.VNet != "" && config.Subnet != "" {
		ui.Message("Checking VNet...")
		if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureWithSubnet(&role, config.Subnet)
	}

	for n, d := range config.DataDisks {
		switch d := d.(type) {
		case int:
			ui.Message(fmt.Sprintf("Configuring datadisk %d: new disk with size %d GB...", n, d))
			destination := fmt.Sprintf("%s-data-%d.vhd", destinationVhd[:len(destinationVhd)-4], n)
			ui.Message(fmt.Sprintf("Destination VHD for data disk %s: %d", destinationVhd, n))
			vmutils.ConfigureWithNewDataDisk(&role, "", destination, d, vmdisk.HostCachingTypeNone)
		case string:
			ui.Message(fmt.Sprintf("Configuring datadisk %d: existing blob (%s)...", n, d))
			vmutils.ConfigureWithVhdDataDisk(&role, d, vmdisk.HostCachingTypeNone)
		default:
			err := fmt.Errorf("Datadisk %d is not a string nor a number", n)
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}

	}

	state.Put("role", &role)

	return multistep.ActionContinue
}
Example #10
0
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)
	config := state.Get(constants.Config).(*Config)

	ui.Say("Validating Azure options...")

	role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)

	ui.Message("Checking Storage Account...")
	destinationVhd, err := validateStorageAccount(config, client)
	if err != nil {
		err = fmt.Errorf("Error checking storage account: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))

	if err := func() error {
		if config.RemoteSourceImageLink != "" {
			ui.Message("Checking remote image source link...")
			response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
			if response != nil && response.Body != nil {
				defer response.Body.Close()
			}
			if err != nil {
				log.Printf("HTTP client returned error: %s", err)
				return fmt.Errorf("error checking remote image source link: %v", err)
			}
			if response.StatusCode != 200 {
				return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
			}
			size := float64(response.ContentLength) / 1024 / 1024 / 1024
			ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))

			vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
		} else {
			ui.Message("Checking image source...")
			imageList, err := osimage.NewClient(client).ListOSImages()
			if err != nil {
				log.Printf("OS image client returned error: %s", err)
				return err
			}

			if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
				vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
				ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
				if osImage.OS != config.OSType {
					return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
				}
			} else {
				imageList, err := vmimage.NewClient(client).ListVirtualMachineImages()
				if err != nil {
					log.Printf("VM image client returned error: %s", err)
					return err
				}

				if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel, config.Location); found {
					vmutils.ConfigureDeploymentFromVMImage(&role, vmImage.Name, destinationVhd, true)
					ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
					if vmImage.OSDiskConfiguration.OS != config.OSType {
						return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
					}
				} else {
					return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
				}
			}
		}
		return nil
	}(); err != nil {
		err = fmt.Errorf("Error determining deployment source: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	if config.OSType == constants.Target_Linux {
		certThumbprint := state.Get(constants.Thumbprint).(string)
		if len(certThumbprint) == 0 {
			err := fmt.Errorf("Certificate Thumbprint is empty")
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)
		vmutils.ConfigureWithPublicSSH(&role)
	} else if config.OSType == constants.Target_Windows {
		password := utils.RandomPassword()
		state.Put("password", password)
		vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
		vmutils.ConfigureWithPublicRDP(&role)
		vmutils.ConfigureWithPublicPowerShell(&role)
	}

	if config.VNet != "" && config.Subnet != "" {
		ui.Message("Checking VNet...")
		if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureWithSubnet(&role, config.Subnet)
	}

	state.Put("role", &role)

	return multistep.ActionContinue
}
Example #11
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
}