freedomofpress / dangerzone

Take potentially dangerous PDFs, office documents, or images and convert them to safe PDFs
https://dangerzone.rocks/
GNU Affero General Public License v3.0
3.35k stars 152 forks source link

Unable to run podman inside containers when using silicon mac #824

Open almet opened 1 month ago

almet commented 1 month ago

Running the development environment is currently not possible on silicon macs. The GUI can run from inside the container, but the containers themselves are unable to run podman.

The issue can be reproduced by issuing the podman load command that's being issued by dangerzone itself (see below).

./dev_scripts/env.py --distro fedora --version 40 run podman load -i /usr/share/dangerzone/container.tar.gz

Which results in the following logs:

bash-5.2$ 
WARN[0000] "/" is not a shared mount, this could cause issues or missing mounts with rootless containers
Getting image source signatures
Copying blob 878b6e8c989b done   |
Copying blob 17520ba7227c done   |
Copying blob d4fc045c9e3a done   |
Copying blob 5318ffca8a84 done   |
Copying blob 74299cc4fe60 done   |
Copying blob 6607f6964f7b done   |
Copying blob b49272996f10 done   |
Copying blob 56274173e908 done   |
Copying blob bb1884f86f6b done   |
Copying blob 15a9735d7a48 done   |
Error: payload does not match any of the supported image formats:
 * oci: open /usr/share/dangerzone/container.tar.gz/index.json: not a directory
 * oci-archive: loading index: open /var/tmp/container_images_oci3855146576/index.json: no such file or directory
 * docker-archive: writing blob: adding layer with blob "sha256:d4fc045c9e3a848011de66f34b81f052d4f2c15a17bb196d637e526349601820": processing tar file(Error: unrecognized command `podman /`

Did you mean this?
    cp
    ps
    rm

Try 'podman --help' for more information
): exit status 125
 * dir: open /usr/share/dangerzone/container.tar.gz/manifest.json: not a directory
podman load -i /usr/share/dangerzone/container.tar.gz

This is currently tracked on the podman bugtracker.


In order to run on the following environment, a few changes are required, which I'm consigning here in case it can help reproducing the issue.

1. Use the correct linux/amd64 platform

Add --platform=linux/amd64 to the FROM statement in the generated Dockerfiles, and in the run commands, so that the correct platform is used when generating the container images.

Here's what the diff looks like:

diff --git a/dev_scripts/env.py b/dev_scripts/env.py
index fcc4bbd..f26255c 100755
--- a/dev_scripts/env.py
+++ b/dev_scripts/env.py
@@ -173,7 +173,7 @@ RUN dnf install -y mupdf && dnf clean all

 # The Dockerfile for building a development environment for Dangerzone. Parts of the
 # Dockerfile will be populated during runtime.
-DOCKERFILE_BUILD_DEV = r"""FROM {distro}:{version}
+DOCKERFILE_BUILD_DEV = r"""FROM --platform=linux/amd64 {distro}:{version}

 {install_deps}

@@ -234,7 +234,7 @@ RUN rpm --restore shadow-utils
 #
 # FIXME: The fact that we remove the package does not reduce the image size. We need to
 # flatten the image layers as well.
-DOCKERFILE_BUILD = r"""FROM {distro}:{version}
+DOCKERFILE_BUILD = r"""FROM --platform=linux/amd64 {distro}:{version}

 {install_deps}

@@ -438,6 +438,7 @@ class Env:

         run_cmd = [
             "run",
+            "--platform=linux/amd64",
             "--rm",
             "-it",
             "-v",

2. Use Rosetta for x86/amd64 emulation on Apple Silicon

By default, Docker Desktop doesn't turn it on, as it is still considered a beta feature. Be sure it's enabled.

3. Allow X11 forwarding using XQuartz

You have to run an X11 server from the host, that the containers will attach. In order to do this you can use XQuartz.

Here are the steps you can follow, taken from this comprehensive guide (be sure to authorize network connections) :

brew install --cask xquartz
xhost +localhost
export DISPLAY="docker.for.mac.host.internal:0"
almet commented 3 weeks ago

This seem to be because "buildah from" is not working for emulated architectures.

When starting a process using an emulator, the kernel passes the binary as the emulator's first argument rather than the argv[0] value we set, so that the emulator can find the binary. The kernel docs mention a "P" flag, which could be used when registering an emulator, which causes the kernel to pass argv[0] to the interpreter as a second argument, presumably with any other flags that were passed on the command line following it. The interpreter has to be expecting that extra argument, though, and I don't think qemu-user does.

See this discussion