Merge pull request #9174 from hashicorp/do_9145

output_filename virtualbox option.
pull/9187/head
Megan Marsh 6 years ago committed by GitHub
commit 279fbb45ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,6 +17,10 @@ type OutputConfig struct {
// the builder. By default this is output-BUILDNAME where "BUILDNAME" is the // the builder. By default this is output-BUILDNAME where "BUILDNAME" is the
// name of the build. // name of the build.
OutputDir string `mapstructure:"output_directory" required:"false"` OutputDir string `mapstructure:"output_directory" required:"false"`
// This is the base name of the file (excluding the file extension) where
// the resulting virtual machine will be created. By default this is the
// `vm_name`.
OutputFilename string `mapstructure:"output_filename" required:"false"`
} }
func (c *OutputConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error { func (c *OutputConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error {

@ -19,6 +19,7 @@ import (
type StepExport struct { type StepExport struct {
Format string Format string
OutputDir string OutputDir string
OutputFilename string
ExportOpts []string ExportOpts []string
Bundling VBoxBundleConfig Bundling VBoxBundleConfig
SkipNatMapping bool SkipNatMapping bool
@ -37,6 +38,9 @@ func (s *StepExport) Run(ctx context.Context, state multistep.StateBag) multiste
driver := state.Get("driver").(Driver) driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string) vmName := state.Get("vmName").(string)
if s.OutputFilename == "" {
s.OutputFilename = vmName
}
// Skip export if requested // Skip export if requested
if s.SkipExport { if s.SkipExport {
@ -61,7 +65,7 @@ func (s *StepExport) Run(ctx context.Context, state multistep.StateBag) multiste
} }
// Export the VM to an OVF // Export the VM to an OVF
outputPath := filepath.Join(s.OutputDir, vmName+"."+s.Format) outputPath := filepath.Join(s.OutputDir, s.OutputFilename+"."+s.Format)
command := []string{ command := []string{
"export", "export",

@ -2,6 +2,7 @@ package common
import ( import (
"context" "context"
"path/filepath"
"testing" "testing"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
@ -43,3 +44,71 @@ func TestStepExport(t *testing.T) {
t.Fatal("bad") t.Fatal("bad")
} }
} }
func TestStepExport_OutputPath(t *testing.T) {
type testCase struct {
Step *StepExport
Expected string
Reason string
}
tcs := []testCase{
{
Step: &StepExport{
Format: "ova",
OutputDir: "output-dir",
OutputFilename: "output-filename",
},
Expected: filepath.Join("output-dir", "output-filename.ova"),
Reason: "output_filename should not be vmName if set.",
},
{
Step: &StepExport{
Format: "ovf",
OutputDir: "output-dir",
OutputFilename: "",
},
Expected: filepath.Join("output-dir", "foo.ovf"),
Reason: "output_filename should default to vmName.",
},
}
for _, tc := range tcs {
state := testState(t)
state.Put("vmName", "foo")
// Test the run
if action := tc.Step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
// Test output state
path, ok := state.GetOk("exportPath")
if !ok {
t.Fatal("should set exportPath")
}
if path != tc.Expected {
t.Fatalf("Expected %s didn't match received %s: %s", tc.Expected, path, tc.Reason)
}
}
}
func TestStepExport_SkipExport(t *testing.T) {
state := testState(t)
step := StepExport{SkipExport: true}
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test driver
if len(driver.VBoxManageCalls) != 0 {
t.Fatal("shouldn't have called vboxmanage; skip_export was set.")
}
}

@ -396,6 +396,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
OutputFilename: b.config.OutputFilename,
ExportOpts: b.config.ExportConfig.ExportOpts, ExportOpts: b.config.ExportConfig.ExportOpts,
Bundling: b.config.VBoxBundleConfig, Bundling: b.config.VBoxBundleConfig,
SkipNatMapping: b.config.SkipNatMapping, SkipNatMapping: b.config.SkipNatMapping,

@ -35,6 +35,7 @@ type FlatConfig struct {
Format *string `mapstructure:"format" required:"false" cty:"format"` Format *string `mapstructure:"format" required:"false" cty:"format"`
ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"` ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"`
OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"` OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"`
OutputFilename *string `mapstructure:"output_filename" required:"false" cty:"output_filename"`
Headless *bool `mapstructure:"headless" required:"false" cty:"headless"` Headless *bool `mapstructure:"headless" required:"false" cty:"headless"`
VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"` VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"`
VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"` VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"`
@ -156,6 +157,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false},
"export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false}, "export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false},
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false}, "output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
"output_filename": &hcldec.AttrSpec{Name: "output_filename", Type: cty.String, Required: false},
"headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false}, "headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false},
"vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false}, "vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false},
"vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false}, "vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false},

@ -158,6 +158,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
OutputFilename: b.config.OutputFilename,
ExportOpts: b.config.ExportConfig.ExportOpts, ExportOpts: b.config.ExportConfig.ExportOpts,
SkipNatMapping: b.config.SkipNatMapping, SkipNatMapping: b.config.SkipNatMapping,
SkipExport: b.config.SkipExport, SkipExport: b.config.SkipExport,

@ -28,6 +28,7 @@ type FlatConfig struct {
Format *string `mapstructure:"format" required:"false" cty:"format"` Format *string `mapstructure:"format" required:"false" cty:"format"`
ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"` ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"`
OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"` OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"`
OutputFilename *string `mapstructure:"output_filename" required:"false" cty:"output_filename"`
Headless *bool `mapstructure:"headless" required:"false" cty:"headless"` Headless *bool `mapstructure:"headless" required:"false" cty:"headless"`
VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"` VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"`
VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"` VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"`
@ -135,6 +136,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false},
"export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false}, "export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false},
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false}, "output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
"output_filename": &hcldec.AttrSpec{Name: "output_filename", Type: cty.String, Required: false},
"headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false}, "headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false},
"vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false}, "vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false},
"vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false}, "vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false},

@ -141,6 +141,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
OutputFilename: b.config.OutputFilename,
ExportOpts: b.config.ExportOpts, ExportOpts: b.config.ExportOpts,
SkipNatMapping: b.config.SkipNatMapping, SkipNatMapping: b.config.SkipNatMapping,
SkipExport: b.config.SkipExport, SkipExport: b.config.SkipExport,

@ -28,6 +28,7 @@ type FlatConfig struct {
Format *string `mapstructure:"format" required:"false" cty:"format"` Format *string `mapstructure:"format" required:"false" cty:"format"`
ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"` ExportOpts []string `mapstructure:"export_opts" required:"false" cty:"export_opts"`
OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"` OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"`
OutputFilename *string `mapstructure:"output_filename" required:"false" cty:"output_filename"`
Headless *bool `mapstructure:"headless" required:"false" cty:"headless"` Headless *bool `mapstructure:"headless" required:"false" cty:"headless"`
VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"` VRDPBindAddress *string `mapstructure:"vrdp_bind_address" required:"false" cty:"vrdp_bind_address"`
VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"` VRDPPortMin *int `mapstructure:"vrdp_port_min" required:"false" cty:"vrdp_port_min"`
@ -131,6 +132,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false},
"export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false}, "export_opts": &hcldec.AttrSpec{Name: "export_opts", Type: cty.List(cty.String), Required: false},
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false}, "output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
"output_filename": &hcldec.AttrSpec{Name: "output_filename", Type: cty.String, Required: false},
"headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false}, "headless": &hcldec.AttrSpec{Name: "headless", Type: cty.Bool, Required: false},
"vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false}, "vrdp_bind_address": &hcldec.AttrSpec{Name: "vrdp_bind_address", Type: cty.String, Required: false},
"vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false}, "vrdp_port_min": &hcldec.AttrSpec{Name: "vrdp_port_min", Type: cty.Number, Required: false},

@ -6,4 +6,8 @@
is executed. This directory must not exist or be empty prior to running is executed. This directory must not exist or be empty prior to running
the builder. By default this is output-BUILDNAME where "BUILDNAME" is the the builder. By default this is output-BUILDNAME where "BUILDNAME" is the
name of the build. name of the build.
- `output_filename` (string) - This is the base name of the file (excluding the file extension) where
the resulting virtual machine will be created. By default this is the
`vm_name`.
Loading…
Cancel
Save