From 16d044b3987f3bd91bb7dfe5f9e5455e75e3b75a Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 28 Mar 2018 13:27:41 -0700 Subject: [PATCH 1/2] add user data and user data file to oracle oci builder --- builder/oracle/oci/config.go | 30 ++++++++++++++++++++++++++++++ builder/oracle/oci/driver_oci.go | 3 +++ 2 files changed, 33 insertions(+) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 881ed1e35..3af6dcbdf 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -1,8 +1,11 @@ package oci import ( + "encoding/base64" "errors" "fmt" + "io/ioutil" + "log" "os" "path/filepath" @@ -41,6 +44,9 @@ type Config struct { BaseImageID string `mapstructure:"base_image_ocid"` Shape string `mapstructure:"shape"` ImageName string `mapstructure:"image_name"` + // UserData and UserDataFile file are both optional and mutually exclusive. + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` // Networking SubnetID string `mapstructure:"subnet_ocid"` @@ -195,6 +201,30 @@ func NewConfig(raws ...interface{}) (*Config, error) { } } + // Optional UserData config + if c.UserData != "" && c.UserDataFile != "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + } else if c.UserDataFile != "" { + if _, err := os.Stat(c.UserDataFile); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) + } + } + // read UserDataFile into string. + if c.UserDataFile != "" { + fiData, err := ioutil.ReadFile(c.UserDataFile) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Problem reading user_data_file: %s", err)) + } + c.UserData = string(fiData) + } + // Test if UserData is encoded already, and if not, encode it + if c.UserData != "" { + if _, err := base64.StdEncoding.DecodeString(c.UserData); err != nil { + log.Printf("[DEBUG] base64 encoding user data...") + c.UserData = base64.StdEncoding.EncodeToString([]byte(c.UserData)) + } + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index ead05a12d..1b6b0a3f9 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -35,6 +35,9 @@ func (d *driverOCI) CreateInstance(publicKey string) (string, error) { "ssh_authorized_keys": publicKey, }, } + if d.cfg.UserData != "" { + params.Metadata["user_data"] = d.cfg.UserData + } instance, err := d.client.Compute.Instances.Launch(params) if err != nil { return "", err From ec5eba82cc27e380820b80e664eb6fcff3127d8f Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 30 Mar 2018 10:57:40 -0700 Subject: [PATCH 2/2] add docs for user_data_file and user_data to oracle-oci builder page --- website/source/docs/builders/oracle-oci.html.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index ea4b08404..4329a56f5 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -125,6 +125,15 @@ builder. - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. + - `user_data` (string) - user_data to be used by cloud + init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Generally speaking, it is easier to use the `user_data_file`, + but you can use this option to put either the platintext data or the base64 + encoded data directly into your Packer config. + + - `user_data_file` (string) - Path to a file to be used as user_data by cloud + init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Example: + `"user_data_file": "./boot_config/myscript.sh"` + ## Basic Example