post-processor/vagrant: do overrides
This commit is contained in:
parent
84f8c0bfa0
commit
5e2f08de70
|
@ -26,66 +26,39 @@ var builtins = map[string]string{
|
||||||
type Config struct {
|
type Config struct {
|
||||||
common.PackerConfig `mapstructure:",squash"`
|
common.PackerConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
|
CompressionLevel int `mapstructure:"compression_level"`
|
||||||
Include []string `mapstructure:"include"`
|
Include []string `mapstructure:"include"`
|
||||||
OutputPath string `mapstructure:"output"`
|
OutputPath string `mapstructure:"output"`
|
||||||
VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
|
Override map[string]interface{}
|
||||||
CompressionLevel int `mapstructure:"compression_level"`
|
VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
|
||||||
|
|
||||||
tpl *packer.ConfigTemplate
|
tpl *packer.ConfigTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
type PostProcessor struct {
|
type PostProcessor struct {
|
||||||
config Config
|
configs map[string]*Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PostProcessor) Configure(raws ...interface{}) error {
|
func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
md, err := common.DecodeConfig(&p.config, raws...)
|
p.configs = make(map[string]*Config)
|
||||||
if err != nil {
|
p.configs[""] = new(Config)
|
||||||
|
if err := p.configureSingle(p.configs[""], raws...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.config.tpl, err = packer.NewConfigTemplate()
|
// Go over any of the provider-specific overrides and load those up.
|
||||||
if err != nil {
|
for name, override := range p.configs[""].Override {
|
||||||
return err
|
subRaws := make([]interface{}, len(raws)+1)
|
||||||
}
|
copy(subRaws, raws)
|
||||||
p.config.tpl.UserVars = p.config.PackerUserVars
|
subRaws[len(raws)] = override
|
||||||
|
|
||||||
// Defaults
|
config := new(Config)
|
||||||
if p.config.OutputPath == "" {
|
p.configs[name] = config
|
||||||
p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
|
if err := p.configureSingle(config, subRaws...); err != nil {
|
||||||
}
|
return fmt.Errorf("Error configuring %s: %s", name, err)
|
||||||
|
|
||||||
found := false
|
|
||||||
for _, k := range md.Keys {
|
|
||||||
if k == "compression_level" {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
|
||||||
p.config.CompressionLevel = flate.DefaultCompression
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate any errors
|
|
||||||
errs := common.CheckUnusedConfig(md)
|
|
||||||
|
|
||||||
validates := map[string]*string{
|
|
||||||
"output": &p.config.OutputPath,
|
|
||||||
"vagrantfile_template": &p.config.VagrantfileTemplate,
|
|
||||||
}
|
|
||||||
|
|
||||||
for n, ptr := range validates {
|
|
||||||
if err := p.config.tpl.Validate(*ptr); err != nil {
|
|
||||||
errs = packer.MultiErrorAppend(
|
|
||||||
errs, fmt.Errorf("Error parsing %s: %s", n, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if errs != nil && len(errs.Errors) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +75,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
panic(fmt.Sprintf("bad provider name: %s", name))
|
panic(fmt.Sprintf("bad provider name: %s", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config := p.configs[""]
|
||||||
|
if specificConfig, ok := p.configs[name]; ok {
|
||||||
|
config = specificConfig
|
||||||
|
}
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", name))
|
ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", name))
|
||||||
|
|
||||||
outputPath, err := p.config.tpl.Process(p.config.OutputPath, &outputPathTemplate{
|
outputPath, err := config.tpl.Process(config.OutputPath, &outputPathTemplate{
|
||||||
ArtifactId: artifact.Id(),
|
ArtifactId: artifact.Id(),
|
||||||
BuildName: p.config.PackerBuildName,
|
BuildName: config.PackerBuildName,
|
||||||
Provider: name,
|
Provider: name,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -121,7 +99,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
// Copy all of the includes files into the temporary directory
|
// Copy all of the includes files into the temporary directory
|
||||||
for _, src := range p.config.Include {
|
for _, src := range config.Include {
|
||||||
ui.Message(fmt.Sprintf("Copying from include: %s", src))
|
ui.Message(fmt.Sprintf("Copying from include: %s", src))
|
||||||
dst := filepath.Join(dir, filepath.Base(src))
|
dst := filepath.Join(dir, filepath.Base(src))
|
||||||
if err := CopyContents(dst, src); err != nil {
|
if err := CopyContents(dst, src); err != nil {
|
||||||
|
@ -143,10 +121,10 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
|
|
||||||
// Write our Vagrantfile
|
// Write our Vagrantfile
|
||||||
var customVagrantfile string
|
var customVagrantfile string
|
||||||
if p.config.VagrantfileTemplate != "" {
|
if config.VagrantfileTemplate != "" {
|
||||||
ui.Message(fmt.Sprintf(
|
ui.Message(fmt.Sprintf(
|
||||||
"Using custom Vagrantfile: %s", p.config.VagrantfileTemplate))
|
"Using custom Vagrantfile: %s", config.VagrantfileTemplate))
|
||||||
customBytes, err := ioutil.ReadFile(p.config.VagrantfileTemplate)
|
customBytes, err := ioutil.ReadFile(config.VagrantfileTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
@ -170,13 +148,64 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the box
|
// Create the box
|
||||||
if err := DirToBox(outputPath, dir, ui, p.config.CompressionLevel); err != nil {
|
if err := DirToBox(outputPath, dir, ui, config.CompressionLevel); err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PostProcessor) configureSingle(config *Config, raws ...interface{}) error {
|
||||||
|
md, err := common.DecodeConfig(config, raws...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config.tpl, err = packer.NewConfigTemplate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.tpl.UserVars = config.PackerUserVars
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
if config.OutputPath == "" {
|
||||||
|
config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, k := range md.Keys {
|
||||||
|
if k == "compression_level" {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
config.CompressionLevel = flate.DefaultCompression
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate any errors
|
||||||
|
errs := common.CheckUnusedConfig(md)
|
||||||
|
|
||||||
|
validates := map[string]*string{
|
||||||
|
"output": &config.OutputPath,
|
||||||
|
"vagrantfile_template": &config.VagrantfileTemplate,
|
||||||
|
}
|
||||||
|
|
||||||
|
for n, ptr := range validates {
|
||||||
|
if err := config.tpl.Validate(*ptr); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, fmt.Errorf("Error parsing %s: %s", n, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func providerForName(name string) Provider {
|
func providerForName(name string) Provider {
|
||||||
switch name {
|
switch name {
|
||||||
case "virtualbox":
|
case "virtualbox":
|
||||||
|
|
|
@ -42,8 +42,9 @@ func TestPostProcessorPrepare_compressionLevel(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.CompressionLevel != flate.DefaultCompression {
|
config := p.configs[""]
|
||||||
t.Fatalf("bad: %#v", p.config.CompressionLevel)
|
if config.CompressionLevel != flate.DefaultCompression {
|
||||||
|
t.Fatalf("bad: %#v", config.CompressionLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
|
@ -53,8 +54,9 @@ func TestPostProcessorPrepare_compressionLevel(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.CompressionLevel != 7 {
|
config = p.configs[""]
|
||||||
t.Fatalf("bad: %#v", p.config.CompressionLevel)
|
if config.CompressionLevel != 7 {
|
||||||
|
t.Fatalf("bad: %#v", config.CompressionLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +79,40 @@ func TestPostProcessorPrepare_outputPath(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPostProcessorPrepare_subConfigs(t *testing.T) {
|
||||||
|
var p PostProcessor
|
||||||
|
|
||||||
|
// Default
|
||||||
|
c := testConfig()
|
||||||
|
c["compression_level"] = 42
|
||||||
|
c["vagrantfile_template"] = "foo"
|
||||||
|
c["override"] = map[string]interface{}{
|
||||||
|
"aws": map[string]interface{}{
|
||||||
|
"compression_level": 7,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := p.Configure(c)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.configs[""].CompressionLevel != 42 {
|
||||||
|
t.Fatalf("bad: %#v", p.configs[""].CompressionLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.configs[""].VagrantfileTemplate != "foo" {
|
||||||
|
t.Fatalf("bad: %#v", p.configs[""].VagrantfileTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.configs["aws"].CompressionLevel != 7 {
|
||||||
|
t.Fatalf("bad: %#v", p.configs["aws"].CompressionLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.configs["aws"].VagrantfileTemplate != "foo" {
|
||||||
|
t.Fatalf("bad: %#v", p.configs["aws"].VagrantfileTemplate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPostProcessorPostProcess_badId(t *testing.T) {
|
func TestPostProcessorPostProcess_badId(t *testing.T) {
|
||||||
artifact := &packer.MockArtifact{
|
artifact := &packer.MockArtifact{
|
||||||
BuilderIdValue: "invalid.packer",
|
BuilderIdValue: "invalid.packer",
|
||||||
|
|
|
@ -68,3 +68,32 @@ below, with more details about certain options in following sections.
|
||||||
|
|
||||||
* `vagrantfile_template` (string) - Path to a template to use for the
|
* `vagrantfile_template` (string) - Path to a template to use for the
|
||||||
Vagrantfile that is packaged with the box.
|
Vagrantfile that is packaged with the box.
|
||||||
|
|
||||||
|
## Provider-Specific Overrides
|
||||||
|
|
||||||
|
If you have a Packer template with multiple builder types within it,
|
||||||
|
you may want to configure the box creation for each type a little differently.
|
||||||
|
For example, the contents of the Vagrantfile for a Vagrant box for AWS might
|
||||||
|
be different from the contents of the Vagrantfile you want for VMware.
|
||||||
|
The post-processor lets you do this.
|
||||||
|
|
||||||
|
Specify overrides within the `override` configuration by provider name:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "vagrant",
|
||||||
|
|
||||||
|
"compression_level": 1,
|
||||||
|
"override": {
|
||||||
|
"vmware": {
|
||||||
|
"compression_level": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the example above, the compression level will be set to 1 except for
|
||||||
|
VMware, where it will be set to 0.
|
||||||
|
|
||||||
|
The available provider names are: `aws`, `digitalocean`, `virtualbox`,
|
||||||
|
and `vmware`.
|
||||||
|
|
Loading…
Reference in New Issue