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 {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
|
||||
CompressionLevel int `mapstructure:"compression_level"`
|
||||
Include []string `mapstructure:"include"`
|
||||
OutputPath string `mapstructure:"output"`
|
||||
VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
|
||||
CompressionLevel int `mapstructure:"compression_level"`
|
||||
Override map[string]interface{}
|
||||
VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
|
||||
|
||||
tpl *packer.ConfigTemplate
|
||||
}
|
||||
|
||||
type PostProcessor struct {
|
||||
config Config
|
||||
configs map[string]*Config
|
||||
}
|
||||
|
||||
func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||
md, err := common.DecodeConfig(&p.config, raws...)
|
||||
if err != nil {
|
||||
p.configs = make(map[string]*Config)
|
||||
p.configs[""] = new(Config)
|
||||
if err := p.configureSingle(p.configs[""], raws...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.config.tpl, err = packer.NewConfigTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.config.tpl.UserVars = p.config.PackerUserVars
|
||||
// Go over any of the provider-specific overrides and load those up.
|
||||
for name, override := range p.configs[""].Override {
|
||||
subRaws := make([]interface{}, len(raws)+1)
|
||||
copy(subRaws, raws)
|
||||
subRaws[len(raws)] = override
|
||||
|
||||
// Defaults
|
||||
if p.config.OutputPath == "" {
|
||||
p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, k := range md.Keys {
|
||||
if k == "compression_level" {
|
||||
found = true
|
||||
break
|
||||
config := new(Config)
|
||||
p.configs[name] = config
|
||||
if err := p.configureSingle(config, subRaws...); err != nil {
|
||||
return fmt.Errorf("Error configuring %s: %s", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -102,11 +75,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
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))
|
||||
|
||||
outputPath, err := p.config.tpl.Process(p.config.OutputPath, &outputPathTemplate{
|
||||
outputPath, err := config.tpl.Process(config.OutputPath, &outputPathTemplate{
|
||||
ArtifactId: artifact.Id(),
|
||||
BuildName: p.config.PackerBuildName,
|
||||
BuildName: config.PackerBuildName,
|
||||
Provider: name,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -121,7 +99,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
defer os.RemoveAll(dir)
|
||||
|
||||
// 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))
|
||||
dst := filepath.Join(dir, filepath.Base(src))
|
||||
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
|
||||
var customVagrantfile string
|
||||
if p.config.VagrantfileTemplate != "" {
|
||||
if config.VagrantfileTemplate != "" {
|
||||
ui.Message(fmt.Sprintf(
|
||||
"Using custom Vagrantfile: %s", p.config.VagrantfileTemplate))
|
||||
customBytes, err := ioutil.ReadFile(p.config.VagrantfileTemplate)
|
||||
"Using custom Vagrantfile: %s", config.VagrantfileTemplate))
|
||||
customBytes, err := ioutil.ReadFile(config.VagrantfileTemplate)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
@ -170,13 +148,64 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
}
|
||||
|
||||
// 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, 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 {
|
||||
switch name {
|
||||
case "virtualbox":
|
||||
|
|
|
@ -42,8 +42,9 @@ func TestPostProcessorPrepare_compressionLevel(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if p.config.CompressionLevel != flate.DefaultCompression {
|
||||
t.Fatalf("bad: %#v", p.config.CompressionLevel)
|
||||
config := p.configs[""]
|
||||
if config.CompressionLevel != flate.DefaultCompression {
|
||||
t.Fatalf("bad: %#v", config.CompressionLevel)
|
||||
}
|
||||
|
||||
// Set
|
||||
|
@ -53,8 +54,9 @@ func TestPostProcessorPrepare_compressionLevel(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if p.config.CompressionLevel != 7 {
|
||||
t.Fatalf("bad: %#v", p.config.CompressionLevel)
|
||||
config = p.configs[""]
|
||||
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) {
|
||||
artifact := &packer.MockArtifact{
|
||||
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 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