Merge pull request #9239 from hashicorp/enable_artifice
Add Artifice postprocessor ID to valid artifacts for postprocessors t…
This commit is contained in:
commit
3c782e9d03
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"github.com/hashicorp/packer/post-processor/artifice"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
"golang.org/x/oauth2/jwt"
|
"golang.org/x/oauth2/jwt"
|
||||||
)
|
)
|
||||||
|
@ -92,9 +93,12 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
if artifact.BuilderId() != googlecompute.BuilderId {
|
switch artifact.BuilderId() {
|
||||||
|
case googlecompute.BuilderId, artifice.BuilderId:
|
||||||
|
break
|
||||||
|
default:
|
||||||
err := fmt.Errorf(
|
err := fmt.Errorf(
|
||||||
"Unknown artifact type: %s\nCan only export from Google Compute Engine builder artifacts.",
|
"Unknown artifact type: %s\nCan only export from Google Compute Engine builder and Artifice post-processor artifacts.",
|
||||||
artifact.BuilderId())
|
artifact.BuilderId())
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/common"
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"github.com/hashicorp/packer/post-processor/artifice"
|
||||||
"github.com/hashicorp/packer/post-processor/compress"
|
"github.com/hashicorp/packer/post-processor/compress"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
@ -123,9 +124,12 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if artifact.BuilderId() != compress.BuilderId {
|
switch artifact.BuilderId() {
|
||||||
err = fmt.Errorf(
|
case compress.BuilderId, artifice.BuilderId:
|
||||||
"incompatible artifact type: %s\nCan only import from Compress post-processor artifacts",
|
break
|
||||||
|
default:
|
||||||
|
err := fmt.Errorf(
|
||||||
|
"Unknown artifact type: %s\nCan only import from Compress post-processor and Artifice post-processor artifacts.",
|
||||||
artifact.BuilderId())
|
artifact.BuilderId())
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
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) {
|
||||||
if _, ok := builtins[artifact.BuilderId()]; !ok {
|
if _, ok := builtins[artifact.BuilderId()]; !ok {
|
||||||
return nil, false, false, fmt.Errorf(
|
return nil, false, false, fmt.Errorf(
|
||||||
"Unknown artifact type, requires box from vagrant post-processor or vagrant builder: %s", artifact.BuilderId())
|
"Unknown artifact type: this post-processor requires an input artifact from the artifice post-processor, vagrant post-processor, or vagrant builder: %s", artifact.BuilderId())
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume that there is only one .box file to upload
|
// We assume that there is only one .box file to upload
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -19,6 +20,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/packer/tmp"
|
"github.com/hashicorp/packer/packer/tmp"
|
||||||
|
"github.com/hashicorp/packer/post-processor/artifice"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
@ -42,6 +44,21 @@ var builtins = map[string]string{
|
||||||
"packer.post-processor.docker-push": "docker",
|
"packer.post-processor.docker-push": "docker",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
common.PackerConfig `mapstructure:",squash"`
|
common.PackerConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
|
@ -51,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
|
||||||
}
|
}
|
||||||
|
@ -67,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,18 +202,28 @@ 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 == "" {
|
||||||
|
n, ok := builtins[artifact.BuilderId()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, false, fmt.Errorf(
|
return nil, false, false, fmt.Errorf(
|
||||||
"Unknown artifact type, can't build box: %s", artifact.BuilderId())
|
"Unknown artifact type, can't build box: %s", artifact.BuilderId())
|
||||||
}
|
}
|
||||||
|
name = n
|
||||||
|
}
|
||||||
|
|
||||||
provider := providerForName(name)
|
provider := providerForName(name)
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
|
if artifact.BuilderId() == artifice.BuilderId {
|
||||||
|
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
|
// This shouldn't happen since we hard code all of these ourselves
|
||||||
panic(fmt.Sprintf("bad provider name: %s", name))
|
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)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ type FlatConfig struct {
|
||||||
Override map[string]interface{} `cty:"override"`
|
Override map[string]interface{} `cty:"override"`
|
||||||
VagrantfileTemplate *string `mapstructure:"vagrantfile_template" cty:"vagrantfile_template"`
|
VagrantfileTemplate *string `mapstructure:"vagrantfile_template" cty:"vagrantfile_template"`
|
||||||
VagrantfileTemplateGenerated *bool `mapstructure:"vagrantfile_template_generated" cty:"vagrantfile_template_generated"`
|
VagrantfileTemplateGenerated *bool `mapstructure:"vagrantfile_template_generated" cty:"vagrantfile_template_generated"`
|
||||||
|
ProviderOverride *string `mapstructure:"provider_override" cty:"provider_override"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlatMapstructure returns a new FlatConfig.
|
// FlatMapstructure returns a new FlatConfig.
|
||||||
|
@ -49,6 +50,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"override": &hcldec.AttrSpec{Name: "override", Type: cty.Map(cty.String), Required: false},
|
"override": &hcldec.AttrSpec{Name: "override", Type: cty.Map(cty.String), Required: false},
|
||||||
"vagrantfile_template": &hcldec.AttrSpec{Name: "vagrantfile_template", Type: cty.String, Required: false},
|
"vagrantfile_template": &hcldec.AttrSpec{Name: "vagrantfile_template", Type: cty.String, Required: false},
|
||||||
"vagrantfile_template_generated": &hcldec.AttrSpec{Name: "vagrantfile_template_generated", Type: cty.Bool, Required: false},
|
"vagrantfile_template_generated": &hcldec.AttrSpec{Name: "vagrantfile_template_generated", Type: cty.Bool, Required: false},
|
||||||
|
"provider_override": &hcldec.AttrSpec{Name: "provider_override", Type: cty.String, Required: false},
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"github.com/hashicorp/packer/post-processor/artifice"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
"github.com/vmware/govmomi"
|
"github.com/vmware/govmomi"
|
||||||
)
|
)
|
||||||
|
@ -27,6 +28,7 @@ var builtins = map[string]string{
|
||||||
vspherepost.BuilderId: "vmware",
|
vspherepost.BuilderId: "vmware",
|
||||||
vmwcommon.BuilderIdESX: "vmware",
|
vmwcommon.BuilderIdESX: "vmware",
|
||||||
vsphere.BuilderId: "vsphere",
|
vsphere.BuilderId: "vsphere",
|
||||||
|
artifice.BuilderId: "artifice",
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"github.com/hashicorp/packer/post-processor/artifice"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -106,9 +107,12 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
if artifact.BuilderId() != yandex.BuilderID {
|
switch artifact.BuilderId() {
|
||||||
|
case yandex.BuilderID, artifice.BuilderId:
|
||||||
|
break
|
||||||
|
default:
|
||||||
err := fmt.Errorf(
|
err := fmt.Errorf(
|
||||||
"Unknown artifact type: %s\nCan only export from Yandex Cloud builder artifacts.",
|
"Unknown artifact type: %s\nCan only export from Yandex Cloud builder artifact or Artifice post-processor artifact.",
|
||||||
artifact.BuilderId())
|
artifact.BuilderId())
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Reference in New Issue