make artifice post-processor play nicely with vagrant post-processor, including template validation., Update docs for each.

pull/9239/head
Megan Marsh 6 years ago
parent b982d987a7
commit 557eb015ea

@ -12,6 +12,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"text/template" "text/template"
"github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/hcl/v2/hcldec"
@ -41,7 +42,21 @@ var builtins = map[string]string{
"packer.post-processor.docker-import": "docker", "packer.post-processor.docker-import": "docker",
"packer.post-processor.docker-tag": "docker", "packer.post-processor.docker-tag": "docker",
"packer.post-processor.docker-push": "docker", "packer.post-processor.docker-push": "docker",
artifice.BuilderId: "artifice", }
func availableProviders() []string {
dedupedProvidersMap := map[string]string{}
for _, v := range builtins {
dedupedProvidersMap[v] = v
}
dedupedProviders := []string{}
for k := range dedupedProvidersMap {
dedupedProviders = append(dedupedProviders, k)
}
return dedupedProviders
} }
type Config struct { type Config struct {
@ -53,6 +68,7 @@ type Config struct {
Override map[string]interface{} Override map[string]interface{}
VagrantfileTemplate string `mapstructure:"vagrantfile_template"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
VagrantfileTemplateGenerated bool `mapstructure:"vagrantfile_template_generated"` VagrantfileTemplateGenerated bool `mapstructure:"vagrantfile_template_generated"`
ProviderOverride string `mapstructure:"provider_override"`
ctx interpolate.Context ctx interpolate.Context
} }
@ -69,6 +85,22 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
if err := p.configureSingle(&p.config, raws...); err != nil { if err := p.configureSingle(&p.config, raws...); err != nil {
return err return err
} }
if p.config.ProviderOverride != "" {
validOverride := false
providers := availableProviders()
for _, prov := range providers {
if prov == p.config.ProviderOverride {
validOverride = true
break
}
}
if !validOverride {
return fmt.Errorf("The given provider_override %s is not valid. "+
"Please choose from one of %s", p.config.ProviderOverride,
strings.Join(providers, ", "))
}
}
return nil return nil
} }
@ -170,17 +202,27 @@ func (p *PostProcessor) PostProcessProvider(name string, provider Provider, ui p
} }
func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) { func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) {
name := p.config.ProviderOverride
name, ok := builtins[artifact.BuilderId()] if name == "" {
if !ok { n, ok := builtins[artifact.BuilderId()]
return nil, false, false, fmt.Errorf( if !ok {
"Unknown artifact type, can't build box: %s", artifact.BuilderId()) return nil, false, false, fmt.Errorf(
"Unknown artifact type, can't build box: %s", artifact.BuilderId())
}
name = n
} }
provider := providerForName(name) provider := providerForName(name)
if provider == nil { if provider == nil {
// This shouldn't happen since we hard code all of these ourselves if artifact.BuilderId() == artifice.BuilderId {
panic(fmt.Sprintf("bad provider name: %s", name)) return nil, false, false, fmt.Errorf(
"Unknown provider type: When using an artifact created by " +
"the artifice post-processor, you need to set the " +
"provider_override option.")
} else {
// This shouldn't happen since we hard code all of these ourselves
panic(fmt.Sprintf("bad provider name: %s", name))
}
} }
artifact, keep, err := p.PostProcessProvider(name, provider, ui, artifact) artifact, keep, err := p.PostProcessProvider(name, provider, ui, artifact)

@ -164,6 +164,24 @@ func TestPostProcessorPrepare_vagrantfileTemplateExists(t *testing.T) {
} }
} }
func TestPostProcessorPrepare_ProviderOverrideExists(t *testing.T) {
c := testConfig()
c["provider_override"] = "foo"
var p PostProcessor
if err := p.Configure(c); err == nil {
t.Fatal("Should have errored since foo is not a valid vagrant provider")
}
c = testConfig()
c["provider_override"] = "aws"
if err := p.Configure(c); err != nil {
t.Fatal("Should not have errored since aws is a valid vagrant provider")
}
}
func TestPostProcessorPostProcess_badId(t *testing.T) { func TestPostProcessorPostProcess_badId(t *testing.T) {
artifact := &packer.MockArtifact{ artifact := &packer.MockArtifact{
BuilderIdValue: "invalid.packer", BuilderIdValue: "invalid.packer",

@ -23,16 +23,18 @@ Type: `artifice`
The artifice post-processor overrides the artifact list from an upstream The artifice post-processor overrides the artifact list from an upstream
builder or post-processor. All downstream post-processors will see the new builder or post-processor. All downstream post-processors will see the new
artifacts you specify. The primary use-case is to build artifacts inside a artifacts you specify.
packer builder -- for example, spinning up an EC2 instance to build a docker
container -- and then extracting the docker container and throwing away the EC2
instance.
After overriding the artifact with artifice, you can use it with other After overriding the artifact with artifice, you can use it with other
post-processors like post-processors, including most of the core post-processors and third-party
[compress](/docs/post-processors/compress), post-processors.
[docker-push](/docs/post-processors/docker-push), or
a third-party post-processor. A major benefit of this is that you can modify builder
artifacts using shell-local and pass those modified artifacts into
post-processors that may not have worked with the original builder.
For example, maybe you want to export a docker container from an amazon-ebs
builder and then use Docker-push to put that Docker container into your Docker
Hub account.
Artifice allows you to use the familiar packer workflow to create a fresh, Artifice allows you to use the familiar packer workflow to create a fresh,
stateless build environment for each build on the infrastructure of your stateless build environment for each build on the infrastructure of your

@ -94,6 +94,13 @@ more details about certain options in following sections.
By default, the value of this config is By default, the value of this config is
`packer_{{.BuildName}}_{{.Provider}}.box`. `packer_{{.BuildName}}_{{.Provider}}.box`.
- `provider_override` (string) - this option will override the internal logic
that decides which Vagrant provider to set for a particular Packer builder's
or post-processor's artifact. It is required when the artifact comes from the
Artifice post-processor, but is otherwise optional. Valid options are:
`digitalocean`, `virtualbox`, `azure`, `vmware`, `libvirt`, `docker`,
`lxc`, `scaleway`, `hyperv`, `parallels`, `aws`, or `google`.
- `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.
@ -179,3 +186,10 @@ accelerators: none, kvm, tcg, or hvf.
If you are using the Vagrant post-processor with the `vmware-esxi` builder, you If you are using the Vagrant post-processor with the `vmware-esxi` builder, you
must export the builder artifact locally; the Vagrant post-processor will must export the builder artifact locally; the Vagrant post-processor will
not work on remote artifacts. not work on remote artifacts.
### Artifice
If you are using this post-processor after defining an artifact using the
Artifice post-processor, then you must set the "provider_override" template
option so that the Vagrant post-processor knows what provider to use to create
the Vagrant box.

Loading…
Cancel
Save