Syntax for build-snaps


+1 to the suggested syntax


The proposal seems to mix ‘channel’ and ‘track’. The example is certainly
using a track. How do you intend to disambiguate between channels and
tracks in the syntax? (Is it legal to have a ‘stable’ track, or are the
names of channels reserved so that they are never used as track names?)

What does the syntax look like if you specify both a channel and a track?
You say that the semantics should be the same as for the snap and snapcraft
commands, but I’m not familiar with usage of either of these that
concatenate package+track+channel into a single string. (E.g. snap takes a
–channel= argument.)


A channel is comprised of Track, Risk and Branch and has a well-defined syntax: track/risk/branch

where track and branch are optional - track defaults to 'latest', risk is one of [stable, candidate, beta, edge] and branch is empty.

So one can snap install foo --channel 2.0/stable/fix-the-problem (or indeed build-snaps: [foo@2.0/stable/fix-the-problem])


A channel is a triplet of <track>/<risk>/<branch>, the track is implicitly latest if not defined and the branch is optional. So if all these combinations would be possible

  • go@beta would get go from beta on the latest track
  • go@1.6/edge would get go from edge on the 1.6 track.
  • go@1.7/stable/hotfix-1 would get go from the hotfix-1 branch
  • go@stable/hotfix-2 would get go from the hotfix-2 branch

These are all cases supported today by snapcraft and snap/snapd


I understand that base snaps will let us bring rpm into the picture, but what happens if a build-snap specifies a base:?


What about the confinement type of a build snap? go requires --classic to be installed. Should that be specified in the YAML as well?


Why would that be needed? snapcraft can determine if the given snap (revision) requires classic or not, and Do The Right Thing™ - there’s nothing that the user is usefully controlling by specifying the confinement type.


It would install that snap using it’s preferred base, and execute the commands that are exposed to the build environment as it would with a homogeneous base. Is there a problem you foresee?


classic snaps are not installable on ubuntu core (not even inside the classic mode there), so you could not build on a core system …

though i think a proper error message that “go is not installable on this system” would be sufficient, no need to have any additional tag in the yaml IMHO


The classic flag exists for security reasons, though. Having it be magically implied in build-snaps doesn’t sound clearly safe.


snapcraft isn’t installable on Ubuntu Core either.


not true, i use its deb every day inside the classic mode :wink:


Well, it the snap command provides the appropriate error message it should be fine.


I’m on the fence between, say, go@1.7/stable and go/1.7/stable… the latter seems more clear for some reason. Perhaps because it gives a feeling of parenthood with stable/1.7 being under “go”, which more correctly reflects reality than the idea of go@1.7/stable, which makes it feel slightly like 1.7/stable is a place where we can find more things than simply go itself. The use of a single punctuation character also feels like a win in this case… less noise.

I’ve just been trying to come up with potential issues that might exist with this syntax. So far it seems fine, because we never have a context where both a channel and a snap name would make sense. So the potential ambiguity which might happen with snap name being interpreted as a track is irrelevant.

So yeah, this feels a bit nicer. Can anyone come up with relevant issues with that?

If that goes forward, we should accept it in the command line as well.

As others pointed out, there’s a bit of confusion here. We have a good document explaining the terminology in detail.

The base should be installed just as usual.

As @wgrant pointed out, it would not make sense to allow them to be installed by default. I suggest supporting a flag such as –allow-classic in snapcraft which would enable these snaps to be installed, and when it’s not provided failing with a clear message.

Agreed. Would just like to emphasize here that bases are strictly defined rather than just preferred.


Interesting that you propose / as a separator, I had the same initial thought and actually had a presentation with that for some reason (instead of using channel) a couple of days ago.

I am all aboard with the proposal, it has a nice launchpad/bzr series connotation to it. If it technically works (I think it does), then yeah, let’s use it. For snapcraft the work would probably be to support

snapcraft release go/1.8 5

Today that is (<snap-name> <revisions> <channel>):

snapcraft release go 5 1.8

I don’t see us changing this though:

snapcraft push go.snap --release 1.8

Which could be confusing to the causal user.

The only reason to choose @ is the way you would read it go at 1.8.


This would need UI integration though. In my mind I was of the thought that 80% of the build-snaps would be classic snaps, this conversation however triggered in my mind that we also want some mechanism to connect required interfaces for the cases of confined snaps.

Can we approach this conversation similarly to the conversation about privileged/unprivileged users by applying language to snapcraft.yaml instead.


I don’t see how that’s an issue for These are VMs specifically prepared for building things, which need to install debs, rpms, classic snaps, or whatever else is necessary for getting the thing to build.

We’ll need to discuss this in more details as it seems to cross a strange line between building a piece of software and modifying the host system.


It’s not just about compromising an existing host system, but also about dirtying or compromising a build. My snapcraft.yaml might use some weird network client snap to acquire a signed build resource, but not want to trust that snap with full access to the system – either because the snap publisher is not 100% trustworthy, or because it has complex protocol handling C code that probably has vulnerabilities so should be sandboxed.

As @sergiusens says, we’ll also need to handle connections, and probably devmode as well, so it seems like a single top-level flag is insufficient regardless.

A full YAML installation specification sounds potentially useful in general. A model assertion or system management tool needs the same sort of behaviour that snapcraft.yaml does.


@wgrant That’s exactly the sort of reason why we should be using containers for builds. The comments above talk about not using root inside the sandbox, and that’s what the quoted comment was about.


As a tangential comment, the plan is to use persistent containers per project for continuous development locally (hidden behind a feature flag today SNAPCRAFT_CONTAINER_BUILD). Furthermore, specifically on, support for build-snap as an entry is forcing a move of launchpad to build in lxd containers.

Now that that is out of the way. Considering we are building in containers we can avoid user interaction for building with --allow-classic transparently in the builders and regular users wouldn’t be surprised. I’d like to leave interface connection discussions for a phase 2 part of the implementation as 90% of the use cases for build snaps are based out of using snaps that are classic confined.

Week 33 of 2017 in snapcraft