Skip to content

Commit

Permalink
feat: support skipping image creation
Browse files Browse the repository at this point in the history
Adds the config option `skip_create_image` to the builders to support
skipping image creation.

Fixes: #180
  • Loading branch information
jkoelker committed Feb 20, 2022
1 parent 379c14b commit 0fea610
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 21 deletions.
12 changes: 8 additions & 4 deletions builder/azure/arm/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
NewStepPowerOffCompute(azureClient, ui),
NewStepSnapshotOSDisk(azureClient, ui, &b.config),
NewStepSnapshotDataDisks(azureClient, ui, &b.config),
NewStepCaptureImage(azureClient, ui),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
}
} else if b.config.OSType == constants.Target_Windows {
steps = []multistep.Step{
Expand Down Expand Up @@ -278,13 +276,19 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
NewStepPowerOffCompute(azureClient, ui),
NewStepSnapshotOSDisk(azureClient, ui, &b.config),
NewStepSnapshotDataDisks(azureClient, ui, &b.config),
NewStepCaptureImage(azureClient, ui),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
)
} else {
return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType)
}

captureSteps := b.config.CaptureSteps(
ui.Say,
NewStepCaptureImage(azureClient, ui),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
)

steps = append(steps, captureSteps...)

if b.config.PackerDebug {
ui.Message(fmt.Sprintf("temp admin user: '%s'", b.config.UserName))
ui.Message(fmt.Sprintf("temp admin password: '%s'", b.config.Password))
Expand Down
2 changes: 2 additions & 0 deletions builder/azure/arm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ type SharedImageGalleryDestination struct {
type Config struct {
common.PackerConfig `mapstructure:",squash"`

azcommon.Config `mapstructure:",squash"`

// Authentication via OAUTH
ClientConfig client.Config `mapstructure:",squash"`

Expand Down
2 changes: 2 additions & 0 deletions builder/azure/arm/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 28 additions & 10 deletions builder/azure/chroot/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const BuilderID = "azure.chroot"
type Config struct {
common.PackerConfig `mapstructure:",squash"`

azcommon.Config `mapstructure:",squash"`

ClientConfig client.Config `mapstructure:",squash"`

// When set to `true`, starts with an empty, unpartitioned disk. Defaults to `false`.
Expand Down Expand Up @@ -441,7 +443,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
state.Put("instance", info)

// Build the step array from the config
steps := buildsteps(b.config, info, &generatedData)
steps := buildsteps(b.config, info, &generatedData, ui.Say)

// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
Expand Down Expand Up @@ -480,7 +482,12 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
return artifact, nil
}

func buildsteps(config Config, info *client.ComputeInfo, generatedData *packerbuilderdata.GeneratedData) []multistep.Step {
func buildsteps(
config Config,
info *client.ComputeInfo,
generatedData *packerbuilderdata.GeneratedData,
say func(string),
) []multistep.Step {
// Build the steps
var steps []multistep.Step
addSteps := func(s ...multistep.Step) { // convenience function
Expand Down Expand Up @@ -615,23 +622,32 @@ func buildsteps(config Config, info *client.ComputeInfo, generatedData *packerbu
&chroot.StepEarlyCleanup{},
)

var captureSteps []multistep.Step

if config.ImageResourceID != "" {
addSteps(&StepCreateImage{
ImageResourceID: config.ImageResourceID,
ImageOSState: string(compute.Generalized),
OSDiskCacheType: config.OSDiskCacheType,
OSDiskStorageAccountType: config.OSDiskStorageAccountType,
Location: info.Location,
})
captureSteps = append(
captureSteps,
&StepCreateImage{
ImageResourceID: config.ImageResourceID,
ImageOSState: string(compute.Generalized),
OSDiskCacheType: config.OSDiskCacheType,
OSDiskStorageAccountType: config.OSDiskStorageAccountType,
Location: info.Location,
},
)
}
if hasValidSharedImage {
addSteps(
captureSteps = append(
captureSteps,
&StepCreateSnapshotset{
OSDiskSnapshotID: config.TemporaryOSDiskSnapshotID,
DataDiskSnapshotIDPrefix: config.TemporaryDataDiskSnapshotIDPrefix,
Location: info.Location,
SkipCleanup: config.SkipCleanup,
},
)
captureSteps = append(
captureSteps,
&StepCreateSharedImageVersion{
Destination: config.SharedImageGalleryDestination,
OSDiskCacheType: config.OSDiskCacheType,
Expand All @@ -640,5 +656,7 @@ func buildsteps(config Config, info *client.ComputeInfo, generatedData *packerbu
)
}

addSteps(config.CaptureSteps(say, captureSteps...)...)

return steps
}
2 changes: 2 additions & 0 deletions builder/azure/chroot/builder.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion builder/azure/chroot/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func Test_buildsteps(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
withMetadataStub(func() { // ensure that values are taken from info, instead of retrieved again
got := buildsteps(tt.config, info, &packerbuilderdata.GeneratedData{})
got := buildsteps(tt.config, info, &packerbuilderdata.GeneratedData{}, func(string) {})
tt.verify(got, t)
})
})
Expand Down
33 changes: 33 additions & 0 deletions builder/azure/common/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//go:generate packer-sdc struct-markdown

package common

import (
"github.com/hashicorp/packer-plugin-sdk/multistep"
)

const (
SkippingImageCreation = "Skipping image creation..."
)

type Config struct {
// Skip creating the image.
// Useful for setting to `true` during a build test stage.
// Defaults to `false`.
SkipCreateImage bool `mapstructure:"skip_create_image" required:"false"`
}

// CaptureSteps returns the steps unless `SkipCreateImage` is `true`. In that case it returns
// a step that to inform the user that image capture is being skipped.
func (config Config) CaptureSteps(say func(string), steps ...multistep.Step) []multistep.Step {
if !config.SkipCreateImage {
return steps
}

return []multistep.Step{
&StepNotify{
message: SkippingImageCreation,
say: say,
},
}
}
44 changes: 44 additions & 0 deletions builder/azure/common/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package common_test

import (
"context"
"testing"

"github.com/hashicorp/packer-plugin-sdk/multistep"
"github.com/stretchr/testify/assert"

"github.com/hashicorp/packer-plugin-azure/builder/azure/common"
)

func TestSkipCreateImage(t *testing.T) {
var said []string

say := func(what string) {
said = append(said, what)
}

config := common.Config{}
message := "Capture Image"

steps := config.CaptureSteps(say, common.NewStepNotify(message, say))
state := &multistep.BasicStateBag{}

ctx := context.Background()

for _, step := range steps {
step.Run(ctx, state)
}

assert.Equal(t, said, []string{message})

said = nil
config.SkipCreateImage = true

steps = config.CaptureSteps(say, common.NewStepNotify(message, say))

for _, step := range steps {
step.Run(ctx, state)
}

assert.Equal(t, said, []string{common.SkippingImageCreation})
}
31 changes: 31 additions & 0 deletions builder/azure/common/step_notify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package common

import (
"context"

"github.com/hashicorp/packer-plugin-sdk/multistep"
)

type StepNotify struct {
message string
say func(string)
}

func NewStepNotify(message string, say func(string)) *StepNotify {
return &StepNotify{
message: message,
say: say,
}
}

func (step *StepNotify) Run(
ctx context.Context,
state multistep.StateBag,
) multistep.StepAction {
step.say(step.message)
return multistep.ActionContinue
}

func (step *StepNotify) Cleanup(state multistep.StateBag) {}

var _ multistep.Step = (*StepNotify)(nil)
30 changes: 30 additions & 0 deletions builder/azure/common/step_notify_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package common_test

import (
"context"
"testing"

"github.com/hashicorp/packer-plugin-sdk/multistep"
"github.com/stretchr/testify/assert"

"github.com/hashicorp/packer-plugin-azure/builder/azure/common"
)

func TestStepNotify(t *testing.T) {
var said []string

say := func(what string) {
said = append(said, what)
}

message := "Notify Step"

step := common.NewStepNotify(message, say)
state := &multistep.BasicStateBag{}

ctx := context.Background()

step.Run(ctx, state)

assert.Equal(t, said, []string{message})
}
15 changes: 9 additions & 6 deletions builder/azure/dtl/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,6 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
Comm: &b.config.Comm,
},
NewStepPowerOffCompute(azureClient, ui, &b.config),
NewStepCaptureImage(azureClient, ui, &b.config),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
NewStepDeleteVirtualMachine(azureClient, ui, &b.config),
}
} else if b.config.OSType == constants.Target_Windows {
steps = []multistep.Step{
Expand All @@ -216,14 +213,20 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
},
&commonsteps.StepProvision{},
NewStepPowerOffCompute(azureClient, ui, &b.config),
NewStepCaptureImage(azureClient, ui, &b.config),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
NewStepDeleteVirtualMachine(azureClient, ui, &b.config),
}
} else {
return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType)
}

captureSteps := b.config.CaptureSteps(
ui.Say,
NewStepCaptureImage(azureClient, ui, &b.config),
NewStepPublishToSharedImageGallery(azureClient, ui, &b.config),
)

steps = append(steps, captureSteps...)
steps = append(steps, NewStepDeleteVirtualMachine(azureClient, ui, &b.config))

if b.config.PackerDebug {
ui.Message(fmt.Sprintf("temp admin user: '%s'", b.config.UserName))
ui.Message(fmt.Sprintf("temp admin password: '%s'", b.config.Password))
Expand Down
2 changes: 2 additions & 0 deletions builder/azure/dtl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ type ArtifactParameter struct {
type Config struct {
common.PackerConfig `mapstructure:",squash"`

azcommon.Config `mapstructure:",squash"`

// Authentication via OAUTH
ClientConfig client.Config `mapstructure:",squash"`

Expand Down
2 changes: 2 additions & 0 deletions builder/azure/dtl/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions docs-partials/builder/azure/common/Config-not-required.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!-- Code generated from the comments of the Config struct in builder/azure/common/config.go; DO NOT EDIT MANUALLY -->

- `skip_create_image` (bool) - Skip creating the image.
Useful for setting to `true` during a build test stage.
Defaults to `false`.

<!-- End of code generated from the comments of the Config struct in builder/azure/common/config.go; -->
2 changes: 2 additions & 0 deletions docs/builders/arm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ Providing `temp_resource_group_name` or `location` in combination with

@include 'builder/azure/common/client/Config-not-required.mdx'

@include 'builder/azure/common/Config-not-required.mdx'

## Build Shared Information Variables

This builder generates data that are shared with provisioner and post-processor via build function of [template engine](https://packer.io/docs/templates/legacy_json_templates/engine) for JSON and [contextual variables](https://packer.io/docs/templates/hcl_templates/contextual-variables) for HCL2.
Expand Down
2 changes: 2 additions & 0 deletions docs/builders/chroot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ information.

@include 'builder/azure/chroot/Config-not-required.mdx'

@include 'builder/azure/common/Config-not-required.mdx'

#### Output options:

At least one of these options needs to be specified:
Expand Down
2 changes: 2 additions & 0 deletions docs/builders/dtl.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ you should specify `subscription_id`, `client_id` and one of `client_secret`,

@include 'builder/azure/dtl/Config-not-required.mdx'

@include 'builder/azure/common/Config-not-required.mdx'

#### DtlArtifact
@include 'provisioner/azure-dtlartifact/DtlArtifact-not-required.mdx'

Expand Down

0 comments on commit 0fea610

Please sign in to comment.