package proxmoxclone import ( "context" "time" "fmt" proxmoxapi "github.com/Telmate/proxmox-api-go/proxmox" "github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/packer/builder/proxmox/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" ) // The unique id for the builder const BuilderID = "proxmox.clone" type Builder struct { config Config } // Builder implements packer.Builder var _ packer.Builder = &Builder{} var pluginVersion = "1.0.0" func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() } func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { return b.config.Prepare(raws...) } func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { state := new(multistep.BasicStateBag) state.Put("clone-config", &b.config) state.Put("vm-creator", &cloneVMCreator{}) state.Put("comm", &b.config.Comm) preSteps := []multistep.Step{ &StepSshKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("%s.pem", b.config.PackerBuildName), Comm: &b.config.Comm, }, } postSteps := []multistep.Step{} sb := proxmox.NewSharedBuilder(BuilderID, b.config.Config, preSteps, postSteps) return sb.Run(ctx, ui, hook, state) } type cloneVMCreator struct{} var _ proxmox.ProxmoxVMCreator = &cloneVMCreator{} func (*cloneVMCreator) Create(vmRef *proxmoxapi.VmRef, config proxmoxapi.ConfigQemu, state multistep.StateBag) error { client := state.Get("proxmoxClient").(*proxmoxapi.Client) c := state.Get("clone-config").(*Config) comm := state.Get("comm").(*communicator.Config) fullClone := 1 if c.FullClone { fullClone = 0 } config.FullClone = &fullClone config.CIuser = comm.SSHUsername config.Sshkeys = string(comm.SSHPublicKey) sourceVmr, err := client.GetVmRefByName(c.CloneVM) if err != nil { return err } err = config.CloneVm(sourceVmr, vmRef, client) if err != nil { return err } err = config.UpdateConfig(vmRef, client) if err != nil { return err } time.Sleep(time.Duration(15) * time.Second) return nil }