Error when building a preloaded image: "ERROR: cannot read `/dev/loop0' (I/O error)"

I’ve tried different versions of docker, but the issue persists.

The command I’m running is:

balena preload <image filename>.img --app <app id> --commit latest

The output is:

Building Docker preloader image. [========================] 100%




/ Starting preloader container
- Fetching application 1275303
1: Step 1/7 : FROM docker:17.10.0-ce-dind
 ---> 9769e0f3f9cb
Step 2/7 : RUN apk update && apk add --no-cache python3 parted btrfs-progs docker util-linux sfdisk file coreutils sgdisk
 ---> Using cache
 ---> e964730dc1cf
Step 3/7 : COPY ./requirements.txt /tmp/
 ---> Using cache
 ---> 8f4cafb6b91f
Step 4/7 : RUN pip3 install -r /tmp/requirements.txt
 ---> Using cache
 ---> f98489c14195
Step 5/7 : COPY ./src /usr/src/app
 ---> Using cache
 ---> eb27e34808c5
Step 6/7 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 639c46386267
Step 7/7 : CMD ["python3", "/usr/src/app/preload.py"]
 ---> Using cache
 ---> 60ac9944b9b6
Successfully built 60ac9944b9b6
Successfully tagged balena/balena-preload:latest
Traceback (most recent call last):
  File "/usr/src/app/preload.py", line 794, in <module>
    PARTITIONS_CACHE[None] = prepare_global_partitions()
  File "/usr/src/app/preload.py", line 76, in prepare_global_partitions
    return get_partitions(IMAGE)
  File "/usr/src/app/preload.py", line 65, in get_partitions
    return {p.label: p for p in PartitionTable(image).partitions if p.label}
  File "/usr/src/app/preload.py", line 380, in __init__
    part = Partition(self, number, **partition_data)
  File "/usr/src/app/preload.py", line 165, in __init__
    self.label = self._get_label()
  File "/usr/src/app/preload.py", line 169, in _get_label
    out = file("-s", device).stdout.decode("utf8").strip()
  File "/usr/lib/python3.6/site-packages/sh.py", line 1427, in __call__
    return RunningCommand(cmd, call_args, stdin, stdout, stderr)
  File "/usr/lib/python3.6/site-packages/sh.py", line 774, in __init__
    self.wait()
  File "/usr/lib/python3.6/site-packages/sh.py", line 792, in wait
    self.handle_command_exit_code(exit_code)
  File "/usr/lib/python3.6/site-packages/sh.py", line 815, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_1:

  RAN: /usr/bin/file -s /dev/loop0

  STDOUT:
/dev/loop0: ERROR: cannot read `/dev/loop0' (I/O error)


  STDERR:

If you need help, don't hesitate in contacting us at:

  GitHub: https://github.com/balena-io/balena-cli/issues/new
  Forums: https://forums.balena.io

- Fetching application <app id>%

Any idea what could be causing this issue?

MacOS 10.14.1
Balena 9.3.5
Docker 18.03.1-ce
docker-machine 0.14.0

I have a similar problem.

  . . .

  RAN: /usr/bin/file -s /dev/loop17

  STDOUT:
/dev/loop17: ERROR: cannot read `/dev/loop17' (I/O error)

  STDERR:
    at container.wait.then (/usr/local/lib/node_modules/balena-cli/node_modules/balena-preload/lib/preload.js:333:19)
    at tryCatcher (/usr/local/lib/node_modules/balena-cli/node_modules/bluebird/js/release/util.js:16:23)
    . . .

Ubuntu 18.04
Balena CLI 9.3.5

Any idea what could be causing this issue?
→ docker-machine 0.14.0

It looks this answer is arriving a bit late - sorry! I believe the problem is that the balena preload implementation is not compatible with the way that docker-machine works. balena preload expects/requires the image file to be in a local filesystem shared between the Docker daemon and the balena CLI, because a bind mount is used to share the image file with a docker-in-docker container created by balena preload and executed behind the scenes. Furthermore, a loop device is then created with losetup and mapped to the image file over the Docker bind mount. However, docker-machine works by creating a virtual machine (VirtualBox by default on macOS) that does not transparently share its local filesystem with the host OS, and I believe that the sshfs docker-machine mount is not good enough to allow the loop device mapping to succeed.

It is however possible to use VirtualBox on macOS to run both “standard Docker for Linux” (rather than docker-machine) and the balena CLI in the VM, and then run balena preload in the VM. This also gets around a known issue of balena preload on macOS: lack of AUFS driver support in newer versions of Docker Desktop.