diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 253b50c14..767ebe470 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "golang.org/x/crypto/ssh" ) // BuilderId uniquely identifies the builder @@ -24,6 +25,24 @@ type Builder struct { runner multistep.Runner } +// TODO: rename, comment +type builderConfig struct { + *communicator.Config +} + +func (c *builderConfig) sshConfigFunc(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { + return func(state multistep.StateBag) (*ssh.ClientConfig, error) { + // copy communicator config by value at the last possible moment, + // so we get any values written by prior steps, then change the static + // details to make it work correctly. + s := *c + s.SSHPty = true + s.Type = "ssh" + s.SSHUsername = username + return s.SSHConfigFunc()(state) + } +} + func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { config, err := NewConfig(rawConfig...) if err != nil { @@ -71,10 +90,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe var steps []multistep.Step if b.config.IsPV() { - builderCommConfig := b.config.Comm - builderCommConfig.SSHPty = true - builderCommConfig.Type = "ssh" - builderCommConfig.SSHUsername = b.config.BuilderSSHUsername + bc := builderConfig{&b.config.Comm} steps = []multistep.Step{ &ocommon.StepKeyPair{ @@ -85,7 +101,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepCreateIPReservation{}, &stepAddKeysToAPI{}, &stepSecurity{ - Comm: &b.config.Comm, + CommType: b.config.Comm.Type, SecurityListKey: "security_list_master", }, &stepCreatePersistentVolume{ @@ -109,7 +125,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepTerminatePVMaster{}, &stepSecurity{ SecurityListKey: "security_list_builder", - Comm: &builderCommConfig, + CommType: "ssh", }, &stepCreatePersistentVolume{ // We double the master volume size because we need room to @@ -128,10 +144,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Index: 2, InstanceInfoKey: "builder_instance_info", }, - &communicator.StepConnect{ - Config: &builderCommConfig, + &communicator.StepConnectSSH{ + Config: &b.config.Comm, Host: ocommon.CommHost, - SSHConfig: builderCommConfig.SSHConfigFunc(), + SSHConfig: bc.sshConfigFunc(b.config.BuilderSSHUsername), }, &stepUploadImage{ UploadImageCommand: b.config.BuilderUploadImageCommand, @@ -151,10 +167,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), }, &stepCreateIPReservation{}, - &stepAddKeysToAPI{}, + &stepAddKeysToAPI{ + Skip: b.config.Comm.Type != "ssh", + }, &stepSecurity{ SecurityListKey: "security_list", - Comm: &b.config.Comm, + CommType: b.config.Comm.Type, }, &stepCreateInstance{}, &communicator.StepConnect{ diff --git a/builder/oracle/classic/pv_config.go b/builder/oracle/classic/pv_config.go index 747c35842..de55b130e 100644 --- a/builder/oracle/classic/pv_config.go +++ b/builder/oracle/classic/pv_config.go @@ -25,6 +25,8 @@ type PVConfig struct { * Documentation * split master/builder image/connection config. i.e. build anything, master only linux possible ignore everything for builder and always use SSH keys + * Need to prepare the ssh config + * Possible also to just have nested config? */ } diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index dafea637f..a68093f32 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -11,7 +11,9 @@ import ( "github.com/hashicorp/packer/packer" ) -type stepAddKeysToAPI struct{} +type stepAddKeysToAPI struct { + Skip bool +} func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state @@ -19,12 +21,12 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult config := state.Get("config").(*Config) client := state.Get("client").(*compute.Client) - if config.Comm.Type != "ssh" { - ui.Say("Not using SSH communicator; skip generating SSH keys...") + if s.Skip { + ui.Say("Skipping generating SSH keys...") return multistep.ActionContinue } - // grab packer-generated key from statebag context. + // Always check configured communicator for keys sshPublicKey := bytes.TrimSpace(config.Comm.SSHPublicKey) // form API call to add key to compute cloud @@ -52,8 +54,11 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult } func (s *stepAddKeysToAPI) Cleanup(state multistep.StateBag) { - // Delete the keys we created during this run + if s.Skip { + return + } config := state.Get("config").(*Config) + // Delete the keys we created during this run if len(config.Comm.SSHKeyPairName) == 0 { // No keys were generated; none need to be cleaned up. return diff --git a/builder/oracle/classic/step_create_image.go b/builder/oracle/classic/step_create_image.go index 94bb204b1..de97cf16b 100644 --- a/builder/oracle/classic/step_create_image.go +++ b/builder/oracle/classic/step_create_image.go @@ -24,7 +24,7 @@ func (s *stepCreateImage) Run(_ context.Context, state multistep.StateBag) multi createMI := &compute.CreateMachineImageInput{ // Two-part name of the account Account: fmt.Sprintf("/Compute-%s/cloud_storage", config.IdentityDomain), - Description: "Packer generated TODO", + Description: "Packer generated Machine Image.", // The three-part name of the object Name: config.ImageName, // image_file.tar.gz, where image_file is the .tar.gz name of the diff --git a/builder/oracle/classic/step_create_persistent_volume.go b/builder/oracle/classic/step_create_persistent_volume.go index 177b7e6b1..497253544 100644 --- a/builder/oracle/classic/step_create_persistent_volume.go +++ b/builder/oracle/classic/step_create_persistent_volume.go @@ -42,8 +42,6 @@ func (s *stepCreatePersistentVolume) Run(_ context.Context, state multistep.Stat return multistep.ActionHalt } - //TODO: wait to become available - ui.Message(fmt.Sprintf("Created volume: %s", cc.Name)) return multistep.ActionContinue } diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 054ca7b5e..2fa6a6216 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -7,13 +7,12 @@ import ( "strings" "github.com/hashicorp/go-oracle-terraform/compute" - "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) type stepSecurity struct { - Comm *communicator.Config + CommType string SecurityListKey string secListName string secRuleName string @@ -37,9 +36,9 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste client := state.Get("client").(*compute.Client) commType := "" - if s.Comm.Type == "ssh" { + if s.CommType == "ssh" { commType = "SSH" - } else if s.Comm.Type == "winrm" { + } else if s.CommType == "winrm" { commType = "WINRM" } secListName := fmt.Sprintf("Packer_%s_Allow_%s", commType, runID) @@ -153,7 +152,7 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { } // Some extra cleanup if we used the winRM communicator - if s.Comm.Type == "winrm" { + if s.CommType == "winrm" { // Delete the packer-generated application application, ok := state.GetOk("winrm_application") if !ok {