This repository has been archived by the owner on Feb 13, 2021. It is now read-only.
/
step_create_image.go
executable file
·101 lines (80 loc) · 3.02 KB
/
step_create_image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See the LICENSE file in the project root for license information.
package azure
import (
"fmt"
"strings"
"time"
"github.com/Azure/packer-azure/packer/builder/azure/common/constants"
"github.com/Azure/packer-azure/packer/builder/azure/smapi/retry"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/Azure/azure-sdk-for-go/management"
vmdisk "github.com/Azure/azure-sdk-for-go/management/virtualmachinedisk"
vmi "github.com/Azure/azure-sdk-for-go/management/virtualmachineimage"
)
type StepCreateImage struct {
TmpServiceName string
TmpVmName string
UserImageLabel string
UserImageName string
RecommendedVMSize string
}
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
}
func (s *StepCreateImage) Cleanup(state multistep.StateBag) {
client := state.Get(constants.RequestManager).(management.Client)
ui := state.Get(constants.Ui).(packer.Ui)
var err error
var res int
if res = state.Get(constants.VmExists).(int); res == 1 { //VM was not removed at image creation step
return
}
// Since VM was successfully removed - remove it's media as well
if res = state.Get(constants.DiskExists).(int); res == 1 {
ui.Message("Removing Temporary Azure Disk...")
errorMsg := "Error Removing Temporary Azure Disk: %s"
diskName, ok := state.Get(constants.HardDiskName).(string)
if ok {
if len(diskName) == 0 {
err := fmt.Errorf(errorMsg, err)
ui.Error(err.Error())
return
}
if err := retry.ExecuteOperation(func() error {
return vmdisk.NewClient(client).DeleteDisk(diskName, true)
}, retry.ConstantBackoffRule("busy", func(err management.AzureError) bool {
return strings.Contains(err.Message, "is currently performing an operation on deployment") ||
strings.Contains(err.Message, "is currently in use by virtual machine")
}, 30*time.Second, 10)); err != nil {
err := fmt.Errorf(errorMsg, err)
ui.Error(err.Error())
return
}
state.Put(constants.DiskExists, 0)
}
}
}