builder/virtualbox/common: Export
This commit is contained in:
parent
026bcd33fe
commit
5feb7bce18
|
@ -0,0 +1,37 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
)
|
||||
|
||||
type ExportConfig struct {
|
||||
Format string `mapstruture:"format"`
|
||||
}
|
||||
|
||||
func (c *ExportConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
if c.Format == "" {
|
||||
c.Format = "ovf"
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"format": &c.Format,
|
||||
}
|
||||
|
||||
errs := make([]error, 0)
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = t.Process(*ptr, nil)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||
}
|
||||
}
|
||||
|
||||
if c.Format != "ovf" && c.Format != "ova" {
|
||||
errs = append(errs,
|
||||
errors.New("invalid format, only 'ovf' or 'ova' are allowed"))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExportConfigPrepare_BootWait(t *testing.T) {
|
||||
var c *ExportConfig
|
||||
var errs []error
|
||||
|
||||
// Bad
|
||||
c = new(ExportConfig)
|
||||
c.Format = "illega"
|
||||
errs = c.Prepare(testConfigTemplate(t))
|
||||
if len(errs) == 0 {
|
||||
t.Fatalf("bad: %#v", errs)
|
||||
}
|
||||
|
||||
// Good
|
||||
c = new(ExportConfig)
|
||||
c.Format = "ova"
|
||||
errs = c.Prepare(testConfigTemplate(t))
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("should not have error: %s", errs)
|
||||
}
|
||||
|
||||
// Good
|
||||
c = new(ExportConfig)
|
||||
c.Format = "ovf"
|
||||
errs = c.Prepare(testConfigTemplate(t))
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("should not have error: %s", errs)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package iso
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"path/filepath"
|
||||
|
@ -16,11 +15,13 @@ import (
|
|||
//
|
||||
// Produces:
|
||||
// exportPath string - The path to the resulting export.
|
||||
type stepExport struct{}
|
||||
type StepExport struct {
|
||||
Format string
|
||||
OutputDir string
|
||||
}
|
||||
|
||||
func (s *stepExport) Run(state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*config)
|
||||
driver := state.Get("driver").(vboxcommon.Driver)
|
||||
func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction {
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vmName := state.Get("vmName").(string)
|
||||
|
||||
|
@ -42,7 +43,7 @@ func (s *stepExport) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
|
||||
// Export the VM to an OVF
|
||||
outputPath := filepath.Join(config.OutputDir, vmName+"."+config.Format)
|
||||
outputPath := filepath.Join(s.OutputDir, vmName+"."+s.Format)
|
||||
|
||||
command = []string{
|
||||
"export",
|
||||
|
@ -65,4 +66,4 @@ func (s *stepExport) Run(state multistep.StateBag) multistep.StepAction {
|
|||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepExport) Cleanup(state multistep.StateBag) {}
|
||||
func (s *StepExport) Cleanup(state multistep.StateBag) {}
|
|
@ -0,0 +1,43 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStepExport_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepExport)
|
||||
}
|
||||
|
||||
func TestStepExport(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepExport)
|
||||
|
||||
state.Put("vmName", "foo")
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test output state
|
||||
if _, ok := state.GetOk("exportPath"); !ok {
|
||||
t.Fatal("should set exportPath")
|
||||
}
|
||||
|
||||
// Test driver
|
||||
if len(driver.VBoxManageCalls) != 2 {
|
||||
t.Fatal("should call vboxmanage")
|
||||
}
|
||||
if driver.VBoxManageCalls[0][0] != "modifyvm" {
|
||||
t.Fatal("bad")
|
||||
}
|
||||
if driver.VBoxManageCalls[1][0] != "export" {
|
||||
t.Fatal("bad")
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ type Builder struct {
|
|||
|
||||
type config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
vboxcommon.ExportConfig `mapstructure:",squash"`
|
||||
vboxcommon.FloppyConfig `mapstructure:",squash"`
|
||||
vboxcommon.OutputConfig `mapstructure:",squash"`
|
||||
vboxcommon.RunConfig `mapstructure:",squash"`
|
||||
|
@ -37,7 +38,6 @@ type config struct {
|
|||
|
||||
BootCommand []string `mapstructure:"boot_command"`
|
||||
DiskSize uint `mapstructure:"disk_size"`
|
||||
Format string `mapstructure:"format"`
|
||||
GuestAdditionsMode string `mapstructure:"guest_additions_mode"`
|
||||
GuestAdditionsPath string `mapstructure:"guest_additions_path"`
|
||||
GuestAdditionsURL string `mapstructure:"guest_additions_url"`
|
||||
|
@ -72,6 +72,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
|
||||
// Accumulate any errors and warnings
|
||||
errs := common.CheckUnusedConfig(md)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.ExportConfig.Prepare(b.config.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(b.config.tpl)...)
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...)
|
||||
|
@ -116,10 +117,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName)
|
||||
}
|
||||
|
||||
if b.config.Format == "" {
|
||||
b.config.Format = "ovf"
|
||||
}
|
||||
|
||||
// Errors
|
||||
templates := map[string]*string{
|
||||
"guest_additions_mode": &b.config.GuestAdditionsMode,
|
||||
|
@ -132,7 +129,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
"iso_url": &b.config.RawSingleISOUrl,
|
||||
"virtualbox_version_file": &b.config.VBoxVersionFile,
|
||||
"vm_name": &b.config.VMName,
|
||||
"format": &b.config.Format,
|
||||
}
|
||||
|
||||
for n, ptr := range templates {
|
||||
|
@ -172,11 +168,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if !(b.config.Format == "ovf" || b.config.Format == "ova") {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("invalid format, only 'ovf' or 'ova' are allowed"))
|
||||
}
|
||||
|
||||
if b.config.HardDriveInterface != "ide" && b.config.HardDriveInterface != "sata" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("hard_drive_interface can only be ide or sata"))
|
||||
|
@ -317,7 +308,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Timeout: b.config.ShutdownTimeout,
|
||||
},
|
||||
new(vboxcommon.StepRemoveDevices),
|
||||
new(stepExport),
|
||||
&vboxcommon.StepExport{
|
||||
Format: b.config.Format,
|
||||
OutputDir: b.config.OutputDir,
|
||||
},
|
||||
}
|
||||
|
||||
// Setup the state bag
|
||||
|
|
|
@ -299,43 +299,6 @@ func TestBuilderPrepare_HTTPPort(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_Format(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Bad
|
||||
config["format"] = "illegal value"
|
||||
warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Good
|
||||
config["format"] = "ova"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Good
|
||||
config["format"] = "ovf"
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
|
|
@ -81,9 +81,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Timeout: b.config.ShutdownTimeout,
|
||||
},
|
||||
new(vboxcommon.StepRemoveDevices),
|
||||
/*
|
||||
new(stepExport),
|
||||
*/
|
||||
&vboxcommon.StepExport{
|
||||
Format: b.config.Format,
|
||||
OutputDir: b.config.OutputDir,
|
||||
},
|
||||
}
|
||||
|
||||
// Run the steps.
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
// Config is the configuration structure for the builder.
|
||||
type Config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
vboxcommon.ExportConfig `mapstructure:",squash"`
|
||||
vboxcommon.FloppyConfig `mapstructure:",squash"`
|
||||
vboxcommon.OutputConfig `mapstructure:",squash"`
|
||||
vboxcommon.RunConfig `mapstructure:",squash"`
|
||||
|
@ -34,6 +35,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
|
||||
// Prepare the errors
|
||||
errs := common.CheckUnusedConfig(md)
|
||||
errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(c.tpl)...)
|
||||
|
|
Loading…
Reference in New Issue