From e46aa7b6d2342ae50c365fac2b839a25ddba5b71 Mon Sep 17 00:00:00 2001 From: Serge Smertin <259697+nfx@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:45:26 +0100 Subject: [PATCH 1/4] Add `darwin` build --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 14b540e8..5de0c1b1 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -37,6 +37,7 @@ builds: - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= ' goos: - linux + - darwin goarch: - amd64 - '386' From 97a7a42a6de7fdc7d9e9955ab12607d1c0b13b67 Mon Sep 17 00:00:00 2001 From: Serge Smertin <259697+nfx@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:50:10 +0100 Subject: [PATCH 2/4] more --- .goreleaser.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 5de0c1b1..b5c30b0f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -25,6 +25,7 @@ builds: - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= ' goos: - linux + - darwin goarch: - amd64 binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' @@ -57,6 +58,7 @@ builds: - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= ' goos: - linux + - darwin goarch: - amd64 - '386' From eefec3418e6649064741609d37e93f19b7a0cc60 Mon Sep 17 00:00:00 2001 From: Serge Smertin <259697+nfx@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:52:50 +0100 Subject: [PATCH 3/4] fix --- docs/builders/arm-image.mdx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/builders/arm-image.mdx b/docs/builders/arm-image.mdx index 09a1dd1b..f2db357f 100644 --- a/docs/builders/arm-image.mdx +++ b/docs/builders/arm-image.mdx @@ -86,6 +86,10 @@ a [communicator](/docs/templates/legacy_json_templates/communicator) can be conf If not provided, we will try to deduce it from the image url. (see autoDetectType()) For list of valid values, see: pkg/image/utils/images.go +- `image_arch` (arch.KnownArchType) - Image's target CPU architecture. + This is used to determine if qemu is necessary and which flavor to use. + Defaults to "arm". For list of valid values, see: pkg/image/arch/arch.go + - `image_mounts` ([]string) - Where to mounts the image partitions in the chroot. first entry is the mount point of the first partition. etc.. @@ -111,7 +115,7 @@ a [communicator](/docs/templates/legacy_json_templates/communicator) can be conf fill up this much room. I.e. if the generated image is 256MB and TargetImageSize is set to 384MB the last partition will be extended with an additional 128MB. -- `qemu_binary` (string) - Qemu binary to use. default is qemu-arm-static +- `qemu_binary` (string) - Qemu binary to use. default is determined based on `image_arch`. If this is an absolute path, it will be used. Otherwise, we will look for one in your PATH and finally, try to auto fetch one from https://github.com/multiarch/qemu-user-static/ @@ -119,6 +123,9 @@ a [communicator](/docs/templates/legacy_json_templates/communicator) can be conf - `qemu_args` ([]string) - Arguments to qemu binary. default depends on the image type. see init() function above. +- `qemu_required` (bool) - Use qemu even when the build machine's CPU architecture matches the image's CPU architecture. + Defaults to true if non-default `qemu_binary` or `qemu_args` are supplied. + From b7bf6047be0313d0c10a6b1c12590505a16412da Mon Sep 17 00:00:00 2001 From: Serge Smertin <259697+nfx@users.noreply.github.com> Date: Sat, 7 Jan 2023 19:18:57 +0100 Subject: [PATCH 4/4] added loopback mount for macOS --- .goreleaser.yml | 2 + pkg/builder/step_map_image_darwin.go | 98 +++++++++++++++++++ ...p_map_image.go => step_map_image_linux.go} | 3 + 3 files changed, 103 insertions(+) create mode 100644 pkg/builder/step_map_image_darwin.go rename pkg/builder/{step_map_image.go => step_map_image_linux.go} (98%) diff --git a/.goreleaser.yml b/.goreleaser.yml index b5c30b0f..cec2480c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -74,6 +74,8 @@ checksum: name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS' algorithm: sha256 + + release: # If you want to manually examine the release before its live, uncomment this line: # draft: true diff --git a/pkg/builder/step_map_image_darwin.go b/pkg/builder/step_map_image_darwin.go new file mode 100644 index 00000000..0d00ce6d --- /dev/null +++ b/pkg/builder/step_map_image_darwin.go @@ -0,0 +1,98 @@ +//go:build darwin +// +build darwin + +package builder + +import ( + "context" + "fmt" + "os/exec" + "regexp" + "sort" + "strings" + + "github.com/hashicorp/packer-plugin-sdk/multistep" + "github.com/hashicorp/packer-plugin-sdk/packer" +) + +type stepMapImage struct { + ImageKey string + ResultKey string +} + +var ( + whitespaceRe = regexp.MustCompile(`\s+`) + diskRe = regexp.MustCompile(`(?m)^(/dev/disk[0-9]+)[a-z][0-9]+$`) +) + +func (s *stepMapImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // Read our value and assert that it is the type we want + image := state.Get(s.ImageKey).(string) + ui := state.Get("ui").(packer.Ui) + + ui.Message(fmt.Sprintf("mapping %s", image)) + + // Attach disk image + // -nomount same as -mount suppressed + // -imagekey diskimage-class=CRawDiskImage + // Output example: + // /dev/disk2 FDisk_partition_scheme + // /dev/disk2s1 Windows_FAT_32 + // /dev/disk2s2 Linux + out, err := exec.Command("hdiutil", "attach", + "-imagekey", "diskimage-class=CRawDiskImage", + "-nomount", image).CombinedOutput() + cmd := fmt.Sprintf("hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount %s", image) + ui.Say(cmd) + if err != nil { + ui.Error(fmt.Sprintf("error %s %v: %s", cmd, err, string(out))) + s.Cleanup(state) + return multistep.ActionHalt + } + + // Look for all partitions of created loopback + var partitions []string + lines := strings.Split(string(out), "\n") + + // make sure /dev/disk2 is always the first line, + // also to make sure disks match the partition map. + sort.Strings(lines) + for _, l := range lines { + split := whitespaceRe.Split(strings.TrimSpace(l), -1) + if len(split) != 2 { + continue + } + partition := split[0] + if !diskRe.MatchString(partition) { + continue + } + partitions = append(partitions, partition) + } + + state.Put(s.ResultKey, partitions) + + return multistep.ActionContinue +} + +func (s *stepMapImage) Cleanup(state multistep.StateBag) { + switch partitions := state.Get(s.ResultKey).(type) { + case nil: + return + case []string: + if len(partitions) > 0 { + // Convert /dev/disk2s1 into /dev/disk2 + matches := diskRe.FindAllStringSubmatch(partitions[0], -1) + if len(matches) == 0 { + // must not happen + return + } + if len(matches[0]) == 0 { + // must not happen + return + } + disk := matches[0][1] + run(context.TODO(), state, fmt.Sprintf( + "hdiutil eject -force %s", disk)) + } + } +} diff --git a/pkg/builder/step_map_image.go b/pkg/builder/step_map_image_linux.go similarity index 98% rename from pkg/builder/step_map_image.go rename to pkg/builder/step_map_image_linux.go index 91583aa4..e0fe247b 100644 --- a/pkg/builder/step_map_image.go +++ b/pkg/builder/step_map_image_linux.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + package builder import (