Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions builder/proxmox/clone/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
state.Put("clone-config", &b.config)

preSteps := []multistep.Step{
&StepSshKeyPair{
Debug: b.config.PackerDebug,
DebugKeyPath: fmt.Sprintf("%s.pem", b.config.PackerBuildName),
},
&StepMapSourceDisks{},
}
postSteps := []multistep.Step{}
Expand Down
16 changes: 12 additions & 4 deletions builder/proxmox/common/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook,

// Build the steps
coreSteps := []multistep.Step{
// Since the ISOs get added to the VM before/during this line we need to update the cloud-init data before this line. It probably needs to be before as CD creation is done in presteps
&stepStartVM{
vmCreator: b.vmCreator,
},
// Also need to update the cloud-init data before this line
commonsteps.HTTPServerFromHTTPConfig(&b.config.HTTPConfig),
&stepTypeBootCommand{
BootConfig: b.config.BootConfig,
Expand All @@ -67,14 +69,21 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook,
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
Comm: &b.config.Comm,
Comm: comm,
},
&stepRemoveCloudInitDrive{},
&stepConvertToTemplate{},
&stepFinalizeTemplateConfig{},
&stepSuccess{},
}
preSteps := b.preSteps

preSteps := []multistep.Step{
&StepSshKeyPair{
Debug: b.config.PackerDebug,
DebugKeyPath: fmt.Sprintf("%s.pem", b.config.PackerBuildName),
},
&StepUpdateCloudInitSSH{},
}
for idx := range b.config.ISOs {
if b.config.ISOs[idx].ISODownloadPVE {
preSteps = append(preSteps,
Expand Down Expand Up @@ -104,8 +113,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook,
}
}

steps := append(preSteps, coreSteps...)
steps = append(steps, b.postSteps...)
steps := append(preSteps, b.preSteps..., coreSteps..., b.postSteps...)
// Run the steps
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package proxmoxclone
package proxmox

import (
"context"
Expand Down Expand Up @@ -47,9 +47,8 @@ func (s *StepSshKeyPair) Run(ctx context.Context, state multistep.StateBag) mult
return multistep.ActionHalt
}

c.Comm.SSHPrivateKey = privateKeyBytes
c.Comm.SSHKeyPairName = kp.Comment
c.Comm.SSHTemporaryKeyPairName = kp.Comment
c.Comm.SSHPrivateKey = privateKeyBytes
c.Comm.SSHPublicKey = kp.PublicKeyAuthorizedKeysLine

return multistep.ActionContinue
Expand Down
95 changes: 95 additions & 0 deletions builder/proxmox/common/step_update_cloud_init_ssh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package proxmox

import (
"context"
"os"
"slices"
"strings"
"fmt"

packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
common "github.com/hashicorp/packer-plugin-proxmox/builder/proxmox/common"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)

type StepUpdateCloudInitSSH struct{}

func (s *StepUpdateCloudInitSSH) Run(ctx context.Context, state multiste.StateBag) multistep.StepAction {
// NOTE: Can pass Cloud-Init data via CD or HTTP Server

ui := state.Get("ui").(packersdk.Ui)
c := state.Get("config").(*common.Config)

if c.Comm.SSHTemporaryKeyPairName == "" ||
(len(c.ISOs) <= 1 &&
c.HTTPConfig.HTTPDir == "" &&
len(c.HTTPConfig.HTTPContent) == 0) {
return multistep.ActionContinue
}

temp_ssh_public_key := string(c.Comm.SSHPublicKey)

if len(c.ISOs) > 1 {
// Skip first ISO as it should be the BootISO
for idx := range c.ISOs[1:] {
if c.ISOs[idx].CDConfig.CDLabel != "cidata" {
continue
}

if value, ok := c.ISOs[idx].CDConfig.CDContent["user-data"]; ok {
c.ISOs[idx].CDConfig.CDContent["user-data"] = strings.ReplaceAll(value, "${temporary_ssh_public_key}", temp_ssh_public_key)
ui.Say("Updated 'user-data' CD Content to use temporary SSH public key")
// CDContent will take precedence over CDFiles
break
}

// TODO: This needs to be able to handle when directories and globs
// are passed to CDFiles
for jdx, value := range c.ISOs[idx].CDConfig.CDFiles {
if slices.Contains(value, "user-data") {
dat, err := os.ReadFile(c.ISOs[idx].CDConfig.CDFiles[jdx])
if err != nil {
// It is ok if file does not exist
break
}
// Choosing to write CDContent to avoid overwriting original
// file or creating a new file with the temporary public key
c.ISOs[idx].CDConfig.CDContent["user-data"] = strings.ReplaceAll(dat, "${temporary_ssh_public_key}", temp_ssh_public_key)
ui.Say("Created 'user-data' CD Content to override CD File and use temporary SSH public key")
// There can only be one user-data file
break
}
}
}
}

if c.HTTPConfig.HTTPDir != "" {
user_data_file := fmt.Sprintf("%s/user-data", c.HTTPConfig.HTTPDir)

dat, err := os.ReadFile(user_data_file)
if err != nil {
// It is ok if file does not exist
return multistep.ActionContinue
}

// Can't just write to "HTTPContent". Since it directly conflicts with
// "HTTPDir", we would have to walk and load every file from "HTTPDir"
// into "HTTPContent"
err := os.WriteFile(user_data_file, strings.ReplaceAll(dat, "${temporary_ssh_public_key}", temp_ssh_public_key), 0600)
if err == nil {
ui.Say(fmt.Sprintf("Rewrote '%s' in HTTPDir to use temporary SSH public key", user_data_file))
} else {
ui.Say(fmt.Sprintf("Failed to rewrite '%s' in HTTPDir to use temporary SSH public key", user_data_file))
}
} else if len(c.HTTPConfig.HTTPContent) > 0 {
if value, ok := c.HTTPConfig.HTTPContent["user-data"]; ok {
c.HTTPConfig.HTTPContent["user-data"] = strings.ReplaceAll(value, "%{temporary_ssh_public_key}", temp_ssh_public_key)
ui.Say("Updated 'user-data' HTTP Content to use temporary SSH public key")
}
}

return multistep.ActionContinue
}