packer-builder-arm icon indicating copy to clipboard operation
packer-builder-arm copied to clipboard

How to build on Mac with Intel CPU?

Open a0s opened this issue 2 years ago • 6 comments

Hi! I am trying to build by instruction but something going wrong:

sudo packer build boards/odroid-xu4/ubuntu.json
arm: output will be in this color.

==> arm: Retrieving rootfs_archive
==> arm: Trying http://de.eu.odroid.in/ubuntu_18.04lts/XU3_XU4_MC1_HC1_HC2/ubuntu-18.04.1-4.14-mate-odroid-xu4-20181203.img.xz?archive=false
==> arm: Trying http://de.eu.odroid.in/ubuntu_18.04lts/XU3_XU4_MC1_HC1_HC2/ubuntu-18.04.1-4.14-mate-odroid-xu4-20181203.img.xz?archive=false&checksum=file%3Ahttp%3A%2F%2Fde.eu.odroid.in%2Fubuntu_18.04lts%2FXU3_XU4_MC1_HC1_HC2%2Fubuntu-18.04.1-4.14-mate-odroid-xu4-20181203.img.xz.md5sum
==> arm: http://de.eu.odroid.in/ubuntu_18.04lts/XU3_XU4_MC1_HC1_HC2/ubuntu-18.04.1-4.14-mate-odroid-xu4-20181203.img.xz?archive=false&checksum=file%3Ahttp%3A%2F%2Fde.eu.odroid.in%2Fubuntu_18.04lts%2FXU3_XU4_MC1_HC1_HC2%2Fubuntu-18.04.1-4.14-mate-odroid-xu4-20181203.img.xz.md5sum => /Users/a0s/3dprinting/packer-builder-arm/packer_cache/21d459da00cabdca71bd375bb18a3a46f7c67b96.xz
    arm: unpacking /Users/a0s/3dprinting/packer-builder-arm/packer_cache/21d459da00cabdca71bd375bb18a3a46f7c67b96.xz to odroid-xu4.img
    arm: unpacking with custom comand: [xz -d /tmp/image210140239/21d459da00cabdca71bd375bb18a3a46f7c67b96.xz]
    arm: searching for empty loop device (to map odroid-xu4.img)
==> arm: error losetup -f exec: "losetup": executable file not found in $PATH:
==> arm: error while unmounting loop device exec: "losetup": executable file not found in $PATH:
Build 'arm' errored after 1 minute 5 seconds: build was halted

==> Wait completed after 1 minute 5 seconds

==> Some builds didn't complete successfully and had errors:
--> arm: build was halted

==> Builds finished but no artifacts were created.

Am i missed something? brew install losetup get nothing. What additional dependencies i need to install?

Also, i tried build with docker (i have Docker on Mac installed):

docker build -t packer-builder-arm -f docker/Dockerfile .
[+] Building 144.7s (25/25) FINISHED
=> exporting to image                                                                                                                                        1.2s
 => => exporting layers                                                                                                                                       1.2s
 => => writing image sha256:e8f6edcfa3cb3f4e7befb57bbbc695d15bef9200ccafdc8bd8aec689c75d8578                                                                  0.0s
 => => naming to docker.io/library/packer-builder-arm

docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build  boards/odroid-xu4/ubuntu.json
uname -a:  Linux e3cf77b13aa4 5.10.25-linuxkit #1 SMP Tue Mar 23 09:27:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
installing: mips64 qemu-mips64 already registered
installing: riscv64 qemu-riscv64 already registered
installing: mips64le qemu-mips64el already registered
{
  "supported": [
    "linux/amd64",
    "linux/arm64",
    "linux/ppc64le",
    "linux/s390x",
    "linux/386",
    "linux/arm/v7",
    "linux/arm/v6"
  ],
  "emulators": [
    "qemu-aarch64",
    "qemu-arm",
    "qemu-mips64",
    "qemu-mips64el",
    "qemu-ppc64le",
    "qemu-riscv64",
    "qemu-s390x"
  ]
}
running /bin/packer build boards/odroid-xu4/ubuntu.json
Error: Failed to initialize build "arm"

error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec
format error



==> Wait completed after 15 microseconds

==> Builds finished but no artifacts were created.

Any help would be appreciate!

a0s avatar Aug 19 '21 08:08 a0s

I had the same issue. Digging in a bit, I found the following...

The problem:

  1. This affects both my x86 and M1 Mac systems.
  2. This is because MacOS does not have a 'losetup' command. The plugin assumes it is running in a Linux environment.

Needs Analysis:

  1. We need a MacOS equivalent to losetup -f (step_map_image.go @ 27)
           -f, --find [file]
           Find the first unused loop device. If a file argument is
           present, use the found device as loop device. Otherwise, just
           print its name.
    
  2. We need a MacOS equivalent to losetup -P (step_map_image.go @38)
    -P, --partscan
        Force the kernel to scan the partition table on a newly
        created loop device. Note that the partition table parsing
        depends on sector sizes. The default is sector size is 512
        bytes, otherwise you need to use the option --sector-size
        together with --partscan.
  1. We need a MacOS equivalent to losetup -d (step_map_image.go @54)
        -d, --detach loopdev...
            Detach the file or device associated with the specified loop
            device(s). Note that since Linux v3.7 kernel uses "lazy
            device destruction". The detach operation does not return
            EBUSY error anymore if device is actively used by system, but
            it is marked by autoclear flag and destroyed later.
    

Solution

  1. Obviously we could wrap the entire project I am working on and which others are using in a Vagrant-based VM to do local builds. That's probably not a bad idea, but it adds complexity.
  2. Alternatively the code would need to be operating-system aware and use hdiutil on MacOS and I'm not sure what to support Windows. Currently the project does not have this awareness.
  3. A third option is to use a Linux CI/CD pipeline (github actions or Bitbucket pipelines) and build images in a branched automation and skip local development.
  4. A fourth option might be to use a privileged docker container for this.

Summary

I'm debating whether or not to invest the time creating a fix here. I thought I would share my findings to help others. If I get time to put toward this, I will send a PR to this repo.

sam-caldwell-opentrons avatar Oct 27 '21 15:10 sam-caldwell-opentrons

I don't have a Mac, so can't help here. Depending on the complexity I'd go with a special handlers/steps for MacOS X (it could be as simple as finding equivalent tooling on mac or as hard as changing the whole flow).

mkaczanowski avatar Dec 27 '21 15:12 mkaczanowski

A fourth option might be to use a privileged docker container for this.

I understand why this won't run natively on macOS due to the dependency on losetup, but I'm a little unclear on why the privileged Docker container build documented in the README fails with

Error: Failed to initialize build "arm"

error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec format error

Might that be a simpler issue to fix? I'm actually hitting this exact same error with the Docker and Vagrant builds on packer-plugin-arm-image too. ~~Is it perhaps an issue with a newer version of Packer config syntax, or a need to upgrade these plugins to use the new plugin SDK for Packer v1.7 and later?~~

mikemorris avatar Dec 28 '21 03:12 mikemorris

Welp, think I figured this out. When using the Docker build, it appears the local directory is not linked into the Docker container (which is probably fine/expected), but this means the plugin binary must be installed to the .packer.d/plugins directory following the steps in manually (multi-component plugin) at https://www.packer.io/plugins#installing-plugins for Packer to find a plugin providing arm build support.

go build
mv packer-builder-arm ~/.packer.d/plugins

Adding support for the Packer 1.7 init command as described in https://github.com/mkaczanowski/packer-builder-arm/issues/100 might help avoid this confusion.

Actually, looking more closely at the Dockerfile, this might be an issue with a newer version of Go or specific to macOS - https://github.com/mkaczanowski/packer-builder-arm/blob/0eff8b7c5475cdca23dd28c2eba174df97585bf7/docker/Dockerfile#L52 assumes the binary will be built into ./build - running go build on my machine instead puts the binary into the repo root.

mikemorris avatar Feb 12 '22 14:02 mikemorris

Welp, think I figured this out. When using the Docker build, it appears the local directory is not linked into the Docker container (which is probably fine/expected), but this means the plugin binary must be installed to the .packer.d/plugins directory following the steps in manually (multi-component plugin) at https://www.packer.io/plugins#installing-plugins for Packer to find a plugin providing arm build support.

go build
mv packer-builder-arm ~/.packer.d/plugins

Adding support for the Packer 1.7 init command as described in #100 might help avoid this confusion.

Actually, looking more closely at the Dockerfile, this might be an issue with a newer version of Go or specific to macOS -

https://github.com/mkaczanowski/packer-builder-arm/blob/0eff8b7c5475cdca23dd28c2eba174df97585bf7/docker/Dockerfile#L52

assumes the binary will be built into ./build - running go build on my machine instead puts the binary into the repo root.

Can you elaborate on what to do for Mac using Docker? I'm running into this issue and struggling to figure out how to get things to work.

kevinelliott avatar Feb 17 '22 22:02 kevinelliott

Welp, think I figured this out. When using the Docker build, it appears the local directory is not linked into the Docker container (which is probably fine/expected), but this means the plugin binary must be installed to the .packer.d/plugins directory following the steps in manually (multi-component plugin) at https://www.packer.io/plugins#installing-plugins for Packer to find a plugin providing arm build support.

go build
mv packer-builder-arm ~/.packer.d/plugins

Adding support for the Packer 1.7 init command as described in #100 might help avoid this confusion. Actually, looking more closely at the Dockerfile, this might be an issue with a newer version of Go or specific to macOS - https://github.com/mkaczanowski/packer-builder-arm/blob/0eff8b7c5475cdca23dd28c2eba174df97585bf7/docker/Dockerfile#L52

assumes the binary will be built into ./build - running go build on my machine instead puts the binary into the repo root.

Can you elaborate on what to do for Mac using Docker? I'm running into this issue and struggling to figure out how to get things to work.

This is working for me on an M1 Mac

git clone https://github.com/mkaczanowski/packer-builder-arm
cd packer-builder-arm
go mod download
go build
mv packer-builder-arm ./build/packer-builder-arm
docker build -t packer-builder-arm -f docker/Dockerfile .
docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json

mv packer-builder-arm ./build/packer-builder-arm is the extra necessary command to make this work. Simply running go build will place the binary at ./packer-builder-arm, but the Docker image expects it to be in ./build/packer-builder-arm.

cristian-rivera avatar Aug 06 '22 16:08 cristian-rivera

This is working for me on an M1 Mac

git clone https://github.com/mkaczanowski/packer-builder-arm
cd packer-builder-arm
go mod download
go build
mv packer-builder-arm ./build/packer-builder-arm
docker build -t packer-builder-arm -f docker/Dockerfile .
docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json

mv packer-builder-arm ./build/packer-builder-arm is the extra necessary command to make this work. Simply running go build will place the binary at ./packer-builder-arm, but the Docker image expects it to be in ./build/packer-builder-arm.

@cristian-rivera I am curious what your container runtime is?

I am trying to replicate but can not. On an x86 mac, running colima, oddly either with x86 virt or arm64 virt:

x86:

docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json

uname -a:  Linux a29b632e5c6e 5.10.93-0-virt #1-Alpine SMP Thu, 27 Jan 2022 09:34:38 +0000 x86_64 x86_64 x86_64 GNU/Linux
installing: mips64 OK
installing: mips64le OK
{
  "supported": [
    "linux/amd64",
    "linux/arm64",
    "linux/riscv64",
    "linux/ppc64le",
    "linux/s390x",
    "linux/386",
    "linux/mips64le",
    "linux/mips64",
    "linux/arm/v7",
    "linux/arm/v6"
  ],
  "emulators": [
    "qemu-aarch64",
    "qemu-arm",
    "qemu-i386",
    "qemu-i486",
    "qemu-mips64",
    "qemu-mips64el",
    "qemu-ppc64le",
    "qemu-riscv64",
    "qemu-s390x"
  ]
}
running /bin/packer build boards/raspberry-pi/raspbian.json
Error: Failed to initialize build "arm"

error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec
format error

==> Wait completed after 59 microseconds

==> Builds finished but no artifacts were created.

arm64:

docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json
uname -a:  Linux c8e005bcaf75 5.10.109-0-virt #1-Alpine SMP Mon, 28 Mar 2022 11:20:52 +0000 aarch64 aarch64 aarch64 GNU/Linux
{
  "supported": [
    "linux/arm64",
    "linux/amd64",
    "linux/riscv64",
    "linux/ppc64le",
    "linux/s390x",
    "linux/386",
    "linux/mips64le",
    "linux/mips64",
    "linux/arm/v7",
    "linux/arm/v6"
  ],
  "emulators": [
    "qemu-i386",
    "qemu-mips64",
    "qemu-mips64el",
    "qemu-ppc64le",
    "qemu-riscv64",
    "qemu-s390x",
    "qemu-x86_64"
  ]
}
running /bin/packer build boards/raspberry-pi/raspbian.json
Error: Failed to initialize build "arm"

error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec
format error

==> Wait completed after 273 microseconds

==> Builds finished but no artifacts were created.

Do you perhaps get an linux/arm/v8 in your supported list on your runs?

goshlanguage avatar Sep 19 '22 16:09 goshlanguage

There have been bugs regarding the Docker container not really be multi-arch in the past (wrong base go image), but those have been fixed some time ago. Tried the example of the README and this works here on multiple M1 and Intel Macs: docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build mkaczanowski/packer-builder-arm:1.0.2 build boards/raspberry-pi/raspbian.json

Can you all try that and report back with log in case there are still issues?

dbast avatar Oct 19 '22 16:10 dbast

Spent more time with above mentioned ideas and proposed solutions and compiled a README usage and scripts update https://github.com/mkaczanowski/packer-builder-arm/pull/232 to debug, explain and avoid/prevent the error error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec format error.

dbast avatar Oct 23 '22 16:10 dbast