Skip to content

Commit b8c44e9

Browse files
committed
common: add skip_convert_to_template option
1 parent 38a075c commit b8c44e9

File tree

13 files changed

+104
-38
lines changed

13 files changed

+104
-38
lines changed

.web-docs/components/builder/clone/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ boot time.
262262
- `template_description` (string) - Description of the template, visible in
263263
the Proxmox interface.
264264

265+
- `skip_convert_to_template` (bool) - Skip converting the VM to a template on completion of build.
266+
Defaults to `false`
267+
265268
- `cloud_init` (bool) - If true, add an empty Cloud-Init CDROM drive after the virtual
266269
machine has been converted to a template. Defaults to `false`.
267270

.web-docs/components/builder/iso/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ in the image's Cloud-Init settings for provisioning.
197197
- `template_description` (string) - Description of the template, visible in
198198
the Proxmox interface.
199199

200+
- `skip_convert_to_template` (bool) - Skip converting the VM to a template on completion of build.
201+
Defaults to `false`
202+
200203
- `cloud_init` (bool) - If true, add an empty Cloud-Init CDROM drive after the virtual
201204
machine has been converted to a template. Defaults to `false`.
202205

builder/proxmox/clone/config.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder/proxmox/common/artifact.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import (
1414

1515
type Artifact struct {
1616
builderID string
17-
templateID int
17+
artifactID int
18+
artifactType string
1819
proxmoxClient *proxmox.Client
1920

2021
// StateData should store data such as GeneratedData
@@ -34,19 +35,19 @@ func (*Artifact) Files() []string {
3435
}
3536

3637
func (a *Artifact) Id() string {
37-
return strconv.Itoa(a.templateID)
38+
return strconv.Itoa(a.artifactID)
3839
}
3940

4041
func (a *Artifact) String() string {
41-
return fmt.Sprintf("A template was created: %d", a.templateID)
42+
return fmt.Sprintf("A %s was created: %d", a.artifactType, a.artifactID)
4243
}
4344

4445
func (a *Artifact) State(name string) interface{} {
4546
return a.StateData[name]
4647
}
4748

4849
func (a *Artifact) Destroy() error {
49-
log.Printf("Destroying template: %d", a.templateID)
50-
_, err := a.proxmoxClient.DeleteVm(proxmox.NewVmRef(a.templateID))
50+
log.Printf("Destroying %s: %d", a.artifactType, a.artifactID)
51+
_, err := a.proxmoxClient.DeleteVm(proxmox.NewVmRef(a.artifactID))
5152
return err
5253
}

builder/proxmox/common/builder.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook,
7171
},
7272
&stepRemoveCloudInitDrive{},
7373
&stepConvertToTemplate{},
74-
&stepFinalizeTemplateConfig{},
74+
&stepFinalizeConfig{},
7575
&stepSuccess{},
7676
}
7777
preSteps := b.preSteps
@@ -118,19 +118,24 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook,
118118
return nil, errors.New("build was cancelled")
119119
}
120120

121-
// Verify that the template_id was set properly, otherwise we didn't progress through the last step
122-
tplID, ok := state.Get("template_id").(int)
121+
// Verify that the artifact_id and artifact_type was set properly, otherwise we didn't progress through the last step
122+
artifactID, ok := state.Get("artifact_id").(int)
123123
if !ok {
124-
return nil, fmt.Errorf("template ID could not be determined")
124+
return nil, fmt.Errorf("artifact ID could not be determined")
125+
}
126+
127+
artifactType, ok := state.Get("artifact_type").(string)
128+
if !ok {
129+
return nil, fmt.Errorf("artifact type could not be determined")
125130
}
126131

127132
artifact := &Artifact{
128133
builderID: b.id,
129-
templateID: tplID,
134+
artifactID: artifactID,
135+
artifactType: artifactType,
130136
proxmoxClient: b.proxmoxClient,
131137
StateData: map[string]interface{}{"generated_data": state.Get("generated_data")},
132138
}
133-
134139
return artifact, nil
135140
}
136141

builder/proxmox/common/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ type Config struct {
178178
// Description of the template, visible in
179179
// the Proxmox interface.
180180
TemplateDescription string `mapstructure:"template_description"`
181+
// Skip converting the VM to a template on completion of build.
182+
// Defaults to `false`
183+
SkipConvertToTemplate bool `mapstructure:"skip_convert_to_template"`
181184

182185
// If true, add an empty Cloud-Init CDROM drive after the virtual
183186
// machine has been converted to a template. Defaults to `false`.

builder/proxmox/common/config.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder/proxmox/common/step_convert_to_template.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// stepConvertToTemplate takes the running VM configured in earlier steps, stops it, and
1717
// converts it into a Proxmox template.
1818
//
19-
// It sets the template_id state which is used for Artifact lookup.
19+
// It sets the artifact_id state which is used for Artifact lookup.
2020
type stepConvertToTemplate struct{}
2121

2222
type templateConverter interface {
@@ -30,6 +30,7 @@ func (s *stepConvertToTemplate) Run(ctx context.Context, state multistep.StateBa
3030
ui := state.Get("ui").(packersdk.Ui)
3131
client := state.Get("proxmoxClient").(templateConverter)
3232
vmRef := state.Get("vmRef").(*proxmox.VmRef)
33+
c := state.Get("config").(*Config)
3334

3435
ui.Say("Stopping VM")
3536
_, err := client.ShutdownVm(vmRef)
@@ -40,16 +41,23 @@ func (s *stepConvertToTemplate) Run(ctx context.Context, state multistep.StateBa
4041
return multistep.ActionHalt
4142
}
4243

43-
ui.Say("Converting VM to template")
44-
err = client.CreateTemplate(vmRef)
45-
if err != nil {
46-
err := fmt.Errorf("Error converting VM to template: %s", err)
47-
state.Put("error", err)
48-
ui.Error(err.Error())
49-
return multistep.ActionHalt
44+
if c.SkipConvertToTemplate {
45+
ui.Say("skip_convert_to_template set, skipping conversion to template")
46+
state.Put("artifact_type", "VM")
47+
} else {
48+
ui.Say("Converting VM to template")
49+
err = client.CreateTemplate(vmRef)
50+
if err != nil {
51+
err := fmt.Errorf("Error converting VM to template: %s", err)
52+
state.Put("error", err)
53+
ui.Error(err.Error())
54+
return multistep.ActionHalt
55+
}
56+
state.Put("artifact_type", "template")
5057
}
51-
log.Printf("template_id: %d", vmRef.VmId())
52-
state.Put("template_id", vmRef.VmId())
58+
59+
log.Printf("artifact_id: %d", vmRef.VmId())
60+
state.Put("artifact_id", vmRef.VmId())
5361

5462
return multistep.ActionContinue
5563
}

builder/proxmox/common/step_convert_to_template_test.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,45 @@ func TestConvertToTemplate(t *testing.T) {
3434
expectCallCreateTemplate bool
3535
createTemplateErr error
3636
expectedAction multistep.StepAction
37-
expectTemplateIdSet bool
37+
expectArtifactIdSet bool
38+
expectArtifactType string
39+
builderConfig *Config
3840
}{
3941
{
4042
name: "no errors returns continue and sets template id",
4143
expectCallCreateTemplate: true,
4244
expectedAction: multistep.ActionContinue,
43-
expectTemplateIdSet: true,
45+
expectArtifactIdSet: true,
46+
expectArtifactType: "template",
47+
builderConfig: &Config{},
48+
},
49+
{
50+
name: "no errors returns continue and sets vm id",
51+
expectCallCreateTemplate: true,
52+
expectedAction: multistep.ActionContinue,
53+
expectArtifactIdSet: true,
54+
expectArtifactType: "VM",
55+
builderConfig: &Config{
56+
SkipConvertToTemplate: true,
57+
},
4458
},
4559
{
4660
name: "when shutdown fails, don't try to create template and halt",
4761
shutdownErr: fmt.Errorf("failed to stop vm"),
4862
expectCallCreateTemplate: false,
4963
expectedAction: multistep.ActionHalt,
50-
expectTemplateIdSet: false,
64+
expectArtifactIdSet: false,
65+
expectArtifactType: "",
66+
builderConfig: &Config{},
5167
},
5268
{
5369
name: "when create template fails, halt",
5470
expectCallCreateTemplate: true,
5571
createTemplateErr: fmt.Errorf("failed to stop vm"),
5672
expectedAction: multistep.ActionHalt,
57-
expectTemplateIdSet: false,
73+
expectArtifactIdSet: false,
74+
expectArtifactType: "",
75+
builderConfig: &Config{},
5876
},
5977
}
6078

@@ -85,21 +103,31 @@ func TestConvertToTemplate(t *testing.T) {
85103
state.Put("ui", packersdk.TestUi(t))
86104
state.Put("vmRef", proxmox.NewVmRef(vmid))
87105
state.Put("proxmoxClient", converter)
106+
state.Put("config", c.builderConfig)
88107

89108
step := stepConvertToTemplate{}
90109
action := step.Run(context.TODO(), state)
91110
if action != c.expectedAction {
92111
t.Errorf("Expected action to be %v, got %v", c.expectedAction, action)
93112
}
94113

95-
id, wasSet := state.GetOk("template_id")
114+
artifactId, artifactIdWasSet := state.GetOk("artifact_id")
115+
artifactType, artifactTypeWasSet := state.GetOk("artifact_type")
116+
117+
if c.expectArtifactIdSet != artifactIdWasSet {
118+
t.Errorf("Expected artifact_id state present=%v was present=%v", c.expectArtifactIdSet, artifactIdWasSet)
119+
}
120+
121+
if c.expectArtifactIdSet && artifactId != vmid {
122+
t.Errorf("Expected artifact_id state to be set to %d, got %v", vmid, artifactId)
123+
}
96124

97-
if c.expectTemplateIdSet != wasSet {
98-
t.Errorf("Expected template_id state present=%v was present=%v", c.expectTemplateIdSet, wasSet)
125+
if c.expectArtifactType == "" && artifactTypeWasSet {
126+
t.Errorf("Expected artifact_type state present=%v was present=%v", c.expectArtifactType, artifactTypeWasSet)
99127
}
100128

101-
if c.expectTemplateIdSet && id != vmid {
102-
t.Errorf("Expected template_id state to be set to %d, got %v", vmid, id)
129+
if artifactTypeWasSet && c.expectArtifactType != artifactType {
130+
t.Errorf("Expected artifact_type state to be set to %s, got %s", c.expectArtifactType, artifactType)
103131
}
104132
})
105133
}

builder/proxmox/common/step_finalize_template_config.go renamed to builder/proxmox/common/step_finalize_config.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,19 @@ import (
1717
// stepFinalizeTemplateConfig does any required modifications to the configuration _after_
1818
// the VM has been converted into a template, such as updating name and description, or
1919
// unmounting the installation ISO.
20-
type stepFinalizeTemplateConfig struct{}
20+
type stepFinalizeConfig struct{}
2121

22-
type templateFinalizer interface {
22+
type finalizer interface {
2323
GetVmConfig(*proxmox.VmRef) (map[string]interface{}, error)
2424
SetVmConfig(*proxmox.VmRef, map[string]interface{}) (interface{}, error)
25+
StartVm(*proxmox.VmRef) (string, error)
2526
}
2627

27-
var _ templateFinalizer = &proxmox.Client{}
28+
var _ finalizer = &proxmox.Client{}
2829

29-
func (s *stepFinalizeTemplateConfig) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
30+
func (s *stepFinalizeConfig) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
3031
ui := state.Get("ui").(packersdk.Ui)
31-
client := state.Get("proxmoxClient").(templateFinalizer)
32+
client := state.Get("proxmoxClient").(finalizer)
3233
c := state.Get("config").(*Config)
3334
vmRef := state.Get("vmRef").(*proxmox.VmRef)
3435

@@ -151,4 +152,4 @@ func (s *stepFinalizeTemplateConfig) Run(ctx context.Context, state multistep.St
151152
return multistep.ActionContinue
152153
}
153154

154-
func (s *stepFinalizeTemplateConfig) Cleanup(state multistep.StateBag) {}
155+
func (s *stepFinalizeConfig) Cleanup(state multistep.StateBag) {}

0 commit comments

Comments
 (0)