-
Notifications
You must be signed in to change notification settings - Fork 54
Add unshare mode #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add unshare mode #14
Conversation
832c15a
to
d93ab8b
Compare
I've created a series for unshare which upstreams the bits which went in |
In an unshare environment, /etc/pacman.d/gnupg is owned by the original root, who is now "nobody". cp will warn about this, since we can't create files owned by the original root, and it instead creates them as the unshare'd root (the original user). This is benign, so ignore it.
This is ready to review pending upstreaming of the unshare series for
As above, you will need to add entries for your user to |
Ok, the unshare stuff got applied to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks fine I think.
I'm mostly not sure if the bash -c
call at the end is a good idea or if there is a better approach to this. It makes it a bit harder to understand what is happening.
I'm also not sure if the declare grepping hack is well enough explained.
These two things is what sticks out to me after skimming it quickly. I'll pull and take it for a test run as well when I have time :)
Since we are using unshare to fork/exec we can only communicate using stdin/out and any command line arguments. And we need to defer some setup until after we are root. The other approach I considered was to have a separate helper script which would contain the contents of pacstrap(). But I think this would be more confusing, because the logic would then live in a separate file. You also have to be careful with that, since every variable you want to use has to be passed in the arguments. If you have a better suggestion, I'd love to hear it, but unfortunately I think anything involving fork/exec is just harder to deal with cleanly in bash.
I will add some more commentary to it. |
This adds an "unshare" mode to pacstrap. This mode lets a regular user create a new arch root filesystem. We use -N because both -U and -u are taken in pacstrap and arch-chroot, respectively. There are two major changes to pacstrap: we need to run many commands in under unshare, and the setup process for mounts is different. Because unshare starts a new shell, it is difficult to run many commands in sequence. To get around this, we create a function for the rest of the commands we wish to run, and then declare all functions and variables in the unshare'd shell. This is pretty convenient. An alternative method would be to generate the shell script as a HERE document, and pipe it to bash. Because unshare starts a new shell, we can only communicate using stdin/out and any command line arguments. And we need to defer some setup until after we are root. To get around this, we create a function for the rest of the commands we wish to run, and then declare all functions and variables in the unshare'd shell. I also considered having a separate helper script which would contain the contents of pacstrap(). But I think this would be confusing, because the logic would then live in a separate file (instead of just a separate function). That method is also tricky because every variable has to be passed in through the command-line arguments. One last method would be to generate a script on the fly (e.g. using a HERE doc). I think that method could work as well. The primary difference to the setup process is that we need to mount filesystems in a different manner: - We bind-mount the root directory. This is so commands which want to determine how much free space there is (or otherwise work with mounts) expect a mount on /. We unmount it with --lazy, since otherwise sys will cause an error (see below). - proc can be mounted multiple times and is mounted in the same way - sys cannot be mounted again, but we can recursively bind-mount it. When mounted this way, we can't unmount it until the mount namespace is deleted (likely because sys has a number of sub-mounts), so we have to use --lazy when unmounting it. - dev can be bind-mounted, but this results in errors because some packages try and modify files in /dev if they exist. Since we don't have permission to do that on the host system, this fails. Instead, we just bind-mount a minimal set of files. - run is not bind-mounted, but is instead created as a new tmpfs. According to aea51ba ("Bind mount /run from host into new root"), the reason this was done was to avoid lengthy timeouts when scanning for lvm devices. Because unshare does not (and cannot) use lvm devices, we don't need to bind-mount. - tmp is created as usual. Closes: #8
This is effectively the same transformation as in the previous patch. We move the mountpoint warning later to avoid warning when we are about to bind-mount the chroot dir ourselves.
Yo, I'm sorry this hasn't gotten the attention it deserved. I was looking into utilizing podman for package building and have partially realized we need this for that. I'll take another stab at reviewing, testing this and hopefully get it merged soon. |
archlinux/svntogit-packages@f2ebf3c We can now progress :) |
@jelly Since it looks like you merged a PR recently, can you have a look at this? |
Fwiw, I've gotten maintainer rights to the repository now and have prodded around different Arch devs/maintainers to help review it since it's admittedly a bit complex. I have been testing it and it does seem to work but more eyes are good I think. |
What about distros which don't ship an up to date |
Not sure, we can address that issue if anyone actually experiences issues. I don't think the default behaviour of pacstrap should change, and they would only have possible issues with using the new -N option. |
This adds support for "unshare" mode. The idea here is that we can create new namespaces with unshare() and then become root in that namespace. To do this, we need a new helper
arch-unshare
, as theunshare
fromutil-linux
is unsuitable; see commit 2 for details. Commands run with this helper will see themselves as the root user, but all actions they take will be done as a regular user.I have left off documentation and completion updates because I would like to make sure I am taking the right approach first. But for example, you can now create a root tarball as a regular user:
You will also need to have added entries for your user to
/etc/subuid
and/etc/subgid
.Closes: #8