RFC: Support building ELBE images without initvm#471
Conversation
e2fsprogs comes with mkfs.ext4 that is needed to populate ext4 filesystems. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
binutils comes with strip that is required by dracut to strip the initramfs, i.e. to avoid INFO:soap:dracut[I]: Could not find 'strip'. Not stripping the initramfs. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
elbepack/initvm(action).py currently couples the SOAP submit/download logic (used by elbe initvm submit) with parts only relevant for the actual VM initialization. To enable a future command that does not depend on a VM, extract the parts relevant for both commands into separate files. This commit only moves code around. No functional change. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
Since the buildsubmitaction.py shall be used also without initvm, drop all VM-specific wording from the messages. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
Add a new top-level "elbe build" command as alternative to "elbe initvm submit". It automatically starts an elbe daemon running detached in the background, but not encapsulated into an initvm. It is meant to be used inside a container that already provides the required isolation. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
With the recent additions, it is no longer necessary to spawn an initvm to build ELBE images. Therefore, provide a container that enables this use case. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
aa2de9e to
b67a433
Compare
| android-sdk-libsparse-utils, | ||
| arch-test, | ||
| binfmt-support, | ||
| binutils, |
There was a problem hiding this comment.
This is already pulled in via devscripts/dpkg-dev as far as I can see.
Also dracut is not part of the initvm. When dracut is installed in the target, then I don't see why we need binutils in the build environment either.
Adding initvm packages to the CDROMs is not reasonable when there is no initvm. Therefore, exclude them. Also, provide this option as CLI parameter (default off) for initvm builds for consistency. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
Packages do not necessarily have the origin fully populated. This is in particular the case when development versions of packages are installed into a container (e.g. via contrib/containerfile-vmless/Containerfile.local ). Therefore, make these entries optional. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
Currently, the dump solely considers /etc/apt/sources.list However, this ignores further content in /etc/apt/sources.list.d/* and in some systems /etc/apt/sources.list is completely replaced by files in /etc/apt/sources.list.d/* Therefore, merge all content of these files before further processing. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
Grub requires to actually access the final file systems to setup itself. Since we want to avoid losetup as much as possible, use fuse2fs instead. WARNING: This currently ONLY works for systems with solely ext* partitions (or systems that do not use Grub at all). It will break builds that rely on vfat efi partitions!
Provide a test that builds a two step ELBE build for trixie without using an initvm. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
|
|
||
| from elbepack.tests.test_helpers import elbevalidate # noqa: F401 | ||
|
|
||
| _WORKDIR_RETENTION = 3 |
There was a problem hiding this comment.
The pytest tmpfile fixture already does the same. Why do we need it here again?
There was a problem hiding this comment.
Because the pytest tmpfile fixture uses /tmp which is backed by RAM so it is not suitable for storing these huge build artifacts. One could change that via the pytest --basetemp=mydir parameter, but then everyone needs to add that manually when calling pytest or will run into RAM exhaustion. The best alternative would be a per-module rewrite of basetemp, but that does not seem to be possible (without ugly monkeypatching...).
There was a problem hiding this comment.
We also use it for the initvm created during testing, which is also big.
We can also provide a new fixture which uses TempPathFactory with a different base.
| def build_image(self): | ||
| print(f'[CONTAINER] Building container image from {self.containerfile_dir}') | ||
|
|
||
| original_cwd = os.getcwd() |
There was a problem hiding this comment.
No need to change the cwd of the python process.
Use subprocess.run(cwd=).
| raise | ||
| except Exception as e: | ||
| print(f'[CONTAINER] Unexpected error during build: {e}') | ||
| raise |
There was a problem hiding this comment.
If the exception is reraised anyways, it's the caller responsibility to log it.
| return pathlib.Path(tempfile.mkdtemp(prefix=f'{prefix}-{timestamp}-', dir=root)) | ||
|
|
||
|
|
||
| class ElbePodmanContainer: |
There was a problem hiding this comment.
Why does it need to be in conftest.py?
It is only used by a single test file.
There was a problem hiding this comment.
Because I would expect that it will be used by more tests in the future when we want to test things both with initvm and containers, but I guess I went a few steps to far with that thought for now. Will reintegrate into the test_build.py.
There was a problem hiding this comment.
Then it would be a fixture in conftest.py but the logic lives somewhere else.
| # ResourceWarning. Inhibit this warning: the daemon is meant to keep running | ||
| # detached from this process (e.g. to serve subsequent "elbe build"/ | ||
| # "elbe control" calls in the same container), so it is never wait()ed for. | ||
| ps.returncode = 0 |
There was a problem hiding this comment.
Not a fan of this scheme of starting and leaving the daemon running in the background.
Instead start it on a random port and shut it down afterwards.
| def _free_port(): | ||
| with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: | ||
| s.bind(('127.0.0.1', 0)) | ||
| return s.getsockname()[1] |
There was a problem hiding this comment.
The ELBE daemon should be able to pick a random port on its own.
|
|
||
|
|
||
| @pytest.mark.slow | ||
| def test_build_extended_image( |
There was a problem hiding this comment.
We shouldn't duplicate the logic from test_xml.py. Instead the build type would be test parameter for the existing tests.
There was a problem hiding this comment.
I explicitly wanted to test the base/extended XMLs. And that is also not parametrized in https://github.com/Linutronix/elbe/blob/master/elbepack/tests/test_xml.py#L163
The question remains why I haven't run the full test file set like https://github.com/Linutronix/elbe/blob/master/elbepack/tests/test_xml.py#L121 and the answer is that most still fail mainly due to this Grub Issue...
There was a problem hiding this comment.
And that is also not parametrized
Not yet, as there was nothing to parameterize it with so far.
| @@ -0,0 +1,59 @@ | |||
| <!-- | |||
There was a problem hiding this comment.
Do we really need another test fixture? The existing ones should be good enough.
There was a problem hiding this comment.
All other ones are bookworm. And I explicitly wanted to test trixie because that is also the basis of the container in contrib/containerfile-vmless/ (and anyway the current stable). Maybe it would be anyway worth to bump all test XMLs to trixie?
| -f Containerfile.local \ | ||
| -t $(IMAGENAME) ../.. | ||
|
|
||
| start: |
There was a problem hiding this comment.
As mentioned elsewhere, I want to get away from the whole persistent container idea.
There was a problem hiding this comment.
I would really love that!
And it is actually also what I am doing in my daily work even when using initvm. I just had doubts if there are use cases by others that rely on a persistent build environments? There are quite a few commands (e.g. the whole elbe control *) that people seem to have wanted to fiddle around after the build was finished.
| ps = subprocess.Popen([ | ||
| sys.executable, '-P', '-m', 'elbepack', | ||
| 'daemon', '--host', host, '--port', str(port) | ||
| ]) |
There was a problem hiding this comment.
Did you check if it is feasible to bypass the the whole SOAP thing?
Instead elbe build would directly use the projectmanager. Something like this was done in the past with raw elbe control build, but that needs a few other manual elbe control ... calls for the full cycle.
Document how to use elbe build in a rootless podman container. Signed-off-by: Florian Kauer <florian.kauer@linutronix.de>
b67a433 to
0377279
Compare
This is the first attempt to enable building ELBE images without initvm, but instead rootless podman containers.
WARNING: This currently ONLY works for systems with solely ext* partitions (or systems that do not use Grub at all). It will break builds that rely on vfat (efi) partitions! More investigation is needed to find a clean way to avoid losetup for Grub.