ublue-os / isogenerator

Creates an ISO for installing a container image as an OS
Apache License 2.0
16 stars 2 forks source link

Failure with losetup on first attempt to create a ISO image #22

Closed noelmiller closed 9 months ago

noelmiller commented 9 months ago

When attempting to use this example, sometimes the ISO creation will fail on Fedora 39 Kinoite System:

docker run --rm --privileged --volume .:/isogenerator/output -e VERSION=38 -e IMAGE_NAME=bluefin -e IMAGE_TAG=gts -e VARIANT=Silverblue ghcr.io/ublue-os/isogenerator:38
noelmiller commented 9 months ago

Error received:

Traceback (most recent call last):
  File "/usr/sbin/lorax", line 223, in <module>
    main()
  File "/usr/sbin/lorax", line 204, in main
    lorax.run(dnfbase, opts.product, opts.version, opts.release,
  File "/usr/lib/python3.12/site-packages/pylorax/__init__.py", line 324, in run
    rc = rb.create_ext4_runtime(joinpaths(installroot,runtime),
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pylorax/treebuilder.py", line 254, in create_ext4_runtime
    imgutils.mkrootfsimg(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"),
  File "/usr/lib/python3.12/site-packages/pylorax/imgutils.py", line 136, in mkrootfsimg
    mkext4img(rootdir, outfile, label=label, size=fssize)
  File "/usr/lib/python3.12/site-packages/pylorax/imgutils.py", line 586, in mkext4img
    mkfsimage("ext4", rootdir, outfile, size, mountargs=mountargs,
  File "/usr/lib/python3.12/site-packages/pylorax/imgutils.py", line 555, in mkfsimage
    with LoopDev(outfile, size) as loopdev:
  File "/usr/lib/python3.12/site-packages/pylorax/imgutils.py", line 357, in __enter__
    self.loopdev = loop_attach(self.filename)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pylorax/imgutils.py", line 204, in loop_attach
    dev = runcmd_output(["losetup", "--find", "--show", outfile]).strip()
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pylorax/executils.py", line 373, in runcmd_output
    return execWithCapture(cmd[0], cmd[1:], **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pylorax/executils.py", line 251, in execWithCapture
    return _run_program(argv, stdin=stdin, root=root, log_output=log_output, filter_stderr=filter_stderr,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pylorax/executils.py", line 205, in _run_program
    raise subprocess.CalledProcessError(proc.returncode, argv, output)
subprocess.CalledProcessError: Command '['losetup', '--find', '--show', '/var/tmp/lorax/lorax.8inbedip/installroot/images/runtime-workdir/LiveOS/rootfs.img']' returned non-zero exit status 1.
2024-02-21 21:24:31,337: Cleaning up tempdir - /var/tmp/lorax/lorax.8inbedip
make: *** [Makefile:51: boot.iso] Error 1
noelmiller commented 9 months ago

I have done more testing. If you attempt to run the docker command a second time, it will allow it to work. I'm wondering if there is something we need to do with losetup beforehand to prep fedora for using the loop device.

noelmiller commented 9 months ago

Filed an issue upstream to Lorax. Current workaround is running the command to generate the ISO, let it fail, and then run again.

Otherwise other workaround is using Ubuntu VM to run the docker container.

bsherman commented 9 months ago

Adding a comment related to some testing I did and discord conversation with @noelmiller ...

I believe there is a known issue with both docker and podman containers where if a new device file is created in /dev after the container is running, the container cannot see the new device file.

This seems to be what is happening here:

  1. running this container causes lorax to do its job, wherein it uses losetup to create a loopback device loop0
  2. the lorax process fails because it can't see loop0, but on the host (outside the container) one can see the device exists
  3. if the container is rerun immediately, while loop0 still exists, the process completes successfully
jkonecny12 commented 9 months ago

You can solve this by creating the loop devices manually inside the privileged container.

https://github.com/rhinstaller/anaconda/blob/master/dockerfile/anaconda-iso-creator/lorax-build#L27

Not great but it works fine.