Merge pull request #7720 from psinghal20/issue-6617
Add feature to import user-data from a file
This commit is contained in:
commit
632e42eb88
|
@ -62,6 +62,7 @@ type Config struct {
|
||||||
Subnetwork string `mapstructure:"subnetwork"`
|
Subnetwork string `mapstructure:"subnetwork"`
|
||||||
Tags []string `mapstructure:"tags"`
|
Tags []string `mapstructure:"tags"`
|
||||||
UseInternalIP bool `mapstructure:"use_internal_ip"`
|
UseInternalIP bool `mapstructure:"use_internal_ip"`
|
||||||
|
MetadataFiles map[string]string `mapstructure:"metadata_files"`
|
||||||
Zone string `mapstructure:"zone"`
|
Zone string `mapstructure:"zone"`
|
||||||
|
|
||||||
Account AccountFile
|
Account AccountFile
|
||||||
|
|
|
@ -431,7 +431,8 @@ func testConfig(t *testing.T) (config map[string]interface{}, tempAccountFile st
|
||||||
"image_licenses": []string{
|
"image_licenses": []string{
|
||||||
"test-license",
|
"test-license",
|
||||||
},
|
},
|
||||||
"zone": "us-east1-a",
|
"metadata_files": map[string]string{},
|
||||||
|
"zone": "us-east1-a",
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, tempAccountFile
|
return config, tempAccountFile
|
||||||
|
@ -484,6 +485,21 @@ func testAccountFile(t *testing.T) string {
|
||||||
return tf.Name()
|
return tf.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testMetadataFileContent = `testMetadata`
|
||||||
|
|
||||||
|
func testMetadataFile(t *testing.T) string {
|
||||||
|
tf, err := ioutil.TempFile("", "packer")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer tf.Close()
|
||||||
|
if _, err := tf.Write([]byte(testMetadataFileContent)); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tf.Name()
|
||||||
|
}
|
||||||
|
|
||||||
// This is just some dummy data that doesn't actually work (it was revoked
|
// This is just some dummy data that doesn't actually work (it was revoked
|
||||||
// a long time ago).
|
// a long time ago).
|
||||||
const testAccountContent = `{}`
|
const testAccountContent = `{}`
|
||||||
|
|
|
@ -19,6 +19,7 @@ type StepCreateInstance struct {
|
||||||
func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string) (map[string]string, error) {
|
func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string) (map[string]string, error) {
|
||||||
instanceMetadata := make(map[string]string)
|
instanceMetadata := make(map[string]string)
|
||||||
var err error
|
var err error
|
||||||
|
var errs *packer.MultiError
|
||||||
|
|
||||||
// Copy metadata from config.
|
// Copy metadata from config.
|
||||||
for k, v := range c.Metadata {
|
for k, v := range c.Metadata {
|
||||||
|
@ -41,10 +42,24 @@ func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string)
|
||||||
if c.StartupScriptFile != "" {
|
if c.StartupScriptFile != "" {
|
||||||
var content []byte
|
var content []byte
|
||||||
content, err = ioutil.ReadFile(c.StartupScriptFile)
|
content, err = ioutil.ReadFile(c.StartupScriptFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
instanceMetadata[StartupWrappedScriptKey] = string(content)
|
instanceMetadata[StartupWrappedScriptKey] = string(content)
|
||||||
} else if wrappedStartupScript, exists := instanceMetadata[StartupScriptKey]; exists {
|
} else if wrappedStartupScript, exists := instanceMetadata[StartupScriptKey]; exists {
|
||||||
instanceMetadata[StartupWrappedScriptKey] = wrappedStartupScript
|
instanceMetadata[StartupWrappedScriptKey] = wrappedStartupScript
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read metadata from files specified with metadata_files
|
||||||
|
for key, value := range c.MetadataFiles {
|
||||||
|
var content []byte
|
||||||
|
content, err = ioutil.ReadFile(value)
|
||||||
|
if err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs, err)
|
||||||
|
}
|
||||||
|
instanceMetadata[key] = string(content)
|
||||||
|
}
|
||||||
|
|
||||||
if sourceImage.IsWindows() {
|
if sourceImage.IsWindows() {
|
||||||
// Windows startup script support is not yet implemented.
|
// Windows startup script support is not yet implemented.
|
||||||
// Mark the startup script as done.
|
// Mark the startup script as done.
|
||||||
|
@ -55,7 +70,10 @@ func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string)
|
||||||
instanceMetadata[StartupScriptStatusKey] = StartupScriptStatusNotDone
|
instanceMetadata[StartupScriptStatusKey] = StartupScriptStatusNotDone
|
||||||
}
|
}
|
||||||
|
|
||||||
return instanceMetadata, err
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
return instanceMetadata, errs
|
||||||
|
}
|
||||||
|
return instanceMetadata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImage(c *Config, d Driver) (*Image, error) {
|
func getImage(c *Config, d Driver) (*Image, error) {
|
||||||
|
@ -98,7 +116,13 @@ func (s *StepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
||||||
|
|
||||||
var errCh <-chan error
|
var errCh <-chan error
|
||||||
var metadata map[string]string
|
var metadata map[string]string
|
||||||
metadata, err = c.createInstanceMetadata(sourceImage, string(c.Comm.SSHPublicKey))
|
metadata, errs := c.createInstanceMetadata(sourceImage, string(c.Comm.SSHPublicKey))
|
||||||
|
if errs != nil {
|
||||||
|
state.Put("error", errs.Error())
|
||||||
|
ui.Error(errs.Error())
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
errCh, err = d.RunInstance(&InstanceConfig{
|
errCh, err = d.RunInstance(&InstanceConfig{
|
||||||
AcceleratorType: c.AcceleratorType,
|
AcceleratorType: c.AcceleratorType,
|
||||||
AcceleratorCount: c.AcceleratorCount,
|
AcceleratorCount: c.AcceleratorCount,
|
||||||
|
|
|
@ -325,3 +325,20 @@ func TestCreateInstanceMetadata_noPublicKey(t *testing.T) {
|
||||||
// ensure the ssh metadata hasn't changed
|
// ensure the ssh metadata hasn't changed
|
||||||
assert.Equal(t, metadata["sshKeys"], sshKeys, "Instance metadata should not have been modified")
|
assert.Equal(t, metadata["sshKeys"], sshKeys, "Instance metadata should not have been modified")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateInstanceMetadata_metadataFile(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
c := state.Get("config").(*Config)
|
||||||
|
image := StubImage("test-image", "test-project", []string{}, 100)
|
||||||
|
content := testMetadataFileContent
|
||||||
|
fileName := testMetadataFile(t)
|
||||||
|
c.MetadataFiles["user-data"] = fileName
|
||||||
|
|
||||||
|
// create our metadata
|
||||||
|
metadata, err := c.createInstanceMetadata(image, "")
|
||||||
|
|
||||||
|
assert.True(t, err == nil, "Metadata creation should have succeeded.")
|
||||||
|
|
||||||
|
// ensure the user-data key in metadata is updated with file content
|
||||||
|
assert.Equal(t, metadata["user-data"], content, "user-data field of the instance metadata should have been updated.")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue