From 543caf3ec575621dd9210a6bd33116193d9da934 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Fri, 12 Jan 2018 14:12:15 -0800 Subject: [PATCH] WIP OCI Classic builder --- builder/oracle/classic/access_config.go | 4 + builder/oracle/classic/artifact.go | 34 ++++++++ builder/oracle/classic/builder.go | 87 +++++++++++++++++++ builder/oracle/classic/config.go | 44 ++++++++++ .../{oci => common}/step_ssh_key_pair.go | 8 +- builder/oracle/oci/builder.go | 3 +- 6 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 builder/oracle/classic/access_config.go create mode 100644 builder/oracle/classic/artifact.go create mode 100644 builder/oracle/classic/builder.go create mode 100644 builder/oracle/classic/config.go rename builder/oracle/{oci => common}/step_ssh_key_pair.go (94%) diff --git a/builder/oracle/classic/access_config.go b/builder/oracle/classic/access_config.go new file mode 100644 index 000000000..99483ceec --- /dev/null +++ b/builder/oracle/classic/access_config.go @@ -0,0 +1,4 @@ +package classic + +type AccessConfig struct { +} diff --git a/builder/oracle/classic/artifact.go b/builder/oracle/classic/artifact.go new file mode 100644 index 000000000..ff01b186f --- /dev/null +++ b/builder/oracle/classic/artifact.go @@ -0,0 +1,34 @@ +package classic + +// Artifact is an artifact implementation that contains a built Custom Image. +type Artifact struct { +} + +// BuilderId uniquely identifies the builder. +func (a *Artifact) BuilderId() string { + return BuilderId +} + +// Files lists the files associated with an artifact. We don't have any files +// as the custom image is stored server side. +func (a *Artifact) Files() []string { + return nil +} + +// Id returns the OCID of the associated Image. +func (a *Artifact) Id() string { + return "" +} + +func (a *Artifact) String() string { + return "" +} + +func (a *Artifact) State(name string) interface{} { + return nil +} + +// Destroy deletes the custom image associated with the artifact. +func (a *Artifact) Destroy() error { + return nil +} diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go new file mode 100644 index 000000000..4b86c449c --- /dev/null +++ b/builder/oracle/classic/builder.go @@ -0,0 +1,87 @@ +package classic + +import ( + "fmt" + "log" + + ocommon "github.com/hashicorp/packer/builder/oracle/common" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +// BuilderId uniquely identifies the builder +const BuilderId = "packer.oracle.classic" + +// Builder is a builder implementation that creates Oracle OCI custom images. +type Builder struct { + config *Config + runner multistep.Runner +} + +func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { + config, err := NewConfig(rawConfig...) + if err != nil { + return nil, err + } + b.config = config + + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + // Populate the state bag + state := new(multistep.BasicStateBag) + state.Put("config", b.config) + state.Put("hook", hook) + state.Put("ui", ui) + + // Build the steps + steps := []multistep.Step{ + &ocommon.StepKeyPair{ + Debug: b.config.PackerDebug, + DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), + PrivateKeyFile: b.config.Comm.SSHPrivateKey, + }, + &stepCreateInstance{}, + &communicator.StepConnect{ + Config: &b.config.Comm, + Host: commHost, + SSHConfig: SSHConfig( + b.config.Comm.SSHUsername, + b.config.Comm.SSHPassword), + }, + &common.StepProvision{}, + &stepSnapshot{}, + } + + // Run the steps + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + /* + // Build the artifact and return it + artifact := &Artifact{ + Image: state.Get("image").(client.Image), + Region: b.config.AccessCfg.Region, + driver: driver, + } + + return artifact, nil + */ + return nil, nil +} + +// Cancel terminates a running build. +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go new file mode 100644 index 000000000..6a3c05fc8 --- /dev/null +++ b/builder/oracle/classic/config.go @@ -0,0 +1,44 @@ +package classic + +import ( + "fmt" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/template/interpolate" +) + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + Comm communicator.Config `mapstructure:",squash"` + + Access *AccessConfig + + // Access config overrides + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` + IdentityDomain string `mapstructure:"identity_domain"` + APIEndpoint string `mapstructure:"api_endpoint"` + + // Image + Shape string `mapstructure:"shape"` + ImageList string `json:"image_list"` + + ctx interpolate.Context +} + +func NewConfig(raws ...interface{}) (*Config, error) { + c := &Config{} + + // Decode from template + err := config.Decode(c, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &c.ctx, + }, raws...) + if err != nil { + return nil, fmt.Errorf("Failed to mapstructure Config: %+v", err) + } + + return c, nil +} diff --git a/builder/oracle/oci/step_ssh_key_pair.go b/builder/oracle/common/step_ssh_key_pair.go similarity index 94% rename from builder/oracle/oci/step_ssh_key_pair.go rename to builder/oracle/common/step_ssh_key_pair.go index 9fa83c17d..c545a09e2 100644 --- a/builder/oracle/oci/step_ssh_key_pair.go +++ b/builder/oracle/common/step_ssh_key_pair.go @@ -1,4 +1,4 @@ -package oci +package common import ( "context" @@ -16,13 +16,13 @@ import ( "golang.org/x/crypto/ssh" ) -type stepKeyPair struct { +type StepKeyPair struct { Debug bool DebugKeyPath string PrivateKeyFile string } -func (s *stepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { @@ -112,6 +112,6 @@ func (s *stepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep return multistep.ActionContinue } -func (s *stepKeyPair) Cleanup(state multistep.StateBag) { +func (s *StepKeyPair) Cleanup(state multistep.StateBag) { // Nothing to do } diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 6a2f6efef..07d41b756 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -6,6 +6,7 @@ import ( "fmt" "log" + ocommon "github.com/hashicorp/packer/builder/oracle/common" client "github.com/hashicorp/packer/builder/oracle/oci/client" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -50,7 +51,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps steps := []multistep.Step{ - &stepKeyPair{ + &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_%s.pem", b.config.PackerBuildName), PrivateKeyFile: b.config.Comm.SSHPrivateKey,