diff --git a/plugin/post-processor-artifice/main.go b/plugin/post-processor-artifice/main.go new file mode 100644 index 000000000..c503e1572 --- /dev/null +++ b/plugin/post-processor-artifice/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/mitchellh/packer/packer/plugin" + "github.com/mitchellh/packer/post-processor/artifice" +) + +func main() { + server, err := plugin.Server() + if err != nil { + panic(err) + } + server.RegisterPostProcessor(new(artifice.PostProcessor)) + server.Serve() +} diff --git a/post-processor/artifice/artifact.go b/post-processor/artifice/artifact.go new file mode 100644 index 000000000..cb344b8e2 --- /dev/null +++ b/post-processor/artifice/artifact.go @@ -0,0 +1,56 @@ +package artifice + +import ( + "fmt" + "os" + "strings" +) + +const BuilderId = "packer.post-processor.artifice" + +type Artifact struct { + files []string +} + +func NewArtifact(files []string) (*Artifact, error) { + for _, f := range files { + if _, err := os.Stat(f); err != nil { + return nil, err + } + } + artifact := &Artifact{ + files: files, + } + return artifact, nil +} + +func (a *Artifact) BuilderId() string { + return BuilderId +} + +func (a *Artifact) Files() []string { + return a.files +} + +func (a *Artifact) Id() string { + return "" +} + +func (a *Artifact) String() string { + files := strings.Join(a.files, ", ") + return fmt.Sprintf("Created artifact from files: %s", files) +} + +func (a *Artifact) State(name string) interface{} { + return nil +} + +func (a *Artifact) Destroy() error { + for _, f := range a.files { + err := os.RemoveAll(f) + if err != nil { + return err + } + } + return nil +} diff --git a/post-processor/artifice/post-processor.go b/post-processor/artifice/post-processor.go new file mode 100644 index 000000000..ff33184de --- /dev/null +++ b/post-processor/artifice/post-processor.go @@ -0,0 +1,60 @@ +package artifice + +import ( + "fmt" + "strings" + + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/helper/config" + "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/template/interpolate" +) + +// The artifact-override post-processor allows you to specify arbitrary files as +// artifacts. These will override any other artifacts created by the builder. +// This allows you to use a builder and provisioner to create some file, such as +// a compiled binary or tarball, extract it from the builder (VM or container) +// and then save that binary or tarball and throw away the builder. + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + + Files []string `mapstructure:"files"` + Keep bool `mapstructure:"keep_input_artifact"` + + ctx interpolate.Context +} + +type PostProcessor struct { + config Config +} + +func (p *PostProcessor) Configure(raws ...interface{}) error { + err := config.Decode(&p.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &p.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{}, + }, + }, raws...) + if err != nil { + return err + } + + if len(p.config.Files) == 0 { + return fmt.Errorf("No files specified in artifice configuration") + } + + return nil +} + +func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { + if len(artifact.Files()) > 0 { + ui.Say(fmt.Sprintf("Discarding artifact files: %s", strings.Join(artifact.Files(), ", "))) + } + + artifact, err := NewArtifact(p.config.Files) + ui.Say(fmt.Sprintf("Using these artifact files: %s", strings.Join(artifact.Files(), ", "))) + + return artifact, true, err +} diff --git a/post-processor/artifice/post-processor_test.go b/post-processor/artifice/post-processor_test.go new file mode 100644 index 000000000..7e087e3e8 --- /dev/null +++ b/post-processor/artifice/post-processor_test.go @@ -0,0 +1 @@ +package artifice