Introduce a new step to collate build artifact at the end of the build
The new step collects together all the required build artifacts and places them in the output directory. * Reintroduce/add the code removed from step export to preserve the legacy export directory structure when skip_export is unset/false * Add a place holder for a future function that will move just the VHD files from the build directory to the output directory when skip_export is true * Add tests for current functionality and placeholder tests for future functions
This commit is contained in:
parent
ee7fa27ada
commit
32148168bd
|
@ -0,0 +1,57 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepCollateArtifacts struct {
|
||||||
|
OutputDir string
|
||||||
|
SkipExport bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs the step required to collate all build artifacts under the
|
||||||
|
// specified output directory
|
||||||
|
func (s *StepCollateArtifacts) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
driver := state.Get("driver").(Driver)
|
||||||
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
|
ui.Say("Collating build artifacts...")
|
||||||
|
|
||||||
|
if s.SkipExport {
|
||||||
|
// If the user has chosen to skip a full export of the VM the only
|
||||||
|
// artifacts that they are interested in will be the VHDs
|
||||||
|
|
||||||
|
// TODO: Grab the disks from the build directory and place them in
|
||||||
|
// a folder named 'Virtual Hard Disks' under the output directory
|
||||||
|
} else {
|
||||||
|
// Get the full path to the export directory from the statebag
|
||||||
|
var exportPath string
|
||||||
|
if v, ok := state.GetOk("export_path"); ok {
|
||||||
|
exportPath = v.(string)
|
||||||
|
}
|
||||||
|
// The export process exports the VM into a folder named 'vm name'
|
||||||
|
// under the output directory. However, to maintain backwards
|
||||||
|
// compatibility, we now need to shuffle around the exported folders
|
||||||
|
// so the 'Snapshots', 'Virtual Hard Disks' and 'Virtual Machines'
|
||||||
|
// directories appear *directly* under <output directory>.
|
||||||
|
// The empty '<output directory>/<vm name>' directory is removed
|
||||||
|
// when complete.
|
||||||
|
// The 'Snapshots' folder will not be moved into the output
|
||||||
|
// directory if it is empty.
|
||||||
|
err := driver.PreserveLegacyExportBehaviour(exportPath, s.OutputDir)
|
||||||
|
if err != nil {
|
||||||
|
// No need to halt here; Just warn the user instead
|
||||||
|
err = fmt.Errorf("WARNING: Error restoring legacy export dir structure: %s", err)
|
||||||
|
ui.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup does nothing
|
||||||
|
func (s *StepCollateArtifacts) Cleanup(state multistep.StateBag) {}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStepCollateArtifacts_impl(t *testing.T) {
|
||||||
|
var _ multistep.Step = new(StepCollateArtifacts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepCollateArtifacts_exportedArtifacts(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
step := new(StepCollateArtifacts)
|
||||||
|
|
||||||
|
step.OutputDir = "foopath"
|
||||||
|
vmName := "foo"
|
||||||
|
|
||||||
|
// Uses export path from the state bag
|
||||||
|
exportPath := filepath.Join(step.OutputDir, vmName)
|
||||||
|
state.Put("export_path", exportPath)
|
||||||
|
|
||||||
|
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 the driver
|
||||||
|
if !driver.PreserveLegacyExportBehaviour_Called {
|
||||||
|
t.Fatal("Should have called PreserveLegacyExportBehaviour")
|
||||||
|
}
|
||||||
|
if driver.PreserveLegacyExportBehaviour_SrcPath != exportPath {
|
||||||
|
t.Fatalf("Should call with correct srcPath. Got: %s Wanted: %s",
|
||||||
|
driver.PreserveLegacyExportBehaviour_SrcPath, exportPath)
|
||||||
|
}
|
||||||
|
if driver.PreserveLegacyExportBehaviour_DstPath != step.OutputDir {
|
||||||
|
t.Fatalf("Should call with correct dstPath. Got: %s Wanted: %s",
|
||||||
|
driver.PreserveLegacyExportBehaviour_DstPath, step.OutputDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Create MoveCreatedVHDsToOutput func etc
|
||||||
|
// if driver.MoveCreatedVHDsToOutput_Called {
|
||||||
|
// t.Fatal("Should NOT have called MoveCreatedVHDsToOutput")
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepCollateArtifacts_skipExportedArtifacts(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
step := new(StepCollateArtifacts)
|
||||||
|
|
||||||
|
// TODO: Needs the path to the main output directory
|
||||||
|
// outputDir := "foopath"
|
||||||
|
// Export has been skipped
|
||||||
|
step.SkipExport = true
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Create MoveCreatedVHDsToOutput func etc
|
||||||
|
// if !driver.MoveCreatedVHDsToOutput_Called {
|
||||||
|
// t.Fatal("Should have called MoveCreatedVHDsToOutput")
|
||||||
|
// }
|
||||||
|
|
||||||
|
if driver.PreserveLegacyExportBehaviour_Called {
|
||||||
|
t.Fatal("Should NOT have called PreserveLegacyExportBehaviour")
|
||||||
|
}
|
||||||
|
}
|
|
@ -465,6 +465,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
OutputDir: b.config.OutputDir,
|
OutputDir: b.config.OutputDir,
|
||||||
SkipExport: b.config.SkipExport,
|
SkipExport: b.config.SkipExport,
|
||||||
},
|
},
|
||||||
|
&hypervcommon.StepCollateArtifacts{
|
||||||
|
OutputDir: b.config.OutputDir,
|
||||||
|
SkipExport: b.config.SkipExport,
|
||||||
|
},
|
||||||
|
|
||||||
// the clean up actions for each step will be executed reverse order
|
// the clean up actions for each step will be executed reverse order
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,6 +482,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
OutputDir: b.config.OutputDir,
|
OutputDir: b.config.OutputDir,
|
||||||
SkipExport: b.config.SkipExport,
|
SkipExport: b.config.SkipExport,
|
||||||
},
|
},
|
||||||
|
&hypervcommon.StepCollateArtifacts{
|
||||||
|
OutputDir: b.config.OutputDir,
|
||||||
|
SkipExport: b.config.SkipExport,
|
||||||
|
},
|
||||||
|
|
||||||
// the clean up actions for each step will be executed reverse order
|
// the clean up actions for each step will be executed reverse order
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue