Coverage Report
Generated on 24 Jan 17 19:02 +0000 with
gocov-htmlReport Overview
Package Overview: github.com/Azure/packer-azure/packer/builder/azure/common 92.86%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/builder/azure/common
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/builder/azure/common | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
RandomPassword(...) | github.com/Azure/packer-azure/packer/builder/azure/common/randomstring.go | 100.00% | 13/13 |
GlueStrings(...) | github.com/Azure/packer-azure/packer/builder/azure/common/gluestrings.go | 100.00% | 9/9 |
RandomString(...) | github.com/Azure/packer-azure/packer/builder/azure/common/randomstring.go | 100.00% | 4/4 |
IsStateCancelled(...) | github.com/Azure/packer-azure/packer/builder/azure/common/state_bag.go | 0.00% | 0/2 |
github.com/Azure/packer-azure/packer/builder/azure/common | 92.86% | 26/28 |
func RandomPassword
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/common/randomstring.go
:
28 | func RandomPassword() (password string) {
|
29 | pwlen := 15
|
30 | batchsize := pwlen / len(pwSymbols)
|
31 | pw := make([]byte, 0, pwlen)
|
32 | // choose character set
|
33 | for c := 0; len(pw) < pwlen; c++ {
|
34 | s := RandomString(pwSymbols[c%len(pwSymbols)], rnd.Intn(batchsize-1)+1)
|
35 | pw = append(pw, []byte(s)...)
|
36 | }
|
37 | // truncate
|
38 | pw = pw[:pwlen]
|
39 |
|
40 | // permute
|
41 | for c := 0; c < pwlen-1; c++ {
|
42 | i := rnd.Intn(pwlen-c) + c
|
43 | x := pw[c]
|
44 | pw[c] = pw[i]
|
45 | pw[i] = x
|
46 | }
|
47 | return string(pw)
|
48 | }
|
func GlueStrings
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/common/gluestrings.go
:
8 | func GlueStrings(a, b string) string {
|
9 | shift := 0
|
10 | for shift < len(a) {
|
11 | i := 0
|
12 | for (i+shift < len(a)) && (i < len(b)) && (a[i+shift] == b[i]) {
|
13 | i++
|
14 | }
|
15 | if i+shift == len(a) {
|
16 | break
|
17 | }
|
18 | shift++
|
19 | }
|
20 |
|
21 | return string(a[:shift]) + b
|
22 | }
|
func RandomString
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/common/randomstring.go
:
20 | func RandomString(chooseFrom string, length int) (randomString string) {
|
21 | cflen := len(chooseFrom)
|
22 | for i := 0; i < length; i++ {
|
23 | randomString += string(chooseFrom[rnd.Intn(cflen)])
|
24 | }
|
25 | return
|
26 | }
|
func IsStateCancelled
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/common/state_bag.go
:
8 | func IsStateCancelled(stateBag multistep.StateBag) bool {
|
9 | _, ok := stateBag.GetOk(multistep.StateCancelled)
|
10 | return ok
|
11 | }
|
Package Overview: github.com/Azure/packer-azure/packer/builder/azure/smapi 13.18%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/builder/azure/smapi
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/builder/azure/smapi | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
func FindVmImage
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
18 | func FindVmImage(imageList []vmi.VMImage, name, label string) (vmi.VMImage, bool) {
|
19 |
|
20 | imageNameRegexp := GetImageNameRegexp(name)
|
21 | matches := make([]vmi.VMImage, 0)
|
22 | for _, im := range imageList {
|
23 | if (len(label) == 0 || im.Label == label) &&
|
24 | (len(name) == 0 || imageNameRegexp.MatchString(im.Name)) {
|
25 | matches = append(matches, im)
|
26 | }
|
27 | }
|
28 |
|
29 | if len(matches) > 0 {
|
30 | sort.Sort(vmImageByPublishDate(matches))
|
31 | return matches[0], true
|
32 | }
|
33 | return vmi.VMImage{}, false
|
34 | }
|
func vmImageByPublishDate.Len
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
38 | func (a vmImageByPublishDate) Len() int { return len(a) }
|
func artifact.BuilderId
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
24 | func (*artifact) BuilderId() string {
|
25 | return BuilderId
|
26 | }
|
func vmImageByPublishDate.Less
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
40 | func (a vmImageByPublishDate) Less(i, j int) bool { return a[i].PublishedDate > a[j].PublishedDate }
|
func GetImageNameRegexp
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
14 | func GetImageNameRegexp(name string) *regexp.Regexp {
|
15 | return regexp.MustCompile(strings.Replace(name, ".", `\.`, -1) + "$")
|
16 | }
|
func newConfig
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/config.go
:
57 | func newConfig(raws ...interface{}) (*Config, []string, error) {
|
58 | var c Config
|
59 |
|
60 | // Default provision timeout
|
61 | c.ProvisionTimeoutInMinutes = 120
|
62 |
|
63 | c.ctx = &interpolate.Context{}
|
64 | err := config.Decode(&c, &config.DecodeOpts{
|
65 | Interpolate: true,
|
66 | InterpolateContext: c.ctx,
|
67 | }, raws...)
|
68 | if err != nil {
|
69 | return nil, nil, err
|
70 | }
|
71 |
|
72 | // Defaults
|
73 | log.Println(fmt.Sprintf("%s: %v", "PackerUserVars", c.PackerConfig.PackerUserVars))
|
74 |
|
75 | if c.StorageContainer == "" {
|
76 | c.StorageContainer = "vhds"
|
77 | }
|
78 |
|
79 | if c.UserName == "" {
|
80 | c.UserName = "packer"
|
81 | }
|
82 |
|
83 | c.Comm.SSHUsername = c.UserName
|
84 | if c.Comm.SSHTimeout == 0 {
|
85 | c.Comm.SSHTimeout = 20 * time.Minute
|
86 | }
|
87 |
|
88 | randSuffix := azureCommon.RandomString("0123456789abcdefghijklmnopqrstuvwxyz", 10)
|
89 | c.tmpVmName = "PkrVM" + randSuffix
|
90 | c.tmpServiceName = "PkrSrv" + randSuffix
|
91 | c.tmpContainerName = "packer-provision-" + randSuffix
|
92 |
|
93 | // Check values
|
94 | var errs *packer.MultiError
|
95 | errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(c.ctx)...)
|
96 |
|
97 | if c.SubscriptionName == "" {
|
98 | errs = packer.MultiErrorAppend(errs,
|
99 | fmt.Errorf("subscription_name must be specified"))
|
100 | }
|
101 |
|
102 | if c.PublishSettingsPath == "" {
|
103 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("publish_settings_path must be specified"))
|
104 | }
|
105 |
|
106 | if c.StorageAccount == "" {
|
107 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("storage_account must be specified"))
|
108 | }
|
109 |
|
110 | if _, err := os.Stat(c.PublishSettingsPath); err != nil {
|
111 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("publish_settings_path is not a valid path: %s", err))
|
112 | }
|
113 |
|
114 | if !(c.OSType == constants.Target_Linux || c.OSType == constants.Target_Windows) {
|
115 | errs = packer.MultiErrorAppend(errs,
|
116 | fmt.Errorf("os_type is not valid, must be one of: %s, %s", constants.Target_Windows, constants.Target_Linux))
|
117 | }
|
118 |
|
119 | count := 0
|
120 | if c.RemoteSourceImageLink != "" {
|
121 | count += 1
|
122 | }
|
123 | if c.OSImageLabel != "" {
|
124 | count += 1
|
125 | }
|
126 | if c.OSImageName != "" {
|
127 | count += 1
|
128 | }
|
129 |
|
130 | if count != 1 {
|
131 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("One source and only one among os_image_label, os_image_label or remote_source_image_link has to be specified"))
|
132 | }
|
133 |
|
134 | if c.Location == "" {
|
135 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("location must be specified"))
|
136 | }
|
137 |
|
138 | if c.InstanceSize == "" {
|
139 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("instance_size must be specified"))
|
140 | }
|
141 |
|
142 | for n := 0; n < len(c.DataDisks); n++ {
|
143 | switch v := c.DataDisks[n].(type) {
|
144 | case string:
|
145 | case int:
|
146 | case float64:
|
147 | if v != math.Floor(v) {
|
148 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("Data disk # %d is a fractional number, needs to be integer", n))
|
149 | }
|
150 | c.DataDisks[n] = int(v)
|
151 | default:
|
152 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("Data disk # %d is not a string to an existing VHD nor an integer number, but a %T", n, v))
|
153 | }
|
154 | }
|
155 |
|
156 | if c.UserImageLabel == "" {
|
157 | log.Println(fmt.Sprintf("Using dynamically generated user_image_label [%s]", c.tmpVmName))
|
158 | c.UserImageLabel = c.tmpVmName
|
159 | }
|
160 |
|
161 | const userLabelRegex = "^[A-Za-z][A-Za-z0-9-_.]*[A-Za-z0-9]$"
|
162 | if !regexp.MustCompile(userLabelRegex).MatchString(c.UserImageLabel) {
|
163 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("user_image_label [%s] is not valid, it should follow the pattern %s", c.UserImageLabel, userLabelRegex))
|
164 | }
|
165 |
|
166 | c.userImageName = fmt.Sprintf("%s_%s", c.UserImageLabel, time.Now().Format("2006-01-02_15-04"))
|
167 |
|
168 | if (c.VNet != "" && c.Subnet == "") || (c.Subnet != "" && c.VNet == "") {
|
169 | errs = packer.MultiErrorAppend(errs, fmt.Errorf("vnet and subnet need to either both be set or both be empty"))
|
170 | }
|
171 |
|
172 | log.Println(common.ScrubConfig(c))
|
173 |
|
174 | if errs != nil && len(errs.Errors) > 0 {
|
175 | return nil, nil, errs
|
176 | }
|
177 |
|
178 | return &c, nil, nil
|
179 | }
|
func findSubscriptionID
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/publishsettings.go
:
9 | func findSubscriptionID(publishSettingsPath, subscriptionName string) (string, error) {
|
10 | data, err := ioutil.ReadFile(publishSettingsPath)
|
11 | if err != nil {
|
12 | return "", fmt.Errorf("Error reading publishsettings (%s): %v", publishSettingsPath, err)
|
13 | }
|
14 |
|
15 | var pubsettings struct {
|
16 | Subscriptions []struct {
|
17 | ID string `xml:"Id,attr"`
|
18 | Name string `xml:",attr"`
|
19 | } `xml:"PublishProfile>Subscription"`
|
20 | }
|
21 | err = xml.Unmarshal(data, &pubsettings)
|
22 | if err != nil {
|
23 | return "", fmt.Errorf("Error deserializing publishsettings (%s): %v", publishSettingsPath, err)
|
24 | }
|
25 |
|
26 | for _, subscription := range pubsettings.Subscriptions {
|
27 | if subscription.Name == subscriptionName {
|
28 | return subscription.ID, nil
|
29 | }
|
30 | }
|
31 |
|
32 | return "", fmt.Errorf("Subscription with name %q not found in %s", subscriptionName, publishSettingsPath)
|
33 | }
|
func artifact.State
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
36 | func (a *artifact) State(name string) interface{} {
|
37 | log.Printf("Artifact.State(%s) called", name)
|
38 |
|
39 | switch name {
|
40 | case "publishSettingsPath":
|
41 | return a.publishSettingsPath
|
42 | case "subscriptionID":
|
43 | return a.subscriptionID
|
44 | default:
|
45 | return nil
|
46 | }
|
47 | }
|
func StepPollStatus.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_poll_status.go
:
26 | func (s *StepPollStatus) Run(state multistep.StateBag) multistep.StepAction {
|
27 | client := state.Get(constants.RequestManager).(management.Client)
|
28 | vmc := vm.NewClient(client)
|
29 | ui := state.Get(constants.Ui).(packer.Ui)
|
30 |
|
31 | errorMsg := "Error polling temporary Azure VM is ready: %s"
|
32 |
|
33 | ui.Say("Polling till temporary Azure VM is ready...")
|
34 |
|
35 | if len(s.OSType) == 0 {
|
36 | err := fmt.Errorf(errorMsg, "'OSType' param is empty")
|
37 | state.Put("error", err)
|
38 | ui.Error(err.Error())
|
39 | return multistep.ActionHalt
|
40 | }
|
41 |
|
42 | var count uint = 60
|
43 | var duration time.Duration = 40
|
44 | sleepTime := time.Second * duration
|
45 | total := count * uint(duration)
|
46 |
|
47 | var deployment vm.DeploymentResponse
|
48 |
|
49 | for count > 0 {
|
50 | var err error // deployment needs to be accessed outside of this loop, can't use :=
|
51 | deployment, err = vmc.GetDeployment(s.TmpServiceName, s.TmpVmName)
|
52 | if err != nil {
|
53 | err := fmt.Errorf(errorMsg, err)
|
54 | state.Put("error", err)
|
55 | ui.Error(err.Error())
|
56 | return multistep.ActionHalt
|
57 | }
|
58 |
|
59 | if len(deployment.RoleInstanceList) > 0 {
|
60 | powerState := deployment.RoleInstanceList[0].PowerState
|
61 | instanceStatus := deployment.RoleInstanceList[0].InstanceStatus
|
62 |
|
63 | if powerState == vm.PowerStateStarted && instanceStatus == vm.InstanceStatusReadyRole {
|
64 | break
|
65 | }
|
66 |
|
67 | if instanceStatus == vm.InstanceStatusFailedStartingRole ||
|
68 | instanceStatus == vm.InstanceStatusFailedStartingVM ||
|
69 | instanceStatus == vm.InstanceStatusUnresponsiveRole {
|
70 | err := fmt.Errorf(errorMsg, "deployment.RoleInstanceList[0].instanceStatus is "+instanceStatus)
|
71 | state.Put("error", err)
|
72 | ui.Error(err.Error())
|
73 | return multistep.ActionHalt
|
74 | }
|
75 | if powerState == vm.PowerStateStopping ||
|
76 | powerState == vm.PowerStateStopped ||
|
77 | powerState == vm.PowerStateUnknown {
|
78 | err := fmt.Errorf(errorMsg, "deployment.RoleInstanceList[0].PowerState is "+powerState)
|
79 | state.Put("error", err)
|
80 | ui.Error(err.Error())
|
81 | return multistep.ActionHalt
|
82 | }
|
83 | }
|
84 |
|
85 | // powerState_Starting or deployment.RoleInstanceList[0] == 0
|
86 | log.Println(fmt.Sprintf("Waiting for another %v seconds...", uint(duration)))
|
87 | time.Sleep(sleepTime)
|
88 | count--
|
89 | }
|
90 |
|
91 | if count == 0 {
|
92 | err := fmt.Errorf(errorMsg, fmt.Sprintf("time is up (%d seconds)", total))
|
93 | state.Put("error", err)
|
94 | ui.Error(err.Error())
|
95 | return multistep.ActionHalt
|
96 | }
|
97 |
|
98 | state.Put(constants.VmRunning, 1)
|
99 |
|
100 | log.Println("s.OSType = " + s.OSType)
|
101 |
|
102 | if s.OSType == constants.Target_Linux {
|
103 | endpoints := deployment.RoleInstanceList[0].InstanceEndpoints
|
104 | if len(endpoints) == 0 {
|
105 | err := fmt.Errorf(errorMsg, "deployment.RoleInstanceList[0].InstanceEndpoints list is empty")
|
106 | state.Put("error", err)
|
107 | ui.Error(err.Error())
|
108 | return multistep.ActionHalt
|
109 | }
|
110 |
|
111 | vip := endpoints[0].Vip
|
112 | state.Put(constants.SSHHost, vip)
|
113 |
|
114 | ui.Message("VM Endpoint: " + vip)
|
115 | }
|
116 |
|
117 | roleList := deployment.RoleList
|
118 | if len(roleList) == 0 {
|
119 | err := fmt.Errorf(errorMsg, "deployment.RoleList is empty")
|
120 | state.Put("error", err)
|
121 | ui.Error(err.Error())
|
122 | return multistep.ActionHalt
|
123 | }
|
124 |
|
125 | diskName := roleList[0].OSVirtualHardDisk.DiskName
|
126 | ui.Message("VM DiskName: " + diskName)
|
127 | state.Put(constants.HardDiskName, diskName)
|
128 |
|
129 | mediaLink := roleList[0].OSVirtualHardDisk.MediaLink
|
130 | ui.Message("VM MediaLink: " + mediaLink)
|
131 | state.Put(constants.MediaLink, mediaLink)
|
132 |
|
133 | return multistep.ActionContinue
|
134 | }
|
func StepValidate.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
28 | func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
|
29 | client := state.Get(constants.RequestManager).(management.Client)
|
30 | ui := state.Get(constants.Ui).(packer.Ui)
|
31 | config := state.Get(constants.Config).(*Config)
|
32 |
|
33 | ui.Say("Validating Azure options...")
|
34 |
|
35 | locationsResponse, err := location.NewClient(client).ListLocations()
|
36 | if err != nil {
|
37 | err = fmt.Errorf("Error checking location: %v", err)
|
38 | state.Put("error", err)
|
39 | ui.Error(err.Error())
|
40 | return multistep.ActionHalt
|
41 | }
|
42 | if err := func() error {
|
43 | for _, l := range locationsResponse.Locations {
|
44 | if config.Location == l.Name {
|
45 | ui.Message("Checking instance size availability...")
|
46 | if !func() bool {
|
47 | for _, size := range l.VirtualMachineRoleSizes {
|
48 | if size == config.InstanceSize {
|
49 | return true
|
50 | }
|
51 | }
|
52 | return false
|
53 | }() {
|
54 | sizes := strings.Join(l.VirtualMachineRoleSizes, ",")
|
55 | return fmt.Errorf("Instance size %q not available in location %q for this subscription, valid instance sizes: %s",
|
56 | config.InstanceSize, config.Location, sizes)
|
57 | }
|
58 | return nil
|
59 | }
|
60 | }
|
61 | return fmt.Errorf("Location %q not available for this subscription, valid locations: %s", config.Location, locationsResponse.String())
|
62 | }(); err != nil {
|
63 | state.Put("error", err)
|
64 | ui.Error(err.Error())
|
65 | return multistep.ActionHalt
|
66 | }
|
67 |
|
68 | role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)
|
69 |
|
70 | ui.Message("Checking storage account...")
|
71 | destinationVhd, err := validateStorageAccount(config, client)
|
72 | if err != nil {
|
73 | err = fmt.Errorf("Error checking storage account: %v", err)
|
74 | state.Put("error", err)
|
75 | ui.Error(err.Error())
|
76 | return multistep.ActionHalt
|
77 | }
|
78 | ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))
|
79 |
|
80 | if err := func() error {
|
81 | if config.RemoteSourceImageLink != "" {
|
82 | ui.Message("Checking remote image source link...")
|
83 | response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
|
84 | if response != nil && response.Body != nil {
|
85 | defer response.Body.Close()
|
86 | }
|
87 | if err != nil {
|
88 | log.Printf("HTTP client returned error: %s", err)
|
89 | return fmt.Errorf("error checking remote image source link: %v", err)
|
90 | }
|
91 | if response.StatusCode != 200 {
|
92 | return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
|
93 | }
|
94 | size := float64(response.ContentLength) / 1024 / 1024 / 1024
|
95 | ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))
|
96 |
|
97 | vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
|
98 | if config.ResizeOSVhdGB != nil {
|
99 | if float64(*config.ResizeOSVhdGB) < size {
|
100 | return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, size)
|
101 | }
|
102 | ui.Say(fmt.Sprintf("Remote image will be resized to %d GiB", *config.ResizeOSVhdGB))
|
103 | role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
|
104 | }
|
105 |
|
106 | } else {
|
107 | ui.Message("Checking image source...")
|
108 | imageList, err := osimage.NewClient(client).ListOSImages()
|
109 | if err != nil {
|
110 | log.Printf("OS image client returned error: %s", err)
|
111 | return err
|
112 | }
|
113 |
|
114 | if osImage, found := FindOSImage(imageList.OSImages, config.OSImageName, config.OSImageLabel, config.Location); found {
|
115 | vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
|
116 | ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
|
117 | if osImage.OS != config.OSType {
|
118 | return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
|
119 | }
|
120 | if config.ResizeOSVhdGB != nil {
|
121 | if float64(*config.ResizeOSVhdGB) < osImage.LogicalSizeInGB {
|
122 | return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, osImage.LogicalSizeInGB)
|
123 | }
|
124 | ui.Say(fmt.Sprintf("OS image will be resized to %d GiB", *config.ResizeOSVhdGB))
|
125 | role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
|
126 | }
|
127 | } else {
|
128 | imageList, err := vmimage.NewClient(client).ListVirtualMachineImages(
|
129 | vmimage.ListParameters{
|
130 | Location: config.Location,
|
131 | })
|
132 | if err != nil {
|
133 | log.Printf("VM image client returned error: %s", err)
|
134 | return err
|
135 | }
|
136 |
|
137 | if vmImage, found := FindVmImage(imageList.VMImages, config.OSImageName, config.OSImageLabel); found {
|
138 | if config.ResizeOSVhdGB != nil {
|
139 | return fmt.Errorf("Packer cannot resize VM images")
|
140 | }
|
141 | if vmImage.OSDiskConfiguration.OSState != vmimage.OSStateGeneralized {
|
142 | 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.")
|
143 | }
|
144 |
|
145 | if vmImage.Category == vmimage.CategoryUser {
|
146 | //vmutils.ConfigureDeploymentFromUserVMImage(&role, vmImage.Name)
|
147 | role.VMImageName = vmImage.Name
|
148 | } else {
|
149 | vmutils.ConfigureDeploymentFromPublishedVMImage(&role, vmImage.Name, destinationVhd, true)
|
150 | }
|
151 |
|
152 | ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
|
153 | if vmImage.OSDiskConfiguration.OS != config.OSType {
|
154 | return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
|
155 | }
|
156 | } else {
|
157 | return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
|
158 | }
|
159 | }
|
160 | }
|
161 | return nil
|
162 | }(); err != nil {
|
163 | err = fmt.Errorf("Error determining deployment source: %v", err)
|
164 | state.Put("error", err)
|
165 | ui.Error(err.Error())
|
166 | return multistep.ActionHalt
|
167 | }
|
168 |
|
169 | if config.OSType == constants.Target_Linux {
|
170 | certThumbprint := state.Get(constants.Thumbprint).(string)
|
171 | if len(certThumbprint) == 0 {
|
172 | err := fmt.Errorf("Certificate Thumbprint is empty")
|
173 | state.Put("error", err)
|
174 | ui.Error(err.Error())
|
175 | return multistep.ActionHalt
|
176 | }
|
177 | vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)
|
178 |
|
179 | // disallowing password login is irreversible on some images, see https://github.com/Azure/packer-azure/issues/62
|
180 | for i, _ := range role.ConfigurationSets {
|
181 | if role.ConfigurationSets[i].ConfigurationSetType == vm.ConfigurationSetTypeLinuxProvisioning {
|
182 | role.ConfigurationSets[i].DisableSSHPasswordAuthentication = "false"
|
183 | }
|
184 | }
|
185 |
|
186 | vmutils.ConfigureWithPublicSSH(&role)
|
187 | } else if config.OSType == constants.Target_Windows {
|
188 | password := common.RandomPassword()
|
189 | state.Put("password", password)
|
190 | vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
|
191 | vmutils.ConfigureWithPublicRDP(&role)
|
192 | vmutils.ConfigureWithPublicPowerShell(&role)
|
193 | }
|
194 |
|
195 | if config.VNet != "" && config.Subnet != "" {
|
196 | ui.Message("Checking VNet...")
|
197 | if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
|
198 | state.Put("error", err)
|
199 | ui.Error(err.Error())
|
200 | return multistep.ActionHalt
|
201 | }
|
202 | vmutils.ConfigureWithSubnet(&role, config.Subnet)
|
203 | }
|
204 |
|
205 | for n, d := range config.DataDisks {
|
206 | switch d := d.(type) {
|
207 | case int:
|
208 | ui.Message(fmt.Sprintf("Configuring datadisk %d: new disk with size %d GB...", n, d))
|
209 | destination := fmt.Sprintf("%s-data-%d.vhd", destinationVhd[:len(destinationVhd)-4], n)
|
210 | ui.Message(fmt.Sprintf("Destination VHD for data disk %s: %d", destinationVhd, n))
|
211 | vmutils.ConfigureWithNewDataDisk(&role, "", destination, d, vmdisk.HostCachingTypeNone)
|
212 | case string:
|
213 | ui.Message(fmt.Sprintf("Configuring datadisk %d: existing blob (%s)...", n, d))
|
214 | vmutils.ConfigureWithVhdDataDisk(&role, d, vmdisk.HostCachingTypeNone)
|
215 | default:
|
216 | err := fmt.Errorf("Datadisk %d is not a string nor a number", n)
|
217 | state.Put("error", err)
|
218 | ui.Error(err.Error())
|
219 | return multistep.ActionHalt
|
220 | }
|
221 |
|
222 | }
|
223 |
|
224 | state.Put("role", &role)
|
225 |
|
226 | return multistep.ActionContinue
|
227 | }
|
func @80:12
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
80 | func() error {
|
81 | if config.RemoteSourceImageLink != "" {
|
82 | ui.Message("Checking remote image source link...")
|
83 | response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
|
84 | if response != nil && response.Body != nil {
|
85 | defer response.Body.Close()
|
86 | }
|
87 | if err != nil {
|
88 | log.Printf("HTTP client returned error: %s", err)
|
89 | return fmt.Errorf("error checking remote image source link: %v", err)
|
90 | }
|
91 | if response.StatusCode != 200 {
|
92 | return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
|
93 | }
|
94 | size := float64(response.ContentLength) / 1024 / 1024 / 1024
|
95 | ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))
|
96 |
|
97 | vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
|
98 | if config.ResizeOSVhdGB != nil {
|
99 | if float64(*config.ResizeOSVhdGB) < size {
|
100 | return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, size)
|
101 | }
|
102 | ui.Say(fmt.Sprintf("Remote image will be resized to %d GiB", *config.ResizeOSVhdGB))
|
103 | role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
|
104 | }
|
105 |
|
106 | } else {
|
107 | ui.Message("Checking image source...")
|
108 | imageList, err := osimage.NewClient(client).ListOSImages()
|
109 | if err != nil {
|
110 | log.Printf("OS image client returned error: %s", err)
|
111 | return err
|
112 | }
|
113 |
|
114 | if osImage, found := FindOSImage(imageList.OSImages, config.OSImageName, config.OSImageLabel, config.Location); found {
|
115 | vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
|
116 | ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
|
117 | if osImage.OS != config.OSType {
|
118 | return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
|
119 | }
|
120 | if config.ResizeOSVhdGB != nil {
|
121 | if float64(*config.ResizeOSVhdGB) < osImage.LogicalSizeInGB {
|
122 | return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, osImage.LogicalSizeInGB)
|
123 | }
|
124 | ui.Say(fmt.Sprintf("OS image will be resized to %d GiB", *config.ResizeOSVhdGB))
|
125 | role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
|
126 | }
|
127 | } else {
|
128 | imageList, err := vmimage.NewClient(client).ListVirtualMachineImages(
|
129 | vmimage.ListParameters{
|
130 | Location: config.Location,
|
131 | })
|
132 | if err != nil {
|
133 | log.Printf("VM image client returned error: %s", err)
|
134 | return err
|
135 | }
|
136 |
|
137 | if vmImage, found := FindVmImage(imageList.VMImages, config.OSImageName, config.OSImageLabel); found {
|
138 | if config.ResizeOSVhdGB != nil {
|
139 | return fmt.Errorf("Packer cannot resize VM images")
|
140 | }
|
141 | if vmImage.OSDiskConfiguration.OSState != vmimage.OSStateGeneralized {
|
142 | 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.")
|
143 | }
|
144 |
|
145 | if vmImage.Category == vmimage.CategoryUser {
|
146 | //vmutils.ConfigureDeploymentFromUserVMImage(&role, vmImage.Name)
|
147 | role.VMImageName = vmImage.Name
|
148 | } else {
|
149 | vmutils.ConfigureDeploymentFromPublishedVMImage(&role, vmImage.Name, destinationVhd, true)
|
150 | }
|
151 |
|
152 | ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
|
153 | if vmImage.OSDiskConfiguration.OS != config.OSType {
|
154 | return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
|
155 | }
|
156 | } else {
|
157 | return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
|
158 | }
|
159 | }
|
160 | }
|
161 | return nil
|
162 | }
|
func Builder.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/builder.go
:
43 | func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
|
44 | ui.Say("Preparing builder...")
|
45 |
|
46 | ui.Message("Creating Azure Service Management client...")
|
47 | subscriptionID, err := findSubscriptionID(b.config.PublishSettingsPath, b.config.SubscriptionName)
|
48 | if err != nil {
|
49 | return nil, fmt.Errorf("Error creating new Azure client: %v", err)
|
50 | }
|
51 | b.client, err = management.ClientFromPublishSettingsFile(b.config.PublishSettingsPath, subscriptionID)
|
52 | if err != nil {
|
53 | return nil, fmt.Errorf("Error creating new Azure client: %v", err)
|
54 | }
|
55 |
|
56 | // add logger if appropriate
|
57 | b.client = GetLoggedClient(b.client)
|
58 |
|
59 | // Set up the state.
|
60 | state := new(multistep.BasicStateBag)
|
61 | state.Put(constants.Config, b.config)
|
62 | state.Put(constants.RequestManager, b.client)
|
63 | state.Put("hook", hook)
|
64 | state.Put(constants.Ui, ui)
|
65 |
|
66 | // complete flags
|
67 | state.Put(constants.SrvExists, 0)
|
68 | state.Put(constants.CertInstalled, 0)
|
69 | state.Put(constants.CertUploaded, 0)
|
70 | state.Put(constants.VmExists, 0)
|
71 | state.Put(constants.DiskExists, 0)
|
72 | state.Put(constants.VmRunning, 0)
|
73 | state.Put(constants.ImageCreated, 0)
|
74 |
|
75 | var steps []multistep.Step
|
76 |
|
77 | if b.config.OSType == constants.Target_Linux {
|
78 | steps = []multistep.Step{
|
79 | &lin.StepCreateCert{
|
80 | TmpServiceName: b.config.tmpServiceName,
|
81 | },
|
82 | new(StepValidate),
|
83 | &StepCreateService{
|
84 | Location: b.config.Location,
|
85 | TmpServiceName: b.config.tmpServiceName,
|
86 | },
|
87 | &StepUploadCertificate{
|
88 | TmpServiceName: b.config.tmpServiceName,
|
89 | },
|
90 | new(StepCreateVm),
|
91 | &StepPollStatus{
|
92 | TmpServiceName: b.config.tmpServiceName,
|
93 | TmpVmName: b.config.tmpVmName,
|
94 | OSType: b.config.OSType,
|
95 | },
|
96 |
|
97 | &communicator.StepConnectSSH{
|
98 | Config: &b.config.Comm,
|
99 | Host: lin.SSHHost,
|
100 | SSHConfig: lin.SSHConfig(b.config.UserName),
|
101 | },
|
102 | &common.StepProvision{},
|
103 |
|
104 | &lin.StepGeneralizeOS{
|
105 | Command: "sudo /usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync",
|
106 | },
|
107 | &StepStopVm{
|
108 | TmpVmName: b.config.tmpVmName,
|
109 | TmpServiceName: b.config.tmpServiceName,
|
110 | },
|
111 | &StepCreateImage{
|
112 | TmpServiceName: b.config.tmpServiceName,
|
113 | TmpVmName: b.config.tmpVmName,
|
114 | UserImageName: b.config.userImageName,
|
115 | UserImageLabel: b.config.UserImageLabel,
|
116 | RecommendedVMSize: b.config.InstanceSize,
|
117 | },
|
118 | }
|
119 | } else if b.config.OSType == constants.Target_Windows {
|
120 | steps = []multistep.Step{
|
121 | new(StepValidate),
|
122 | &StepCreateService{
|
123 | Location: b.config.Location,
|
124 | TmpServiceName: b.config.tmpServiceName,
|
125 | },
|
126 | new(StepCreateVm),
|
127 | &StepPollStatus{
|
128 | TmpServiceName: b.config.tmpServiceName,
|
129 | TmpVmName: b.config.tmpVmName,
|
130 | OSType: b.config.OSType,
|
131 | },
|
132 | &StepSetProvisionInfrastructure{
|
133 | VmName: b.config.tmpVmName,
|
134 | ServiceName: b.config.tmpServiceName,
|
135 | StorageAccountName: b.config.StorageAccount,
|
136 | TempContainerName: b.config.tmpContainerName,
|
137 | ProvisionTimeoutInMinutes: b.config.ProvisionTimeoutInMinutes,
|
138 | },
|
139 | &common.StepProvision{},
|
140 | &StepStopVm{
|
141 | TmpVmName: b.config.tmpVmName,
|
142 | TmpServiceName: b.config.tmpServiceName,
|
143 | },
|
144 | &StepCreateImage{
|
145 | TmpServiceName: b.config.tmpServiceName,
|
146 | TmpVmName: b.config.tmpVmName,
|
147 | UserImageName: b.config.userImageName,
|
148 | UserImageLabel: b.config.UserImageLabel,
|
149 | RecommendedVMSize: b.config.InstanceSize,
|
150 | },
|
151 | }
|
152 |
|
153 | } else {
|
154 | return nil, fmt.Errorf("Unkonwn OS type: %s", b.config.OSType)
|
155 | }
|
156 |
|
157 | // Run the steps.
|
158 | if b.config.PackerDebug {
|
159 | b.runner = &multistep.DebugRunner{
|
160 | Steps: steps,
|
161 | PauseFn: common.MultistepDebugFn(ui),
|
162 | }
|
163 | } else {
|
164 | b.runner = &multistep.BasicRunner{Steps: steps}
|
165 | }
|
166 | b.runner.Run(state)
|
167 |
|
168 | // Report any errors.
|
169 | if rawErr, ok := state.GetOk("error"); ok {
|
170 | return nil, rawErr.(error)
|
171 | }
|
172 |
|
173 | // If we were interrupted or cancelled, then just exit.
|
174 | if _, ok := state.GetOk(multistep.StateCancelled); ok {
|
175 | return nil, errors.New("Build was cancelled.")
|
176 | }
|
177 |
|
178 | if _, ok := state.GetOk(multistep.StateHalted); ok {
|
179 | return nil, errors.New("Build was halted.")
|
180 | }
|
181 |
|
182 | vmImageList, err := vmimage.NewClient(b.client).ListVirtualMachineImages(
|
183 | vmimage.ListParameters{
|
184 | Location: b.config.Location,
|
185 | })
|
186 | if err != nil {
|
187 | log.Printf("VM image client returned error: %s", err)
|
188 | return nil, fmt.Errorf("Can't create artifact")
|
189 | }
|
190 |
|
191 | if userImage, found := FindVmImage(vmImageList.VMImages, b.config.userImageName, b.config.UserImageLabel); found {
|
192 | return &artifact{
|
193 | imageLabel: userImage.Label,
|
194 | imageName: userImage.Name,
|
195 | mediaLocation: userImage.OSDiskConfiguration.MediaLink,
|
196 |
|
197 | publishSettingsPath: b.config.PublishSettingsPath,
|
198 | subscriptionID: subscriptionID,
|
199 | }, nil
|
200 | } else {
|
201 | log.Printf("could not find image %s", b.config.userImageName)
|
202 | return nil, fmt.Errorf("Can't create artifact")
|
203 | }
|
204 | }
|
func validateStorageAccount
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
231 | func validateStorageAccount(config *Config, client management.Client) (string, error) {
|
232 | ssc := storageservice.NewClient(client)
|
233 |
|
234 | sa, err := ssc.GetStorageService(config.StorageAccount)
|
235 | if err != nil {
|
236 | return "", err
|
237 | }
|
238 |
|
239 | if sa.StorageServiceProperties.Location != config.Location {
|
240 | return "", fmt.Errorf("Storage account %q is not in location %q, but in location %q.",
|
241 | config.StorageAccount, config.Location, sa.StorageServiceProperties.Location)
|
242 | }
|
243 |
|
244 | var blobEndpoint string
|
245 | for _, uri := range sa.StorageServiceProperties.Endpoints {
|
246 | if strings.Contains(uri, ".blob.") {
|
247 | blobEndpoint = uri
|
248 | }
|
249 | }
|
250 | if blobEndpoint == "" {
|
251 | return "", fmt.Errorf("Could not find blob endpoint for account %q in %v",
|
252 | sa.ServiceName, sa.StorageServiceProperties.Endpoints)
|
253 | }
|
254 | log.Printf("Blob endpoint: %s", blobEndpoint)
|
255 |
|
256 | log.Print("Getting key for storage account...")
|
257 | keys, err := ssc.GetStorageServiceKeys(config.StorageAccount)
|
258 | if err != nil {
|
259 | return "", fmt.Errorf("Could not retrieve key for storage account %q", config.StorageAccount)
|
260 | }
|
261 | config.storageAccountKey = keys.PrimaryKey
|
262 |
|
263 | config.storageClient, err = storage.NewClient(config.StorageAccount, config.storageAccountKey,
|
264 | strings.TrimSuffix(blobEndpoint[strings.Index(blobEndpoint, ".blob.")+6:], "/"), storage.DefaultAPIVersion, true)
|
265 | if err != nil {
|
266 | return "", fmt.Errorf("Could not create storage client for account %q", config.StorageAccount)
|
267 | }
|
268 |
|
269 | return fmt.Sprintf("%s%s/%s.vhd", blobEndpoint, config.StorageContainer, config.tmpVmName), nil
|
270 | }
|
func checkVirtualNetworkConfiguration
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
272 | func checkVirtualNetworkConfiguration(client management.Client, vnetname, subnetname, location string) error {
|
273 | const getVNetConfig = "services/networking/media"
|
274 | d, err := client.SendAzureGetRequest(getVNetConfig)
|
275 | if err != nil {
|
276 | return err
|
277 | }
|
278 |
|
279 | var vnetConfig struct {
|
280 | VNets []struct {
|
281 | Name string `xml:"name,attr"`
|
282 | AffinityGroup string `xml:",attr"`
|
283 | Location string `xml:",attr"`
|
284 | Subnets []struct {
|
285 | Name string `xml:"name,attr"`
|
286 | AddressPrefix string
|
287 | } `xml:"Subnets>Subnet"`
|
288 | } `xml:"VirtualNetworkConfiguration>VirtualNetworkSites>VirtualNetworkSite"`
|
289 | }
|
290 | err = xml.Unmarshal(d, &vnetConfig)
|
291 | if err != nil {
|
292 | return err
|
293 | }
|
294 |
|
295 | for _, vnet := range vnetConfig.VNets {
|
296 | if vnet.Name == vnetname {
|
297 | if vnet.AffinityGroup != "" {
|
298 | vnet.Location, err = getAffinityGroupLocation(client, vnet.AffinityGroup)
|
299 | if err != nil {
|
300 | return err
|
301 | }
|
302 | }
|
303 | if vnet.Location != location {
|
304 | return fmt.Errorf("VNet %q is not in location %q, but in %q", vnet.Name, location, vnet.Location)
|
305 | }
|
306 |
|
307 | for _, sn := range vnet.Subnets {
|
308 | if sn.Name == subnetname {
|
309 | return nil
|
310 | }
|
311 | }
|
312 | }
|
313 | }
|
314 |
|
315 | return fmt.Errorf("Could not find vnet %q and subnet %q in network configuration: %v", vnetname, subnetname, vnetConfig)
|
316 | }
|
func StepCreateImage.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_image.go
:
62 | func (s *StepCreateImage) Cleanup(state multistep.StateBag) {
|
63 | client := state.Get(constants.RequestManager).(management.Client)
|
64 | ui := state.Get(constants.Ui).(packer.Ui)
|
65 |
|
66 | var err error
|
67 | var res int
|
68 |
|
69 | if res = state.Get(constants.VmExists).(int); res == 1 { //VM was not removed at image creation step
|
70 | return
|
71 | }
|
72 |
|
73 | // Since VM was successfully removed - remove it's media as well
|
74 |
|
75 | if res = state.Get(constants.DiskExists).(int); res == 1 {
|
76 | ui.Message("Removing Temporary Azure Disk...")
|
77 | errorMsg := "Error Removing Temporary Azure Disk: %s"
|
78 |
|
79 | diskName, ok := state.Get(constants.HardDiskName).(string)
|
80 | if ok {
|
81 | if len(diskName) == 0 {
|
82 | err := fmt.Errorf(errorMsg, err)
|
83 | ui.Error(err.Error())
|
84 | return
|
85 | }
|
86 |
|
87 | if err := retry.ExecuteOperation(func() error {
|
88 | return vmdisk.NewClient(client).DeleteDisk(diskName, true)
|
89 | }, retry.ConstantBackoffRule("busy", func(err management.AzureError) bool {
|
90 | return strings.Contains(err.Message, "is currently performing an operation on deployment") ||
|
91 | strings.Contains(err.Message, "is currently in use by virtual machine")
|
92 | }, 30*time.Second, 10)); err != nil {
|
93 | err := fmt.Errorf(errorMsg, err)
|
94 | ui.Error(err.Error())
|
95 | return
|
96 | }
|
97 |
|
98 | state.Put(constants.DiskExists, 0)
|
99 | }
|
100 | }
|
101 | }
|
func StepSetProvisionInfrastructure.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_set_provision_infrastructure.go
:
29 | func (s *StepSetProvisionInfrastructure) Run(state multistep.StateBag) multistep.StepAction {
|
30 | ui := state.Get("ui").(packer.Ui)
|
31 | client := state.Get(constants.RequestManager).(management.Client)
|
32 | config := state.Get(constants.Config).(*Config)
|
33 |
|
34 | errorMsg := "Error StepSetProvisionInfrastructure: %s"
|
35 | ui.Say("Preparing infrastructure for provision...")
|
36 |
|
37 | // get key for storage account
|
38 | ui.Message("Looking up storage account...")
|
39 |
|
40 | //create temporary container
|
41 | s.flagTempContainerCreated = false
|
42 |
|
43 | ui.Message("Creating Azure temporary container...")
|
44 | err := config.storageClient.GetBlobService().CreateContainer(s.TempContainerName, storage.ContainerAccessTypePrivate)
|
45 | if err != nil {
|
46 | err := fmt.Errorf(errorMsg, err)
|
47 | state.Put("error", err)
|
48 | ui.Error(err.Error())
|
49 | return multistep.ActionHalt
|
50 | }
|
51 |
|
52 | s.flagTempContainerCreated = true
|
53 |
|
54 | comm := azureVmCustomScriptExtension.New(
|
55 | azureVmCustomScriptExtension.Config{
|
56 | ServiceName: s.ServiceName,
|
57 | VmName: s.VmName,
|
58 | StorageAccountName: s.StorageAccountName,
|
59 | StorageAccountKey: config.storageAccountKey,
|
60 | BlobClient: config.storageClient.GetBlobService(),
|
61 | ContainerName: s.TempContainerName,
|
62 | Ui: ui,
|
63 | ManagementClient: client,
|
64 | ProvisionTimeoutInMinutes: s.ProvisionTimeoutInMinutes,
|
65 | })
|
66 |
|
67 | packerCommunicator := packer.Communicator(comm)
|
68 |
|
69 | state.Put("communicator", packerCommunicator)
|
70 |
|
71 | return multistep.ActionContinue
|
72 | }
|
func StepCreateVm.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_vm.go
:
21 | func (*StepCreateVm) Run(state multistep.StateBag) multistep.StepAction {
|
22 | client := state.Get(constants.RequestManager).(management.Client)
|
23 | ui := state.Get("ui").(packer.Ui)
|
24 | config := state.Get(constants.Config).(*Config)
|
25 |
|
26 | errorMsg := "Error Creating temporary Azure VM: %s"
|
27 |
|
28 | ui.Say("Creating temporary Azure VM...")
|
29 |
|
30 | role := state.Get("role").(*vm.Role)
|
31 |
|
32 | options := vm.CreateDeploymentOptions{}
|
33 | if config.VNet != "" && config.Subnet != "" {
|
34 | options.VirtualNetworkName = config.VNet
|
35 | }
|
36 |
|
37 | if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
|
38 | return vm.NewClient(client).CreateDeployment(*role, config.tmpServiceName, options)
|
39 | }); err != nil {
|
40 | err := fmt.Errorf(errorMsg, err)
|
41 | state.Put("error", err)
|
42 | ui.Error(err.Error())
|
43 | return multistep.ActionHalt
|
44 | }
|
45 |
|
46 | state.Put(constants.VmExists, 1)
|
47 | state.Put(constants.DiskExists, 1)
|
48 |
|
49 | return multistep.ActionContinue
|
50 | }
|
func StepCreateImage.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_image.go
:
30 | func (s *StepCreateImage) Run(state multistep.StateBag) multistep.StepAction {
|
31 | client := state.Get(constants.RequestManager).(management.Client)
|
32 | ui := state.Get(constants.Ui).(packer.Ui)
|
33 |
|
34 | errorMsg := "Error Creating Azure Image: %s"
|
35 |
|
36 | ui.Say("Creating Azure Image. If Successful, This Will Remove the Temporary VM...")
|
37 |
|
38 | description := "packer made image"
|
39 | imageFamily := "PackerMade"
|
40 |
|
41 | if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
|
42 | return vmi.NewClient(client).Capture(s.TmpServiceName, s.TmpVmName, s.TmpVmName,
|
43 | s.UserImageName, s.UserImageLabel, vmi.OSStateGeneralized, vmi.CaptureParameters{
|
44 | Description: description,
|
45 | ImageFamily: imageFamily,
|
46 | RecommendedVMSize: s.RecommendedVMSize,
|
47 | })
|
48 | }); err != nil {
|
49 | err := fmt.Errorf(errorMsg, err)
|
50 | state.Put("error", err)
|
51 | ui.Error(err.Error())
|
52 | return multistep.ActionHalt
|
53 | }
|
54 |
|
55 | // CatpureVMImage removes the VM
|
56 | state.Put(constants.ImageCreated, 1)
|
57 | state.Put(constants.VmExists, 0)
|
58 |
|
59 | return multistep.ActionContinue
|
60 | }
|
func StepUploadCertificate.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_upload_certificate.go
:
23 | func (s *StepUploadCertificate) Run(state multistep.StateBag) multistep.StepAction {
|
24 | client := state.Get(constants.RequestManager).(management.Client)
|
25 | ui := state.Get("ui").(packer.Ui)
|
26 | errorMsg := "Error Uploading Temporary Certificate: %s"
|
27 | var err error
|
28 |
|
29 | ui.Say("Uploading Temporary Certificate...")
|
30 |
|
31 | certData := []byte(state.Get(constants.Certificate).(string))
|
32 |
|
33 | if err = retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
|
34 | return hostedservice.NewClient(client).AddCertificate(s.TmpServiceName, certData, hostedservice.CertificateFormatPfx, "")
|
35 | }); err != nil {
|
36 | err := fmt.Errorf(errorMsg, err)
|
37 | state.Put("error", err)
|
38 | ui.Error(err.Error())
|
39 | return multistep.ActionHalt
|
40 | }
|
41 |
|
42 | state.Put(constants.CertUploaded, 1)
|
43 |
|
44 | return multistep.ActionContinue
|
45 | }
|
func StepCreateService.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_service.go
:
25 | func (s *StepCreateService) Run(state multistep.StateBag) multistep.StepAction {
|
26 | client := state.Get(constants.RequestManager).(management.Client)
|
27 | hsc := hostedservice.NewClient(client)
|
28 | ui := state.Get(constants.Ui).(packer.Ui)
|
29 |
|
30 | errorMsg := "Error creating temporary Azure service: %s"
|
31 |
|
32 | ui.Say("Creating temporary Azure service...")
|
33 |
|
34 | if err := hsc.CreateHostedService(hostedservice.CreateHostedServiceParameters{
|
35 | ServiceName: s.TmpServiceName,
|
36 | Location: s.Location,
|
37 | Label: base64.StdEncoding.EncodeToString([]byte(s.TmpServiceName)),
|
38 | }); err != nil {
|
39 | err := fmt.Errorf(errorMsg, err)
|
40 | state.Put("error", err)
|
41 | ui.Error(err.Error())
|
42 | return multistep.ActionHalt
|
43 | }
|
44 |
|
45 | state.Put(constants.SrvExists, 1)
|
46 |
|
47 | return multistep.ActionContinue
|
48 | }
|
func StepStopVm.Run
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_stop_vm.go
:
24 | func (s *StepStopVm) Run(state multistep.StateBag) multistep.StepAction {
|
25 | client := state.Get(constants.RequestManager).(management.Client)
|
26 | ui := state.Get(constants.Ui).(packer.Ui)
|
27 |
|
28 | errorMsg := "Error Stopping Temporary Azure VM: %s"
|
29 |
|
30 | ui.Say("Stopping Temporary Azure VM...")
|
31 |
|
32 | if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
|
33 | return vm.NewClient(client).ShutdownRole(s.TmpServiceName, s.TmpVmName, s.TmpVmName, vm.PostShutdownActionStopped)
|
34 | }); err != nil {
|
35 | err := fmt.Errorf(errorMsg, err)
|
36 | state.Put("error", err)
|
37 | ui.Error(err.Error())
|
38 | return multistep.ActionHalt
|
39 | }
|
40 |
|
41 | state.Put(constants.VmRunning, 0)
|
42 |
|
43 | return multistep.ActionContinue
|
44 | }
|
func GetLoggedClient
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
20 | func GetLoggedClient(client management.Client) management.Client {
|
21 | logLengthStr := os.Getenv(logLengthKey)
|
22 | if logLengthStr == "" {
|
23 | log.Printf("%s %s not set, not logging", logPrefix, logLengthKey)
|
24 | return client
|
25 | }
|
26 | maxlen, err := strconv.ParseInt(logLengthStr, 10, 64)
|
27 | if err != nil {
|
28 | log.Printf("%s WARNING: Found %s in environment, but %s is not an integer?", logPrefix, logLengthKey, logLengthStr)
|
29 | return client
|
30 | }
|
31 |
|
32 | log.Printf("%s Azure requests will be logged", logPrefix)
|
33 |
|
34 | return loggedAzureClient{client, maxlen}
|
35 | }
|
func FindOSImage
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
42 | func FindOSImage(imageList []osi.OSImage, name, label, location string) (osi.OSImage, bool) {
|
43 |
|
44 | imageNameRegexp := GetImageNameRegexp(name)
|
45 | matches := make([]osi.OSImage, 0)
|
46 | for _, im := range imageList {
|
47 | for _, loc := range strings.Split(im.Location, ";") {
|
48 | if loc == location &&
|
49 | (len(label) == 0 || im.Label == label) &&
|
50 | (len(name) == 0 || imageNameRegexp.MatchString(im.Name)) {
|
51 | matches = append(matches, im)
|
52 | }
|
53 | }
|
54 | }
|
55 |
|
56 | if len(matches) > 0 {
|
57 | sort.Sort(osImageByPublishDate(matches))
|
58 | return matches[0], true
|
59 | }
|
60 | return osi.OSImage{}, false
|
61 | }
|
func StepCreateService.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_service.go
:
50 | func (s *StepCreateService) Cleanup(state multistep.StateBag) {
|
51 | client := state.Get(constants.RequestManager).(management.Client)
|
52 | hsc := hostedservice.NewClient(client)
|
53 | ui := state.Get(constants.Ui).(packer.Ui)
|
54 |
|
55 | if res := state.Get(constants.SrvExists).(int); res == 1 {
|
56 | ui.Say("Removing temporary Azure service and its deployments, if any...")
|
57 | errorMsg := "Error removing temporary Azure service: %s"
|
58 |
|
59 | if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
|
60 | return hsc.DeleteHostedService(s.TmpServiceName, true)
|
61 | }); err != nil {
|
62 | ui.Error(fmt.Sprintf(errorMsg, err))
|
63 | return
|
64 | }
|
65 | }
|
66 | }
|
func StepSetProvisionInfrastructure.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_set_provision_infrastructure.go
:
74 | func (s *StepSetProvisionInfrastructure) Cleanup(state multistep.StateBag) {
|
75 | ui := state.Get("ui").(packer.Ui)
|
76 | config := state.Get(constants.Config).(*Config)
|
77 | ui.Say("Cleaning Up Infrastructure for provision...")
|
78 |
|
79 | if s.flagTempContainerCreated {
|
80 | ui.Message("Removing Azure temporary container...")
|
81 |
|
82 | err := config.storageClient.GetBlobService().DeleteContainer(s.TempContainerName)
|
83 | if err != nil {
|
84 | ui.Message("Error removing temporary container: " + err.Error())
|
85 | }
|
86 | }
|
87 | }
|
func @42:12
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
42 | func() error {
|
43 | for _, l := range locationsResponse.Locations {
|
44 | if config.Location == l.Name {
|
45 | ui.Message("Checking instance size availability...")
|
46 | if !func() bool {
|
47 | for _, size := range l.VirtualMachineRoleSizes {
|
48 | if size == config.InstanceSize {
|
49 | return true
|
50 | }
|
51 | }
|
52 | return false
|
53 | }() {
|
54 | sizes := strings.Join(l.VirtualMachineRoleSizes, ",")
|
55 | return fmt.Errorf("Instance size %q not available in location %q for this subscription, valid instance sizes: %s",
|
56 | config.InstanceSize, config.Location, sizes)
|
57 | }
|
58 | return nil
|
59 | }
|
60 | }
|
61 | return fmt.Errorf("Location %q not available for this subscription, valid locations: %s", config.Location, locationsResponse.String())
|
62 | }
|
func getAffinityGroupLocation
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
318 | func getAffinityGroupLocation(client management.Client, affinityGroup string) (string, error) {
|
319 | const getAffinityGroupProperties = "affinitygroups/%s"
|
320 | d, err := client.SendAzureGetRequest(fmt.Sprintf(getAffinityGroupProperties, affinityGroup))
|
321 | if err != nil {
|
322 | return "", err
|
323 | }
|
324 |
|
325 | var afGroup struct {
|
326 | Location string
|
327 | }
|
328 | err = xml.Unmarshal(d, &afGroup)
|
329 |
|
330 | return afGroup.Location, err
|
331 | }
|
func loggedAzureClient.SendAzurePostRequest
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
78 | func (c loggedAzureClient) SendAzurePostRequest(url string, data []byte) (management.OperationID, error) {
|
79 | oid, err := c.Client.SendAzurePostRequest(url, data)
|
80 | c.logRequest("POST", url, err)
|
81 | c.logRequestBody(data)
|
82 | c.logOperationID(oid)
|
83 | return oid, err
|
84 | }
|
func loggedAzureClient.SendAzurePutRequest
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
86 | func (c loggedAzureClient) SendAzurePutRequest(url, contentType string, data []byte) (management.OperationID, error) {
|
87 | oid, err := c.Client.SendAzurePutRequest(url, contentType, data)
|
88 | c.logRequest("PUT", url, err)
|
89 | c.logRequestBody(data)
|
90 | c.logOperationID(oid)
|
91 | return oid, err
|
92 | }
|
func Builder.Prepare
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/builder.go
:
31 | func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
32 | c, warnings, errs := newConfig(raws...)
|
33 | if errs != nil {
|
34 | return warnings, errs
|
35 | }
|
36 | b.config = c
|
37 |
|
38 | return warnings, nil
|
39 | }
|
func loggedAzureClient.WaitForOperation
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
106 | func (c loggedAzureClient) WaitForOperation(operationID management.OperationID, cancel chan struct{}) error {
|
107 | log.Printf("%s WaitForOperation( %s ) - begin", logPrefix, operationID)
|
108 | start := time.Now()
|
109 | err := c.Client.WaitForOperation(operationID, cancel)
|
110 | log.Printf("%s WaitForOperation( %s ) - end, duration: %v, err: %v", logPrefix, operationID, time.Now().Sub(start), err)
|
111 | return err
|
112 | }
|
func loggedAzureClient.chop
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
59 | func (c loggedAzureClient) chop(data []byte) string {
|
60 | s := string(data)
|
61 | if int64(len(s)) > c.maxlen {
|
62 | s = s[:c.maxlen-3] + "..."
|
63 | }
|
64 | return s
|
65 | }
|
func @46:9
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
46 | func() bool {
|
47 | for _, size := range l.VirtualMachineRoleSizes {
|
48 | if size == config.InstanceSize {
|
49 | return true
|
50 | }
|
51 | }
|
52 | return false
|
53 | }
|
func loggedAzureClient.SendAzureGetRequest
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
71 | func (c loggedAzureClient) SendAzureGetRequest(url string) ([]byte, error) {
|
72 | d, err := c.Client.SendAzureGetRequest(url)
|
73 | c.logRequest("GET", url, err)
|
74 | c.logResponseBody(d)
|
75 | return d, err
|
76 | }
|
func loggedAzureClient.SendAzureDeleteRequest
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
94 | func (c loggedAzureClient) SendAzureDeleteRequest(url string) (management.OperationID, error) {
|
95 | oid, err := c.Client.SendAzureDeleteRequest(url)
|
96 | c.logRequest("DELETE", url, err)
|
97 | c.logOperationID(oid)
|
98 | return oid, err
|
99 | }
|
func loggedAzureClient.logRequest
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
42 | func (loggedAzureClient) logRequest(method, url string, err error) {
|
43 | if err == nil {
|
44 | log.Printf("%s %s %s", logPrefix, method, url)
|
45 | } else {
|
46 | // keep lines together
|
47 | log.Printf("%s %s %s\n%s ERROR: %v", logPrefix, method, url, logPrefix, err)
|
48 | }
|
49 | }
|
func Builder.Cancel
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/builder.go
:
207 | func (b *Builder) Cancel() {
|
208 | if b.runner != nil {
|
209 | log.Println("Cancelling the step runner...")
|
210 | b.runner.Cancel()
|
211 | }
|
212 | }
|
func @41:48
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_image.go
:
41 | func() (management.OperationID, error) {
|
42 | return vmi.NewClient(client).Capture(s.TmpServiceName, s.TmpVmName, s.TmpVmName,
|
43 | s.UserImageName, s.UserImageLabel, vmi.OSStateGeneralized, vmi.CaptureParameters{
|
44 | Description: description,
|
45 | ImageFamily: imageFamily,
|
46 | RecommendedVMSize: s.RecommendedVMSize,
|
47 | })
|
48 | }
|
func @59:49
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_service.go
:
59 | func() (management.OperationID, error) {
|
60 | return hsc.DeleteHostedService(s.TmpServiceName, true)
|
61 | }
|
func loggedAzureClient.logOperationID
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
67 | func (c loggedAzureClient) logOperationID(oid management.OperationID) {
|
68 | log.Printf("%s <<< operation id: %s", logPrefix, oid)
|
69 | }
|
func @37:48
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_vm.go
:
37 | func() (management.OperationID, error) {
|
38 | return vm.NewClient(client).CreateDeployment(*role, config.tmpServiceName, options)
|
39 | }
|
func vmImageByPublishDate.Swap
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
39 | func (a vmImageByPublishDate) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func loggedAzureClient.logRequestBody
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
51 | func (c loggedAzureClient) logRequestBody(data []byte) {
|
52 | log.Printf("%s >>> %s", logPrefix, c.chop(data))
|
53 | }
|
func osImageByPublishDate.Len
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
65 | func (a osImageByPublishDate) Len() int { return len(a) }
|
func @89:41
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_image.go
:
89 | func(err management.AzureError) bool {
|
90 | return strings.Contains(err.Message, "is currently performing an operation on deployment") ||
|
91 | strings.Contains(err.Message, "is currently in use by virtual machine")
|
92 | }
|
func @87:37
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_image.go
:
87 | func() error {
|
88 | return vmdisk.NewClient(client).DeleteDisk(diskName, true)
|
89 | }
|
func artifact.Destroy
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
57 | func (a *artifact) Destroy() error {
|
58 |
|
59 | // TODO: remove image and vhd
|
60 | return nil
|
61 | }
|
func @32:48
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_stop_vm.go
:
32 | func() (management.OperationID, error) {
|
33 | return vm.NewClient(client).ShutdownRole(s.TmpServiceName, s.TmpVmName, s.TmpVmName, vm.PostShutdownActionStopped)
|
34 | }
|
func loggedAzureClient.logResponseBody
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/requestlogger.go
:
55 | func (c loggedAzureClient) logResponseBody(data []byte) {
|
56 | log.Printf("%s <<< %s", logPrefix, c.chop(data))
|
57 | }
|
func artifact.String
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
49 | func (a *artifact) String() string {
|
50 | return fmt.Sprintf("{%s,%s,%s}",
|
51 | fmt.Sprintf("\"imageLabel\": \"%s\"", a.imageLabel),
|
52 | fmt.Sprintf("\"imageName\": \"%s\"", a.imageName),
|
53 | fmt.Sprintf("\"mediaLocation\": \"%s\"", a.mediaLocation),
|
54 | )
|
55 | }
|
func @33:47
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_upload_certificate.go
:
33 | func() (management.OperationID, error) {
|
34 | return hostedservice.NewClient(client).AddCertificate(s.TmpServiceName, certData, hostedservice.CertificateFormatPfx, "")
|
35 | }
|
func osImageByPublishDate.Less
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
67 | func (a osImageByPublishDate) Less(i, j int) bool { return a[i].PublishedDate > a[j].PublishedDate }
|
func artifact.Id
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
32 | func (a *artifact) Id() string {
|
33 | return a.imageName
|
34 | }
|
func artifact.Files
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/artifact.go
:
28 | func (a *artifact) Files() []string {
|
29 | return nil
|
30 | }
|
func osImageByPublishDate.Swap
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/FindImage.go
:
66 | func (a osImageByPublishDate) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func StepUploadCertificate.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_upload_certificate.go
:
47 | func (s *StepUploadCertificate) Cleanup(state multistep.StateBag) {
|
48 | // do nothing
|
49 | }
|
func StepValidate.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_validate.go
:
229 | func (*StepValidate) Cleanup(multistep.StateBag) {}
|
func StepPollStatus.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_poll_status.go
:
136 | func (s *StepPollStatus) Cleanup(state multistep.StateBag) {
|
137 | // nothing to do
|
138 | }
|
func StepCreateVm.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_create_vm.go
:
52 | func (*StepCreateVm) Cleanup(multistep.StateBag) {}
|
func StepStopVm.Cleanup
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/step_stop_vm.go
:
46 | func (s *StepStopVm) Cleanup(state multistep.StateBag) {
|
47 | // do nothing
|
48 | }
|
Package Overview: github.com/Azure/packer-azure/packer/builder/azure/smapi/retry 18.18%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/builder/azure/smapi/retry
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/builder/azure/smapi/retry | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
ConstantBackoffRule(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 100.00% | 3/3 |
newRetryRuleConflictInUse(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 100.00% | 1/1 |
@87:47(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 100.00% | 1/1 |
@29:9(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 71.43% | 5/7 |
ExecuteAsyncOperation(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go | 0.00% | 0/17 |
@47:9(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/11 |
retryPolicy.ShouldRetry(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/4 |
ExponentialBackoffRule(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/4 |
@52:36(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go | 0.00% | 0/1 |
newRetryRuleThrottling(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/1 |
@75:46(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/1 |
newRetryRuleInternalError(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/1 |
@81:46(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/1 |
ExecuteOperation(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go | 0.00% | 0/1 |
newDefaultRetryPolicy(...) | github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go | 0.00% | 0/1 |
github.com/Azure/packer-azure/packer/builder/azure/smapi/retry | 18.18% | 10/55 |
func ConstantBackoffRule
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
26 | func ConstantBackoffRule(name string, match matchRule, backoff time.Duration, maxRetries int) RetryRule {
|
27 | indefinitely := maxRetries == 0
|
28 | retries := 0
|
29 | return func(err management.AzureError) (bool, time.Duration) {
|
30 | if match(err) {
|
31 | if indefinitely || retries < maxRetries {
|
32 | retries++
|
33 | log.Printf("Retry %d for rule '%s' with %v backoff", retries, name, backoff)
|
34 | return true, backoff
|
35 | } else {
|
36 | log.Printf("Retries for rule '%s' exhausted (%d)", name, retries)
|
37 | }
|
38 | }
|
39 | return false, 0
|
40 | }
|
41 | }
|
func newRetryRuleConflictInUse
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
86 | func newRetryRuleConflictInUse() RetryRule {
|
87 | return ConstantBackoffRule("Conflict/InUse", func(err management.AzureError) bool {
|
88 | return (err.Code == "BadRequest" && strings.Contains(err.Message, "is currently in use by")) ||
|
89 | (err.Code == "ConflictError" && strings.Contains(err.Message, "that requires exclusive access"))
|
90 | }, 10*time.Second, 100)
|
91 | }
|
func @87:47
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
87 | func(err management.AzureError) bool {
|
88 | return (err.Code == "BadRequest" && strings.Contains(err.Message, "is currently in use by")) ||
|
89 | (err.Code == "ConflictError" && strings.Contains(err.Message, "that requires exclusive access"))
|
90 | }
|
func @29:9
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
29 | func(err management.AzureError) (bool, time.Duration) {
|
30 | if match(err) {
|
31 | if indefinitely || retries < maxRetries {
|
32 | retries++
|
33 | log.Printf("Retry %d for rule '%s' with %v backoff", retries, name, backoff)
|
34 | return true, backoff
|
35 | } else {
|
36 | log.Printf("Retries for rule '%s' exhausted (%d)", name, retries)
|
37 | }
|
38 | }
|
39 | return false, 0
|
40 | }
|
func ExecuteAsyncOperation
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go
:
16 | func ExecuteAsyncOperation(client management.Client, asyncOperation func() (management.OperationID, error), extraRules ...RetryRule) error {
|
17 | if asyncOperation == nil {
|
18 | return fmt.Errorf("Parameter not specified: %s", "asyncOperation")
|
19 | }
|
20 |
|
21 | retryPolicy := append(newDefaultRetryPolicy(), extraRules...)
|
22 |
|
23 | for { // retry loop for azure errors, call continue for retryable errors
|
24 |
|
25 | operationId, err := asyncOperation()
|
26 | if err == nil && operationId != "" {
|
27 | log.Printf("Waiting for operation: %s", operationId)
|
28 | err = client.WaitForOperation(operationId, nil)
|
29 | }
|
30 | if err != nil {
|
31 | log.Printf("Caught error (%T) during retryable operation: %v", err, err)
|
32 | // need to remove the pointer receiver in Azure SDK to make these *'s go away
|
33 | if azureError, ok := err.(management.AzureError); ok {
|
34 | log.Printf("Error is Azure error, checking if we should retry...")
|
35 | if shouldRetry, backoff := retryPolicy.ShouldRetry(azureError); shouldRetry {
|
36 | log.Printf("Error needs to be retried, sleeping %v", backoff)
|
37 | time.Sleep(backoff)
|
38 | continue // retry asyncOperation
|
39 | }
|
40 | }
|
41 | }
|
42 | return err
|
43 | }
|
44 | }
|
func @47:9
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
47 | func(err management.AzureError) (bool, time.Duration) {
|
48 | if match(err) {
|
49 | if indefinitely || retries < maxRetries {
|
50 | retries++
|
51 | thisBackoff := backoff
|
52 | backoff *= 2
|
53 | if backoff > maximumBackoff {
|
54 | backoff = maximumBackoff
|
55 | }
|
56 | log.Printf("Retry %d for rule '%s' with %v backoff", retries, name, thisBackoff)
|
57 | return true, thisBackoff
|
58 | } else {
|
59 | log.Printf("Retries for rule '%s' exhausted (%d)", name, retries)
|
60 | }
|
61 | }
|
62 | return false, 0
|
63 | }
|
func retryPolicy.ShouldRetry
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
17 | func (rules retryPolicy) ShouldRetry(err management.AzureError) (bool, time.Duration) {
|
18 | for _, rule := range rules {
|
19 | if shouldRetry, backoff := rule(err); shouldRetry {
|
20 | return shouldRetry, backoff
|
21 | }
|
22 | }
|
23 | return false, 0
|
24 | }
|
func ExponentialBackoffRule
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
43 | func ExponentialBackoffRule(name string, match matchRule, initialBackoff time.Duration, maximumBackoff time.Duration, maxRetries int) RetryRule {
|
44 | indefinitely := maxRetries == 0
|
45 | retries := 0
|
46 | backoff := initialBackoff
|
47 | return func(err management.AzureError) (bool, time.Duration) {
|
48 | if match(err) {
|
49 | if indefinitely || retries < maxRetries {
|
50 | retries++
|
51 | thisBackoff := backoff
|
52 | backoff *= 2
|
53 | if backoff > maximumBackoff {
|
54 | backoff = maximumBackoff
|
55 | }
|
56 | log.Printf("Retry %d for rule '%s' with %v backoff", retries, name, thisBackoff)
|
57 | return true, thisBackoff
|
58 | } else {
|
59 | log.Printf("Retries for rule '%s' exhausted (%d)", name, retries)
|
60 | }
|
61 | }
|
62 | return false, 0
|
63 | }
|
64 | }
|
func @52:36
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go
:
52 | func() (management.OperationID, error) { return "", syncOperation() }
|
func newRetryRuleThrottling
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
74 | func newRetryRuleThrottling() RetryRule {
|
75 | return ExponentialBackoffRule("Throttling", func(err management.AzureError) bool {
|
76 | return err.Code == "TooManyRequests"
|
77 | }, 5*time.Second, 2*time.Minute, 0)
|
78 | }
|
func @75:46
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
75 | func(err management.AzureError) bool {
|
76 | return err.Code == "TooManyRequests"
|
77 | }
|
func newRetryRuleInternalError
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
80 | func newRetryRuleInternalError() RetryRule {
|
81 | return ConstantBackoffRule("InternalError", func(err management.AzureError) bool {
|
82 | return err.Code == "InternalError"
|
83 | }, 10*time.Second, 100)
|
84 | }
|
func @81:46
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
81 | func(err management.AzureError) bool {
|
82 | return err.Code == "InternalError"
|
83 | }
|
func ExecuteOperation
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/operations.go
:
51 | func ExecuteOperation(syncOperation func() error, extraRules ...RetryRule) error {
|
52 | return ExecuteAsyncOperation(nil, func() (management.OperationID, error) { return "", syncOperation() }, extraRules...)
|
53 | }
|
func newDefaultRetryPolicy
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/builder/azure/smapi/retry/retrypolicy.go
:
66 | func newDefaultRetryPolicy() retryPolicy {
|
67 | return retryPolicy{
|
68 | newRetryRuleThrottling(),
|
69 | newRetryRuleInternalError(),
|
70 | newRetryRuleConflictInUse(),
|
71 | }
|
72 | }
|
Package Overview: github.com/Azure/packer-azure/packer/plugin/packer-builder-azure 0.00%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/plugin/packer-builder-azure
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/plugin/packer-builder-azure | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
main(...) | github.com/Azure/packer-azure/packer/plugin/packer-builder-azure/main.go | 0.00% | 0/5 |
github.com/Azure/packer-azure/packer/plugin/packer-builder-azure | 0.00% | 0/5 |
func main
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/plugin/packer-builder-azure/main.go
:
11 | func main() {
|
12 | server, err := plugin.Server()
|
13 | if err != nil {
|
14 | panic(err)
|
15 | }
|
16 | server.RegisterBuilder(new(azure.Builder))
|
17 | server.Serve()
|
18 | }
|
Package Overview: github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure 0.00%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
main(...) | github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure/main.go | 0.00% | 0/5 |
github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure | 0.00% | 0/5 |
func main
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/plugin/packer-provisioner-powershell-azure/main.go
:
11 | func main() {
|
12 | server, err := plugin.Server()
|
13 | if err != nil {
|
14 | panic(err)
|
15 | }
|
16 | server.RegisterProvisioner(new(powershell.Provisioner))
|
17 | server.Serve()
|
18 | }
|
Package Overview: github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly 17.65%
This is a coverage report created after analysis of the github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly
package. It
has been generated with the following command:
gocov test github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly | gocov-html
Here are the stats. Please select a function name to view its implementation and see what's left for testing.
func PostProcessor.PostProcess
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
31 | func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact /*keep*/, bool, error) {
|
32 | ui.Say("Validating artifact")
|
33 | if artifact.BuilderId() != azure.BuilderId {
|
34 | return nil, false, fmt.Errorf(
|
35 | "Unknown artifact type: %s\nCan only import from Azure builder artifacts (%s).",
|
36 | artifact.BuilderId(), azure.BuilderId)
|
37 | }
|
38 |
|
39 | publishSettingsPath, ok := artifact.State("publishSettingsPath").(string)
|
40 | if !ok || publishSettingsPath == "" {
|
41 | return nil, false, fmt.Errorf(stateError, "publishSettingsPath")
|
42 | }
|
43 | subscriptionID, ok := artifact.State("subscriptionID").(string)
|
44 | if !ok || subscriptionID == "" {
|
45 | return nil, false, fmt.Errorf(stateError, "subscriptionID")
|
46 | }
|
47 |
|
48 | name := artifact.Id()
|
49 |
|
50 | ui.Message("Creating Azure Service Management client...")
|
51 | client, err := management.ClientFromPublishSettingsFile(publishSettingsPath, subscriptionID)
|
52 | if err != nil {
|
53 | return nil, false, fmt.Errorf("Error creating new Azure client: %v", err)
|
54 | }
|
55 | client = azure.GetLoggedClient(client)
|
56 | vmic := virtualmachineimage.NewClient(client)
|
57 |
|
58 | ui.Message("Retrieving VM image...")
|
59 | var image virtualmachineimage.VMImage
|
60 | if err = retry.ExecuteOperation(func() error {
|
61 | imageList, err := vmic.ListVirtualMachineImages(
|
62 | virtualmachineimage.ListParameters{
|
63 | Category: virtualmachineimage.CategoryUser,
|
64 | })
|
65 | if err != nil {
|
66 | return err
|
67 | }
|
68 |
|
69 | for _, i := range imageList.VMImages {
|
70 | if i.Name == name {
|
71 | image = i
|
72 | break
|
73 | }
|
74 | }
|
75 | return nil
|
76 | }); err != nil {
|
77 | log.Printf("VM image client returned error: %s", err)
|
78 | return nil, false, err
|
79 | }
|
80 | if image.Name != name {
|
81 | return nil, false, fmt.Errorf("Could not find image: %s", name)
|
82 | }
|
83 |
|
84 | ui.Message(fmt.Sprintf("Deleting VM image (keeping VHDs) %s: %s...", image.Name, image.Label))
|
85 | err = retry.ExecuteOperation(func() error { return vmic.DeleteVirtualMachineImage(image.Name, false) })
|
86 | if err != nil {
|
87 | log.Printf("Error deleting VM image: %s", err)
|
88 | return nil, false, err
|
89 | }
|
90 |
|
91 | blobs := VMBlobListArtifact{
|
92 | OSDisk: image.OSDiskConfiguration.MediaLink,
|
93 | DataDisks: make([]string, len(image.DataDiskConfigurations))}
|
94 |
|
95 | for i, ddc := range image.DataDiskConfigurations {
|
96 | blobs.DataDisks[i] = ddc.MediaLink
|
97 | }
|
98 |
|
99 | return blobs, false, nil
|
100 | }
|
func @60:34
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
60 | func() error {
|
61 | imageList, err := vmic.ListVirtualMachineImages(
|
62 | virtualmachineimage.ListParameters{
|
63 | Category: virtualmachineimage.CategoryUser,
|
64 | })
|
65 | if err != nil {
|
66 | return err
|
67 | }
|
68 |
|
69 | for _, i := range imageList.VMImages {
|
70 | if i.Name == name {
|
71 | image = i
|
72 | break
|
73 | }
|
74 | }
|
75 | return nil
|
76 | }
|
func VMBlobListArtifact.String
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
116 | func (a VMBlobListArtifact) String() string {
|
117 | d, err := json.Marshal(&a)
|
118 | if err != nil {
|
119 | return fmt.Sprintf("Error: %v", err)
|
120 | }
|
121 | return string(d)
|
122 | }
|
func PostProcessor.Configure
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
27 | func (p *PostProcessor) Configure(raws ...interface{}) error {
|
28 | return nil
|
29 | }
|
func VMBlobListArtifact.BuilderId
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
109 | func (VMBlobListArtifact) BuilderId() string { return BuilderID }
|
func VMBlobListArtifact.Destroy
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
110 | func (VMBlobListArtifact) Destroy() error { return nil }
|
func VMBlobListArtifact.Files
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
111 | func (VMBlobListArtifact) Files() []string { return nil }
|
func VMBlobListArtifact.Id
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
112 | func (a VMBlobListArtifact) Id() string {
|
113 | return fmt.Sprintf("%x", md5.Sum([]byte(a.String())))
|
114 | }
|
func VMBlobListArtifact.State
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
115 | func (VMBlobListArtifact) State(string) interface{} { return nil }
|
func @85:31
BackIn /home/travis/gopath/src/github.com/Azure/packer-azure/packer/post-processor/azure-sm-vhdonly/post-processor.go
:
85 | func() error { return vmic.DeleteVirtualMachineImage(image.Name, false) }
|