domjudge icon indicating copy to clipboard operation
domjudge copied to clipboard

Add additional sources to chroot

Open vmcj opened this issue 4 years ago • 9 comments
trafficstars

Currently its very hard to add additional repositories to the chroot, the usecase for this is for example a newer version of pypy3 which is not in the main repos yet. Its possible to fix this with custom deb files but it shouldn't be to hard to append an extra file listing the additional repositories.

vmcj avatar Nov 05 '21 13:11 vmcj

My current idea is to provide an extra directory where we loop with similar named files and GPG keys so: ppa_pypy3.list ppa_pypy3.gpg kotlinc.list kotlinc.gpg

so there is verification that a package is installed correctly.

vmcj avatar Nov 05 '21 13:11 vmcj

More info: during BAPC we wanted pypy3 to be loaded from a PPA, but this is not easily possible. The base chroot installs pypy3 and its dependency pypy3-lib. If you provide your own .deb's you get an error about a version mismatch, which you can manually fix by running dpkg -i *.deb twice but that's not really helpful. We do have an option to remove default packages, but we run that after installing custom deb's, so that's also not helping.

In the end I modified Ansible to manually remove pypy3 and pypy3-lib, and then install our own version.

But I agree that it would be nice if we could add custom apt repo's. Not sure how this will work with GPG keys, but I like @mvr320 his idea.

nickygerritsen avatar Nov 05 '21 13:11 nickygerritsen

I don't like adding various unofficial sources by default, as it might surprise people about what packages get installed, and also it will be more work to maintain. I do think it should be easy to add such repositories yourself, so would be good to find a way to make this easy. Maybe have a commandline option to provide a list of such repos (and gpg keys) to add in the chroot /etc/apt tree.

eldering avatar Nov 05 '21 13:11 eldering

I don't like adding various unofficial sources by default, as it might surprise people about what packages get installed, and also it will be more work to maintain. I do think it should be easy to add such repositories yourself, so would be good to find a way to make this easy. Maybe have a commandline option to provide a list of such repos (and gpg keys) to add in the chroot /etc/apt tree.

Just to be sure, you would be fine with having a directory optional_sources where all .list files there would be auto added but which is default empty?

vmcj avatar Nov 08 '21 21:11 vmcj

I'm not sure where that directory should live, but I'd suggest to pass that directory as an argument, like we currently have for -l to specify local debs to install.

eldering avatar Nov 08 '21 22:11 eldering

Regarding this issue, I propose a more general solution: add a flag for specifying a directory of "extra install scripts" to run. Then those script will be executed one after the other, in alphabetical order.

This allows one to install more complex software that may not be packaged for Debian/Ubuntu, as well as customizing even further the chroot environment. Furthermore, we can use this hypothetical flag here, enabling a deeper customization also for the docker environment.

What do you think?

edomora97 avatar Dec 13 '21 13:12 edomora97

What do you think?

Sounds like a reasonable solution that offers more flexibility indeed. Just a few comments:

  • Are you aware that we already have a script https://github.com/DOMjudge/domjudge/blob/main/misc-tools/dj_run_chroot.in? I'm not sure that's already exactly suited as is, but mentioning it to not duplicate effort and code.
  • Although scripts offer more flexibility, they also require better specification of when in the chroot creation process and in exactly what environment (which directory, which FSs are mounted, etc.) they get executed.

eldering avatar Dec 13 '21 22:12 eldering

Are you aware that we already have a script https://github.com/DOMjudge/domjudge/blob/main/misc-tools/dj_run_chroot.in?

No, I wasn't aware of that, thanks for pointing it out.

I was imagining this flag (for example dj_make_chroot -s "$host_dir") working like so:

  • After all the setup of the current dj_make_chroot is done (i.e. before starting the cleanup), a new temporary directory (let's call it $tmp) is created inside the chroot;
  • All the contents of $host_dir is copied inside $tmp (i.e. from the host into the chroot);
  • Each executable file in $tmp is executed (inside the chroot) with something like chroot "$CHROOTDIR" "$tmp/$filename" (or similar, maybe inside a shell? maybe with a cd "$tmp" before?);
  • The directory $tmp is removed, with all its contents (to leave the chroot clean).

There are still some open questions though:

  • Should the whole process fail if any of those scripts exit with non-zero? (my opinion is: yes)
  • Should those script be executed before installing the packages? (my opinion is: no)
  • Should $tmp be a fixed directory inside the chroot (e.g. /install-scripts) or a mktemp -d? (my opinion is: the latter)
  • Should files inside subfolders of $tmp be executed as well? (my opinion is: no)

I think that all of that can be easily expressed by this sketch:

With -s you can provide a folder that will be temporarily copied inside the chroot, and before the cleanup starts, all the files inside of it are executed in alphabetical order.

If I'm not mistaken, this flag is a bit more powerful than dj_run_chroot because of its ability of copying a folder tree, allowing you to write actual bash scripts. And in those scripts you can, for example, download a dpkg from somewhere and install it, or add manually a ppa, or do anything you want, without having to run dj_run_chroot multiple times.

edomora97 avatar Dec 14 '21 19:12 edomora97

I was imagining this flag (for example dj_make_chroot -s "$host_dir") working like so:

* After all the setup of the current `dj_make_chroot` is done (i.e. [before starting the cleanup](https://github.com/DOMjudge/domjudge/blob/9d2b7fb186cf467a7f9d9c27c66f86b87175725f/misc-tools/dj_make_chroot.in#L371)), a new temporary directory (let's call it `$tmp`) is created inside the chroot;

* All the contents of `$host_dir` is copied inside `$tmp` (i.e. from the host into the chroot);

* Each executable file in `$tmp` is executed (inside the chroot) with something like `chroot "$CHROOTDIR" "$tmp/$filename"` (or similar, maybe inside a shell? maybe with a `cd "$tmp"` before?);

I think it's best to do this without a cd $tmp: if the script needs it, it can always do so itself, as it's called with its full path from the root of the chroot. This way, there's no process open in $tmp so you could just delete/move/(un)mount that directory if necessary (not sure that's necessarily a good idea, but still).

* The directory `$tmp` is removed, with all its contents (to leave the chroot clean).

Makes sense.

There are still some open questions though:

* Should the whole process fail if any of those scripts exit with non-zero? (my opinion is: _yes_)

* Should those script be executed before installing the packages? (my opinion is: _no_)

* Should `$tmp` be a fixed directory inside the chroot (e.g. `/install-scripts`) or a `mktemp -d`? (my opinion is: _the latter_)

Agree with these above.

* Should files inside subfolders of $tmp be executed as well? (my opinion is: _no_)

Agreed, also because that offers a way to copy executable files into the chroot that don't get executed. Although those could of course be copied in in a tarball or without executable bit set.

I think that all of that can be easily expressed by this sketch:

With -s you can provide a folder that will be temporarily copied inside the chroot, and before the cleanup starts, all the files inside of it are executed in alphabetical order.

If I'm not mistaken, this flag is a bit more powerful than dj_run_chroot because of its ability of copying a folder tree, allowing you to write actual bash scripts. And in those scripts you can, for example, download a dpkg from somewhere and install it, or add manually a ppa, or do anything you want, without having to run dj_run_chroot multiple times.

Yes, although dj_run_chroot is still useful for quick one-liner commands. Might be nice to see if the duplication between the various scripts can be removed (also with dj_make_chroot) but not that important.

eldering avatar Dec 14 '21 22:12 eldering

I think we can add the additional scripts later if there is a real usecase.

vmcj avatar Nov 10 '22 09:11 vmcj