Skip to content

Conversation

Forty-Bot
Copy link
Contributor

@Forty-Bot Forty-Bot commented Oct 17, 2021

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 the unshare from util-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:

$ mkdir mnt
$ arch-unshare pacstrap -u mnt
$ arch-unshare tar -C mnt -cvf arch.tar .
$ arch-unshare rm -rf mnt

You will also need to have added entries for your user to /etc/subuid and /etc/subgid.

Closes: #8

@Forty-Bot Forty-Bot force-pushed the unshare branch 3 times, most recently from 832c15a to d93ab8b Compare October 18, 2021 00:38
@Forty-Bot
Copy link
Contributor Author

I've created a series for unshare which upstreams the bits which went in arch-unshare. So the next spin of this series will not include that. However, I would still like feedback on my modifications to pacstrap. Thanks.

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.
@Forty-Bot
Copy link
Contributor Author

Forty-Bot commented Nov 17, 2021

This is ready to review pending upstreaming of the unshare series for util-linux. For your convenience, the util-linux series is also available from my fork. To build util-linux, run ./autogen.sh && ./configure && make. To test out this series, you can try the following commands:

$ mkdir mnt
$ PATH=/path/to/util-linux:$PATH ./pacstrap -N mnt
$ PATH=/path/to/util-linux:$PATH ./arch-chroot -N mnt ls -l /
$ /path/to/util-linux/unshare --map-auto --map-root-user tar -C mnt -cvf arch.tar .
$ /path/to/util-linux/unshare --map-auto --map-root-user rm -rf mnt

As above, you will need to add entries for your user to /etc/sub{u,g}id.

@Forty-Bot
Copy link
Contributor Author

Ok, the unshare stuff got applied to util-linux, so I'm marking this as a "real" PR.

@Forty-Bot Forty-Bot marked this pull request as ready for review December 1, 2021 15:42
Copy link
Member

@Foxboron Foxboron left a 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 :)

@Forty-Bot
Copy link
Contributor Author

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.

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'm also not sure if the declare grepping hack is well enough explained.

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.
@Foxboron
Copy link
Member

Foxboron commented Feb 8, 2022

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.

@Foxboron
Copy link
Member

archlinux/svntogit-packages@f2ebf3c

We can now progress :)

@Forty-Bot
Copy link
Contributor Author

@jelly Since it looks like you merged a PR recently, can you have a look at this?

@Foxboron Foxboron requested a review from alex19EP May 28, 2022 19:40
@Foxboron
Copy link
Member

Foxboron commented Jun 2, 2022

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.

@Foxboron Foxboron merged commit d5d3da3 into archlinux:master Jun 28, 2022
@jelly
Copy link
Member

jelly commented Jun 28, 2022

What about distros which don't ship an up to date util-linux I know at least Fedora packages arch-install-scripts and it being Fedora util-linux should be up to date :)

@Foxboron
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can namespaces be used instead of chroot to make archiso build run unpriveledged?

3 participants