Snap license metadata

That sounds bad for multiple reasons:

  • We don’t want to block updates of working software; it’s unexpected and will create problems.
  • We have no interface to ask for agreements on a license.
  • Most license changes on free/open source preserve the software as free/open source.
  • Many license changes will be trivial fixes (we lack good information today).
  • No other package manager does that.

And with all that said, this is all unrelated to the original point: that issue exists whether we keep an authoritative version in the store or not, so is not good motivation for doing it one way or the other.

The approach I would recommend is this: we keep the authoritative version in the store, because we need to display something to people that want to know what the license is, and because we don’t want to overwrite that license every time a snap is pushed (again, same problem of summaries and descriptions). Locally, we display the locally installed snap license. When the local snap is refreshed to something containing a different license, we issue a warning through the upcoming warnings framework. We also warn when the just installed snap holds a license that diverges from the authoritative one in the store, which they may have read.

so, to summarise:

  • snaps will have a license field
  • the store will have a per-snap (not per-revision) license. This is taken from a snap’s yaml but can be changed online, or via re-reading any later snap, at which point that license is the one that applies to that snap irrespective of revision
  • in other words, snap license changes retroactively apply to software previously released.
  • when a snap’s license is changed, the user isn’t notified. If and when the developer pushes a revision to the channel they’re tracking, they’ll get a warning. Meanwhile they’ll still be told the license of the software is the one in the snap, despite it not being that.

The two last points disagree with the proposal made.

We’re misunderstanding each other, I fear.

We’re now in agreement. :slight_smile:

We discussed this today in the call, and we now understand each other.

The suggestion from @chipaca is that instead of requiring manual fiddling with an editable label in the store, it’s much simpler to always take the license from the stable channel. That’s a good idea and simpler in all angles. The only bit I’d amend is that we should pick the license from the most stable channel, not just stable itself, because we need to show something if there’s no snap in stable.

So, the next steps are:

  1. Implement the described logic in the store
  2. Support custom licenses
  3. Change snapcraft to warn about missing licenses
  4. Change the store to reject new snaps without licenses

Step 4 needs to wait some grace period until everybody had a chance to update their snaps.

Trying to get some extra clarifications about the suggested plan.

  • Are you proposing the store should not allow to modify the license through the web UI, or via API, but only extract the license expression as provided by each uploaded revision?

  • There is still a snap-level license, given by the current most stable released revision. This means that depending on the channel map constraints (arch, validation, epochs, etc), the snap could expose a (dynamically calculated) different license?

  • Similarly, if I’m following the beta channel, and I got a snap installed under X license, and the developer releases a new revision to stable (not affecting the beta channel) with Y license, does the license for the snap change for me?

Given the channel map is calculated on the fly given a set of constraints, I’m not sure if tying the license around that will work as expected.

Yes, the license would not be editable outside of the snap, as the license is tightly bound to the snap content. Each released snap carries its own license information.

For the second question, by “snap-level” I assume you mean independent of any revisions. Yes, we need to present some kind of information that is “current”, usable in the web interface, etc. For that we pick the license of the most recently published snap in the most stable channel not closed (latest/stable itself, if available).

For the last question, no… once you install a snap, the license displayed locally through snapd is the one for the local snap. Once our warnings pipeline is developed, we will issue a warning on license changes.

Regarding the channel map, that’s exactly why we need a notion of “current license” that is bound to the whole snap. We already have the ability to display multiple licenses for an individual revision. Trying to provide details of all licenses that all revisions carry would be very confusing.

That seems a scary restriction. What if an upstream project is relicensed for future releases only (not past), e.g. a project transitioning from GPLv2 to GPLv3 … ? Or, alternatively, what if some revisions of a snap contain extra components (with their own license) that other revisions do not?

This is not a theoretical case, by the way. This happened to me, with the ldc2 snap, when the upstream project removed a dependency on libconfig (previously statically compiled into the snap):
https://github.com/ldc-developers/ldc2.snap/commit/80db8f3322d33f940ad0981783772ce1182b6774

@joseph.wakeling Per following discussion, the “irrespective of revision” means the license that is displayed by default in interfaces when you list the snap alone, and it will be extracted from the revisions themselves using some reasonable heuristics (latest stable, for instance).

The individual snaps will still hold their own license, which will be displayed if locally installed.

Right, my point in this case was that the channel map, in most cases, has multiple revisions released to stable at a given time (because of series or arch, or refresh control, for example), so when we say “the license from the revision in the most stable channel”, this could really be a list of (potentially) different licenses.

It changes depending on the point of view of the client, in the sense that we could have different “current licenses” for clients with different architectures (ie. 2 revisions, different arch, different license, both released to stable).

Do you have a suggestion of a polished way to implement that heuristic?

I think we should avoid a heuristic and leave it up to the snap author as it is now, which is also consistent with how we handle other metadata. Too many ways of doing things with snap-level data will be confusing. I’d suggest we add a license-last-modified date as well so there’s some indication in that top-level data of a change and then interested parties can dig into the README or License.txt to get further info.

We definitely can, but I see no good rationale for doing it considering everything we discussed above. It’s not simpler, or easier to support, or understand. Plus, it has the serious downside that makes people think that just having a license set in the store is enough to give their snaps a license. It’s not.

So how about this:

The general license when the operation at hand has no revision context is the one for the revision currently in the latest track, in the most stable risk available. That means latest/stable is the preferred choice. The architecture lookup order is: amd64, 386, arm64, arm, etc. If there are no revisions in latest, then the snap license is unknown unless there is a revision for the operation at hand (e.g. the snap is installed).

How is that list of criteria easier to understand or support than “The license shown when no revision context is available is the one the developer explicitly sets”?

1 Like

You are thinking about the implementation. I’m thinking about the publisher and the user.

Option one, with license in snap and field in the store

How it works:

You need to set the license in the snap, and in the store.

Consequences:

  • When is the data updated?
  • Who updates it?
  • What happens if it is updated?
  • What if it is not updated?
  • Why is my software showing no license if I have updated it in the store?
  • Why is snap A showing the license of edge while B shows the one of stable?
  • Why is my software showing a different license if I updated it in the store?

Option 2, with license in snap only

How it works:

You set the license in the snap.

Consequences:

  • When is the data updated?
    You’ve built the snap with it.

  • Who updates it?
    You’ve built the snap with it.

  • What happens if it is updated?
    You’ve built the snap with it.

  • What if it is not updated?
    You’ve built the snap with it.

  • Why is my software showing no license?
    You’ve built the snap with it.

  • Why is snap A showing the license of edge while B shows the one of stable?
    They don’t.

  • Why is my software showing a different license?
    Yes, that’s still an issue. It will always be no matter what we do, because we cannot reasonably show every license of every revision at once when presenting the store generally. Thus, heuristics pick a sensible one when we have no context.

1 Like

While working on some documentation and examples I tried to include license in a new snap I made. I noticed that snapcraft doesn’t allow the license field defined at the top-level.

snapcraft --version
snapcraft, version 2.34+17.10

The error message I got was:

Issues while validating snapcraft.yaml: Additional properties are not allowed ('license' was unexpected)

The snapcraft.yaml contained license: MIT

1 Like

@sergiusens :arrow_up:

We removed that almost 2 years ago and were waiting on the validation tool to add again (as discussed in Warsaw). Are we saying we now want the field and to allow for non-validated entries?