Make PIR images work
This commit is contained in:
parent
b5401d552a
commit
bbac79f0a4
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Azure/go-autorest/autorest/azure"
|
"github.com/Azure/go-autorest/autorest/azure"
|
||||||
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -26,7 +27,8 @@ type Config struct {
|
||||||
|
|
||||||
ClientConfig client.Config `mapstructure:",squash"`
|
ClientConfig client.Config `mapstructure:",squash"`
|
||||||
|
|
||||||
FromScratch bool `mapstructure:"from_scratch"`
|
FromScratch bool `mapstructure:"from_scratch"`
|
||||||
|
Source string `mapstructure:"source"`
|
||||||
|
|
||||||
CommandWrapper string `mapstructure:"command_wrapper"`
|
CommandWrapper string `mapstructure:"command_wrapper"`
|
||||||
PreMountCommands []string `mapstructure:"pre_mount_commands"`
|
PreMountCommands []string `mapstructure:"pre_mount_commands"`
|
||||||
|
@ -75,6 +77,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
},
|
},
|
||||||
}, raws...)
|
}, raws...)
|
||||||
|
|
||||||
|
var errs *packer.MultiError
|
||||||
|
var warns []string
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
err = b.config.ClientConfig.SetDefaultValues()
|
err = b.config.ClientConfig.SetDefaultValues()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,7 +120,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.TemporaryOSDiskName == "" {
|
if b.config.TemporaryOSDiskName == "" {
|
||||||
b.config.TemporaryOSDiskName = "PackerTemp-{{timestamp}}"
|
|
||||||
|
if def, err := interpolate.Render("PackerTemp-{{timestamp}}", &b.config.ctx); err == nil {
|
||||||
|
b.config.TemporaryOSDiskName = def
|
||||||
|
} else {
|
||||||
|
errs = packer.MultiErrorAppend(errs, fmt.Errorf("unable to render temporary disk name: %s", err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.OSDiskStorageAccountType == "" {
|
if b.config.OSDiskStorageAccountType == "" {
|
||||||
|
@ -135,10 +145,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks, accumulate any errors or warnings
|
// checks, accumulate any errors or warnings
|
||||||
var errs *packer.MultiError
|
|
||||||
var warns []string
|
|
||||||
|
|
||||||
if b.config.FromScratch {
|
if b.config.FromScratch {
|
||||||
|
if b.config.Source != "" {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, errors.New("source cannot be specified when building from_scratch"))
|
||||||
|
}
|
||||||
if b.config.OSDiskSizeGB == 0 {
|
if b.config.OSDiskSizeGB == 0 {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, errors.New("os_disk_size_gb is required with from_scratch"))
|
errs, errors.New("os_disk_size_gb is required with from_scratch"))
|
||||||
|
@ -148,7 +160,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs, errors.New("pre_mount_commands is required with from_scratch"))
|
errs, errors.New("pre_mount_commands is required with from_scratch"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errs = packer.MultiErrorAppend(errors.New("only 'from_scratch'=true is supported right now"))
|
if _, err := client.ParsePlatformImageURN(b.config.Source); err == nil {
|
||||||
|
log.Println("Source is platform image:", b.config.Source)
|
||||||
|
} else {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, fmt.Errorf("source: %q is not a valid platform image specifier", b.config.Source))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkDiskCacheType(b.config.OSDiskCacheType); err != nil {
|
if err := checkDiskCacheType(b.config.OSDiskCacheType); err != nil {
|
||||||
|
@ -271,10 +288,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
// Build the steps
|
// Build the steps
|
||||||
var steps []multistep.Step
|
var steps []multistep.Step
|
||||||
|
|
||||||
if !b.config.FromScratch {
|
if b.config.FromScratch {
|
||||||
panic("Only from_scratch is currently implemented")
|
|
||||||
// create disk from PIR / managed image (warn on non-linux images)
|
|
||||||
} else {
|
|
||||||
steps = append(steps,
|
steps = append(steps,
|
||||||
&StepCreateNewDisk{
|
&StepCreateNewDisk{
|
||||||
SubscriptionID: info.SubscriptionID,
|
SubscriptionID: info.SubscriptionID,
|
||||||
|
@ -285,6 +299,31 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
HyperVGeneration: b.config.ImageHyperVGeneration,
|
HyperVGeneration: b.config.ImageHyperVGeneration,
|
||||||
Location: info.Location,
|
Location: info.Location,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
if pi, err := client.ParsePlatformImageURN(b.config.Source); err == nil {
|
||||||
|
if strings.EqualFold(pi.Version, "latest") {
|
||||||
|
|
||||||
|
vmi, err := azcli.VirtualMachineImagesClient().GetLatest(ctx, pi.Publisher, pi.Offer, pi.Sku, info.Location)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error retieving latest version of %q: %v", b.config.Source, err)
|
||||||
|
}
|
||||||
|
pi.Version = to.String(vmi.Name)
|
||||||
|
log.Println("Resolved latest version of source image:", pi.Version)
|
||||||
|
}
|
||||||
|
steps = append(steps,
|
||||||
|
&StepCreateNewDisk{
|
||||||
|
SubscriptionID: info.SubscriptionID,
|
||||||
|
ResourceGroup: info.ResourceGroupName,
|
||||||
|
DiskName: b.config.TemporaryOSDiskName,
|
||||||
|
DiskSizeGB: b.config.OSDiskSizeGB,
|
||||||
|
DiskStorageAccountType: b.config.OSDiskStorageAccountType,
|
||||||
|
HyperVGeneration: b.config.ImageHyperVGeneration,
|
||||||
|
Location: info.Location,
|
||||||
|
PlatformImage: pi,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
panic("Unknown image source: " + b.config.Source)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
steps = append(steps,
|
steps = append(steps,
|
||||||
|
|
|
@ -51,9 +51,12 @@ func (s *StepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
||||||
StorageProfile: &compute.ImageStorageProfile{
|
StorageProfile: &compute.ImageStorageProfile{
|
||||||
OsDisk: &compute.ImageOSDisk{
|
OsDisk: &compute.ImageOSDisk{
|
||||||
OsState: compute.OperatingSystemStateTypes(s.ImageOSState),
|
OsState: compute.OperatingSystemStateTypes(s.ImageOSState),
|
||||||
|
OsType: compute.Linux,
|
||||||
ManagedDisk: &compute.SubResource{
|
ManagedDisk: &compute.SubResource{
|
||||||
ID: &diskResourceID,
|
ID: &diskResourceID,
|
||||||
},
|
},
|
||||||
|
StorageAccountType: compute.StorageAccountTypes(s.OSDiskStorageAccountType),
|
||||||
|
Caching: compute.CachingTypes(s.OSDiskCacheType),
|
||||||
},
|
},
|
||||||
// DataDisks: nil,
|
// DataDisks: nil,
|
||||||
// ZoneResilient: nil,
|
// ZoneResilient: nil,
|
||||||
|
|
|
@ -20,6 +20,7 @@ type StepCreateNewDisk struct {
|
||||||
DiskStorageAccountType string // from compute.DiskStorageAccountTypes
|
DiskStorageAccountType string // from compute.DiskStorageAccountTypes
|
||||||
HyperVGeneration string
|
HyperVGeneration string
|
||||||
Location string
|
Location string
|
||||||
|
PlatformImage *client.PlatformImage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StepCreateNewDisk) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
func (s StepCreateNewDisk) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
@ -42,10 +43,8 @@ func (s StepCreateNewDisk) Run(ctx context.Context, state multistep.StateBag) mu
|
||||||
DiskProperties: &compute.DiskProperties{
|
DiskProperties: &compute.DiskProperties{
|
||||||
OsType: "Linux",
|
OsType: "Linux",
|
||||||
HyperVGeneration: compute.HyperVGeneration(s.HyperVGeneration),
|
HyperVGeneration: compute.HyperVGeneration(s.HyperVGeneration),
|
||||||
CreationData: &compute.CreationData{
|
CreationData: &compute.CreationData{},
|
||||||
CreateOption: compute.Empty,
|
DiskSizeGB: to.Int32Ptr(s.DiskSizeGB),
|
||||||
},
|
|
||||||
DiskSizeGB: to.Int32Ptr(s.DiskSizeGB),
|
|
||||||
},
|
},
|
||||||
//Tags: map[string]*string{
|
//Tags: map[string]*string{
|
||||||
}
|
}
|
||||||
|
@ -54,6 +53,17 @@ func (s StepCreateNewDisk) Run(ctx context.Context, state multistep.StateBag) mu
|
||||||
disk.DiskProperties.DiskSizeGB = to.Int32Ptr(s.DiskSizeGB)
|
disk.DiskProperties.DiskSizeGB = to.Int32Ptr(s.DiskSizeGB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.PlatformImage == nil {
|
||||||
|
disk.CreationData.CreateOption = compute.Empty
|
||||||
|
} else {
|
||||||
|
disk.CreationData.CreateOption = compute.FromImage
|
||||||
|
disk.CreationData.ImageReference = &compute.ImageDiskReference{
|
||||||
|
ID: to.StringPtr(fmt.Sprintf(
|
||||||
|
"/subscriptions/%s/providers/Microsoft.Compute/locations/%s/publishers/%s/artifacttypes/vmimage/offers/%s/skus/%s/versions/%s",
|
||||||
|
s.SubscriptionID, s.Location, s.PlatformImage.Publisher, s.PlatformImage.Offer, s.PlatformImage.Sku, s.PlatformImage.Version)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f, err := azcli.DisksClient().CreateOrUpdate(ctx, s.ResourceGroup, s.DiskName, disk)
|
f, err := azcli.DisksClient().CreateOrUpdate(ctx, s.ResourceGroup, s.DiskName, disk)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = f.WaitForCompletionRef(ctx, azcli.PollClient())
|
err = f.WaitForCompletionRef(ctx, azcli.PollClient())
|
||||||
|
|
Loading…
Reference in New Issue