Run snapcraft in container as a user

Currently snapcraft runs itself as root to do everything inside a LXD container. The same is true for Launchpad. This is usually fine, however

More generally speaking

  • Snaps built on developer machines tend be built as a user because otherwise file ownership would get messed up
  • Build tools may not be designed to run as root
  • Launchpad is moving towards building snaps as a user

On the flip side, specific use cases may require root

  • os and kernel snaps usually need root to be snapped

In consequence, I’m proposing that

  • containers use a regular user
  • snapcraft mirror the user’s intention, if it’s invoked as root it can do the same in the container to allow enforcing privileges
  • snapcraft elevate privileges if needed if type: os and step is stage
  • documentation of plugins be improved to point out build requirements
1 Like

how about rather …

“building as root becomes automatic”

just default to non-root for everything but os and kernel types … snapcraft knows what the snap type is and should just invoke sudo when necessary …

This is exactly what I proposed in Comment #2 of LP: #1702656

1 Like

Yeah, seems like we had the same idea. I noticed after adding my comment :smiley:

Please re-read all of the points. What you’re suggesting is already in there.

1 Like

I made this comment in the PR a while ago but I’ll make it here as well:

Automatically elevating privs because we happen to know that os snaps are currently built in such a way to need that doesn’t give me warm fuzzies. I’d like to see something more explicit to allow the user who’s in a position to know what does and doesn’t require sudo to request it: an environment variable, a build attribute, or a CLI flag.

One of the points of running things in containers is precisely so that we can give the process system-level access without giving the whole procedure system-level access to the host systems, so -1 on this part of the proposal.

Also, we’re on the way to introducing support for multiple users and groups in snaps, which means we’ll need more privileged access to the system to be able to put the snap in place, and that’s true for all snaps not only core (the old “type: os”, which should die) or base snaps.

So what we need is a more explicit declaration in snapcraft.yaml of whether this particular snap needs administrative access to perform its duties, and where specifically it needs that access.


I agree that we shouldn’t just do root, just because.
Everything we have from a plugin perspective can build without root except for two very particular components:

  • the current core snap
  • the official kernel snaps (kernel snaps built with the kernel plugin do not require root)

And this is due to the fact that these set of snaps wrap around livebuild to actually build the snaps. I don’t think this is a hard requirement to build a proper base as, heck, even Android can be fully built without root.

This issue is raised by quite the opposite side effect, many build systems don’t like to be run as root (e.g.; jhbuild, latest npm) but launchpad always has and we wanted to reflect that in our containers.

We are actively working on doing user level builds by default and the roadblock is building these snaps that use livebuild underneath.

I bring this up specifically, because these are wrapped under the make plugin and just call sudo internally so to go down this path we need a way to disable sudo for that step in the lifecycle unless explicitly declared (I can think of ways to do this but it could be worked around for the solution I have in mind).

This paragraph outlines why I dislike automatically elevating just because of the snap type.

Part of the point I’m raising is that this will become less of an exception once we support multi-user snaps, which are coming soon.

Can we have a more clear proposal of how to define the requirement that certain parts should be run or depend on being able to run with more privilege?

As a side note, if snapcraft runs as root inside containers today, changing that default behavior will break everybody that relies on that behavior. It doesn’t sound like this decision should be taken so lightly.

We build as root in cleanbuild as launchpad builds as root, launchpad is switching to building as users, we are following suit.

What comes to mind is that there will be an archive rebuild on launchpad staging testing for anything that breaks.

You are restating the facts, but you’re not really responding to the issues raised above about compatibility breakage and it being unsuitable for a world where the snaps depend on multiple users to be built.

Oh, I just missed that part. This to me just warrants a snapcraft 3.0 track.

I think it warrants thinking more carefully about how we want to change the current behavior instead!

In particular, let’s please not change the behavior in Launchpad until we respond those questions. We don’t want to change the behavior in a rush, breaking everybody, just to change the behavior again in a different direction.t

Repeating the same question above: can we have a more clear proposal of how to define the requirement that certain parts should be run or depend on being able to run with more privilege?

Right, changing the behavior boils down to a plethora of options, no breakage limits that (and we don’t want to break).

I am inclined to:

  • introduce yaml to specify the build should be user mode driven from the top.
  • allow plugins to have a say in which mode they should build (root-required).
  • have attributes defined which ask to raise to root.

The multi user aspect aside from priv and unpriv escapes me. Mind elaborating on what this looks like? Or better yet a couple of user stories to work from.

Once you have root on a system you can manipulate ownership and run things as that user. That’s useful when you need to set up a snap that holds a multi-user environment.

What is a snap that holds a multi user environment and how is snapcraft involved in this? That is what escapes me.

@niemeyer that topic makes sense, but I personally am still having trouble figuring out what it has to do with whether we build the snap in the first place as root or as a user. Are you simply saying that building a snap that has a multi-user environment will require root as well? Which of course requires more logic than “building a core snap? Fine, you get root.”