openwrt / docker

Docker containers of the ImageBuilder and SDK
GNU General Public License v2.0
463 stars 76 forks source link

Cross architecture rootfs images are declared as amd64 #112

Closed bwoodsend closed 1 year ago

bwoodsend commented 1 year ago
> docker pull openwrtorg/rootfs:mips_24kc
mips_24kc: Pulling from openwrtorg/rootfs
Digest: sha256:44e17879beb8da4b64aad5569fbe550ec7320f0f390202758db5026b492493cb
Status: Image is up to date for openwrtorg/rootfs:mips_24kc
docker.io/openwrtorg/rootfs:mips_24kc

> docker image inspect openwrtorg/rootfs:mips_24kc | jq '.[].Architecture'
"amd64"

This used to not matter because Docker could be made to run it by setting the architecture explicitly using --platform but now that's not allowed.

> docker run -it --rm --platform=linux/mips_24kc openwrtorg/rootfs:mips_24kc
Unable to find image 'openwrtorg/rootfs:mips_24kc' locally
mips_24kc: Pulling from openwrtorg/rootfs
Digest: sha256:44e17879beb8da4b64aad5569fbe550ec7320f0f390202758db5026b492493cb
Status: Image is up to date for openwrtorg/rootfs:mips_24kc
docker: Error response from daemon: image with reference openwrtorg/rootfs:mips_24kc was found but does not match the specified platform: wanted linux/mips_24kc, actual: linux/amd64.

I suspect you need to set the platforms option here. Edit: I mean here.

aparcar commented 1 year ago

Looks like you're already working on a PR to fix that, thanks!

bwoodsend commented 1 year ago

Hmm, almost. But MIPS is causing issues.

I added a dumb run it test which sure enough reproduces this ticket. Adding my hypothesised one line fix fixes every platform except MIPS which is raising Docker's not so informative wrong architecture error.

Running it locally gives me the same thing:

> docker build --platform linux/mips_24kc --build-arg 'DOWNLOAD_FILE=openwrt-.*-rootfs.tar.gz' --build-arg WORKDIR=/ --build-arg USER=root --build-arg VERSION_PATH=snapshots --build-arg TARGET=malta/be --build-arg BASE_IMAGE=scratch --build-arg CMD=ash .
[+] Building 2.6s (22/22) FINISHED                                                                                                                                                                                                            
 => [internal] load .dockerignore                                                                                                                                                                                                        0.0s
...
 => => writing image sha256:b3d596932ac4091b06535b990144d701814f26af08d573bb4484430b362005d3                                                                                                                                             0.0s
> docker run --platform=linux/mips_24kc sha256:b3d596932ac4091b06535b990144d701814f26af08d573bb4484430b362005d3 uname -m
exec /bin/uname: exec format error

I wasn't too sure what Docker/qemu aliases as mips_24kc (for the --platform flag) so I downloaded the rootfs tarball and tried to empirically determine which qemu emulator it needs:

wget https://downloads.openwrt.org/snapshots/targets/malta/be/openwrt-malta-be-default-rootfs.tar.gz
tar xf openwrt-malta-be-default-rootfs.tar.gz
for qemu in /bin/qemu-*static; echo $qemu; $qemu lib/libc.so; end

qemu-mips-static is the emulator that matches the architecture of the binaries in that tarball which corresponds to --platform=linux/mips:

> docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes | grep mips
Setting /usr/bin/qemu-mips-static as binfmt interpreter for mips
Setting /usr/bin/qemu-mipsel-static as binfmt interpreter for mipsel
Setting /usr/bin/qemu-mipsn32-static as binfmt interpreter for mipsn32
Setting /usr/bin/qemu-mipsn32el-static as binfmt interpreter for mipsn32el
Setting /usr/bin/qemu-mips64-static as binfmt interpreter for mips64
Setting /usr/bin/qemu-mips64el-static as binfmt interpreter for mips64el

Setting --platform=linux/mips also doesn't work though:

> docker build --platform linux/mips -q --build-arg 'DOWNLOAD_FILE=openwrt-.*-rootfs.tar.gz' --build-arg WORKDIR=/ --build-arg USER=root --build-arg VERSION_PATH=snapshots --build-arg TARGET=malta/be --build-arg BASE_IMAGE=scratch --build-arg CMD=ash .
sha256:f8e5382d05afe40ea1618ba2dad3f1b2b1b3dd62a5dc744851b304682d465fbc
> docker run --platform=linux/mips sha256:f8e5382d05afe40ea1618ba2dad3f1b2b1b3dd62a5dc744851b304682d465fbc uname -m
exec /bin/uname: exec format error

I suspect that this reveals the cause:

> docker run --platform=linux/mips sha256:f8e5382d05afe40ea1618ba2dad3f1b2b1b3dd62a5dc744851b304682d465fbc /lib/libc.so
qemu-mipsn32-static: /lib/libc.so: Invalid ELF image for this architecture

Docker is using qemu-mipsn32-static instead of qemu-mips-static.

So unless you have any ideas, I think the best I can do is fix the others and disable MIPs rootfs then poke around the Docker community to see why Docker is using the wrong qemu emulator.

aparcar commented 1 year ago

@dangowrt do you have an idea on how to treat this?

aparcar commented 1 year ago

Thank you for the insights, very helpful! I'd be fine to drop it for now