diff --git a/go.mod b/go.mod index 9f06ddc3..1e96f640 100644 --- a/go.mod +++ b/go.mod @@ -75,6 +75,7 @@ require ( github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -98,6 +99,7 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gotest.tools v2.2.0+incompatible // indirect ) replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.12.1 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187 diff --git a/go.sum b/go.sum index a12bdefd..c8062dcb 100644 --- a/go.sum +++ b/go.sum @@ -610,6 +610,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/post-processor/vagrant/libvirt.go b/post-processor/vagrant/libvirt.go index 82dcb18c..4b1ebc4a 100644 --- a/post-processor/vagrant/libvirt.go +++ b/post-processor/vagrant/libvirt.go @@ -7,6 +7,7 @@ import ( "fmt" "path/filepath" "strconv" + "strings" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -66,26 +67,28 @@ func (p *LibVirtProvider) KeepInputArtifact() bool { return false } func (p *LibVirtProvider) Process(ui packersdk.Ui, artifact packersdk.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + disks := []map[string]string{} + format := artifact.State("diskType").(string) diskName := artifact.State("diskName").(string) - - // Copy the disk image into the temporary directory (as box.img) + disk_index := 0 for _, path := range artifact.Files() { - if filepath.Base(path) == diskName { - ui.Message(fmt.Sprintf("Copying from artifact: %s", path)) - dstPath := filepath.Join(dir, "box.img") - if err = CopyContents(dstPath, path); err != nil { - return - } + // DiskName is [vmName, vmName-1, vmName-2] + if !strings.HasPrefix(filepath.Base(path), diskName) { + continue + } + ui.Message(fmt.Sprintf("Copying from artifact: %s", path)) + dstDiskName := fmt.Sprintf("box_%d.img", disk_index) + dstPath := filepath.Join(dir, dstDiskName) + disks = append(disks, map[string]string{ + "path": dstDiskName, + "format": format, + }) + disk_index++ + if err = CopyContents(dstPath, path); err != nil { + return } } - format := artifact.State("diskType").(string) - origSize := sizeInMegabytes(artifact.State("diskSize").(string)) - size := origSize / 1024 // In MB, want GB - if origSize%1024 > 0 { - // Make sure we don't make the size smaller - size++ - } domainType := artifact.State("domainType").(string) // Convert domain type to libvirt driver @@ -101,9 +104,8 @@ func (p *LibVirtProvider) Process(ui packersdk.Ui, artifact packersdk.Artifact, // Create the metadata metadata = map[string]interface{}{ - "provider": "libvirt", - "format": format, - "virtual_size": size, + "provider": "libvirt", + "disks": disks, } vagrantfile = fmt.Sprintf(libvirtVagrantfile, driver) diff --git a/post-processor/vagrant/libvirt_test.go b/post-processor/vagrant/libvirt_test.go index 016b1d84..c4df3bdf 100644 --- a/post-processor/vagrant/libvirt_test.go +++ b/post-processor/vagrant/libvirt_test.go @@ -5,7 +5,11 @@ package vagrant import ( "fmt" + "os" "testing" + + packersdk "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer-plugin-sdk/tmp" ) func assertSizeInMegabytes(t *testing.T, size string, expected uint64) { @@ -70,3 +74,81 @@ func Test_sizeInMegabytes_WithExabytesUnit(t *testing.T) { assertSizeInMegabytes(t, "1234E", 1234*1024*1024*1024*1024) assertSizeInMegabytes(t, "1E", 1*1024*1024*1024*1024) } + +func Test_ManyFilesInArtifact(t *testing.T) { + p := new(LibVirtProvider) + ui := testUi() + type testCases struct { + Files []string + Format string + FilesExpected []string + } + testcases := []testCases{ + { + []string{}, + "qcow2", + []string{}, + }, + { + []string{"test"}, + "vmdk", + []string{"box_0.img"}, + }, + { + []string{"test", "test-1", "test-2"}, + "qcow2", + []string{"box_0.img", "box_1.img", "box_2.img"}, + }, + { + []string{"test", "efivars.fd", "test-1", "test-2"}, + "qcow2", + []string{"box_0.img", "box_1.img", "box_2.img"}, + }, + } + for _, tc := range testcases { + dir, _ := tmp.Dir("pkr") + defer os.RemoveAll(dir) + + artifactFiles := []string{} + for _, file := range tc.Files { + fullFilePath := fmt.Sprintf("%s/%s", dir, file) + artifactFiles = append(artifactFiles, fullFilePath) + _, err := os.Create(fullFilePath) + if err != nil { + t.Fatalf("Can't create %s : %s", fullFilePath, err) + } + } + + artifact := &packersdk.MockArtifact{ + FilesValue: artifactFiles, + StateValues: map[string]interface{}{ + "diskType": tc.Format, + "diskSize": "1234M", + "diskName": "test", + "domainType": "kvm", + }, + } + + dirProcess, _ := tmp.Dir("process") + defer os.RemoveAll(dirProcess) + _, metadata, err := p.Process(ui, artifact, dirProcess) + + if err != nil { + t.Fatalf("should not have error: %s", err) + } + metaDisks := metadata["disks"].([]map[string]string) + if len(tc.FilesExpected) != len(metaDisks) { + t.Errorf("Expected %d disks, but test returned %d", len(tc.FilesExpected), len(metaDisks)) + } + + for i, disk := range metaDisks { + if tc.FilesExpected[i] != disk["path"] { + t.Errorf("%s. Expected %#v", "Disk files order must be respected", tc.FilesExpected[i]) + } + if tc.Format != disk["format"] { + t.Errorf("%s. Expected %#v", "Disk files format must be present", tc.Format) + } + } + } + +}