Controlling snap releases with channels, tracks and branches – Part 2

By Daniel Manrique, Engineering Manager at Canonical, Online Services

(Part 1)

Tracks

With tracks, developers can give a group of users the ability to stay on a robust, proven version of their software, even when a newer stable version has been released. Using a track can be useful if the newer stable version has some backward-incompatibilities or users may have other reasons to “stay behind”. For example, users may have a large body of work in a file format that’s incompatible with the new version, or older versions may have protocol or interoperability changes which would make it burdensome to upgrade.

Tracks can be useful for any software supporting parallel major releases.

An important feature of snaps is auto-refreshing, to help users stay up to date which improves their security. Tracks modify this behavior slightly: once a user decides to start following a track, only updates to that track will be installed when refreshing. Because of this, we want developers to be very aware of how tracks behave, and commit to ensuring relevant updates are propagated to tracks as well. As such, tracks need to be requested in the Snapcraft forum, approved by reviewers and created by a store administrator.

Example

Let’s look at an example situation where tracks are useful.

DataCorp’s webdb 5.0 is the first release with no support for the legacy webdb 1.0 format. The developer plans to keep backporting security patches to webdb 4.0 (the last version supporting the legacy format) but since version 5.0 is considered stable, they want to offer that by default to their users and encourage them to migrate. Still, some users have data they want to keep in the old format, and have expressed this concern to DataCorp, which has agreed to keep 4.0 alive and provide important updates (but no new features).

For this, DataCorp requests creation of a “4.0” track for webdb. When that is created, they can release the latest version of 4.0 to this channel (the channel name will be composed of the track and the risk). Let’s say Webdb 4.0.59 was uploaded as the snap’s revision 357 and is what’s currently released to the stable (remember, latest/stable) channel.

snapcraft release webdb 357 --release 4.0/stable

Track  Arch   Channel    Version  Revision
4.0    amd64  stable     4.0.59   357
              candidate  ^        ^
              beta       ^        ^
              edge       ^        ^

The '4.0/stable' channel is now open.

Note how the Track, which up until now when releasing had always been “latest”, now shows “4.0”. Snapcraft will show the channels for the track we’re currently releasing to.

Once the software is available in the new track, DataCorp informs their users (via their blog and Twitter, because it’s 2017):

“On December 31st, 2017, we will release webdb 5.0 as stable. As such, your webdb installation will automatically update to 5.0 a few hours after the release. If you want to stay on version 4.0, please use this command to switch to the 4.0 track:

snap refresh webdb --channel 4.0/stable

Security updates to the 4.0 series will be released in this track and you will receive them automatically.”

From now on, DataCorp developers can test and release both 5.0 (in the implicit latest track) and 4.0 (in the 4.0 track) releases. Both tracks have the well-known risks, so even for the 4.0 track, releases can be made to edge for testing and progressively release to more stable channels (4.0/edge, 4.0/beta, 4.0/candidate, 4.0/stable). Releases to 5.0, meanwhile, can be made just by using the risk names (edge, beta, candidate, stable):

snapcraft release webdb 525 --channel stable

Track   Arch   Channel    Version  Revision
latest  amd64  stable     5.0.1    525
               candidate  ^        ^
               beta       ^        ^
               edge       ^        ^

Branches

Let’s now look at branches, which can be used by a developer to provide more fine-grained control of their releases. Branches allow creating custom “temporary” channels to which a snap can be released. Because branches are temporary, when the branch “expires” the user automatically returns to the previously-followed channel, ensuring they will continue to get updates. Contrast this with the more permanent nature of tracks which imply a conscious decision to not get mainstream updates.

Example

Let’s look at an example scenario using branches.

John the Developer gets a report from a user that his great-game snap doesn’t work on the graphwiz graphics card. John codes a fix for this, and wants feedback from users with this specific hardware. He doesn’t want to release this to edge because he’s already working in parallel on some new levels which are released to edge, and wants to field test this fix before releasing to all stable users.

John can release the fix in a branch like so:

snapcraft push great-game_graphwiz_amd64.snap --release stable/graphwiz

Track  Arch  Channel         Version    Revision Expires at
latest amd64 stable          5          5
             candidate       ^          ^
             beta            ^          ^
             edge            new-levels 15
             stable/graphwiz graphwiz   25       2017-10-01T00:00:00.0

Here you can see version 5 on stable, new-levels on edge, and the newly-created stable/graphwizs channel with the “graphwiz” version on it. John can notify users with the affected graphics card to install and test the fix using:

snap install great-game --channel=stable/graphwiz

Note the expiration date for the branch, shown when the snap was released. Past this date, users will no longer be able to install from it. Existing users subscribed to that branch will automatically be returned to the branch’s parent channel (stable in this case which currently contains version 5) on the next refresh. Branches have two key characteristics: they expire and become unavailable after a specific amount of time, returning users to the risk channel they were using before; and they are not discoverable by default, meaning developers have to be explicit when asking users to install from a branch.

Once John has validated the fix works as expected, he can apply those changes to his version 5, and release a version 5.1 to stable. When the branch expires, users will get the stable version with the fixes for the problem.

Branches can also be explicitly closed, like any other channel. For example, if John releases the 5.1 version to stable with the fixes, he doesn’t have to wait for the branch to expire:

snapcraft close great-game stable/graphwiz

Track   Arch   Channel    Version     Revision  Expires at
latest  amd64  stable     5.1         26
               candidate  ^           ^
               beta       ^           ^
               edge       new-levels  15

The stable/graphwiz channel is now closed.

Once this is done, users will no longer be able to use --channel=stable/grapwhiz. But it doesn’t matter because the fixes were incorporated into stable. And any users who had installed from that branch will automatically return to tracking the stable channel. As we saw here, the branch allows releasing snaps with fixes targeted to specific problems, while ensuring users who install them will eventually automatically be returned to the “mainline”.

As we saw here, the branch allows releasing snaps with fixes targeted to specific problems

A branch’s expiration time will be reset if a new version of a snap is released to it. So if John were preparing builds for users to test and report back, he could still use the same branch, keeping it “alive” beyond the initial 30 day expiration by releasing to it.

Combining Branches and Tracks

Can Branches be used with a Track? Yes! Let’s say that a customer finds a data corruption issue with webdb 4.0 with a specific brand of network card. DataCorp issues a fix for this customer to try, putting it on a new branch from 4.0/stable (since 4.0 only receives critical updates, it makes sense to apply this change on what’s on the stable risk):

snapcraft push webdb-4.0_358_amd64.snap --release 4.0/stable/fix-crashcom-issue

Pushing webdb-4.0_358_amd64.snap
After pushing, an attempt to release to ['4.0/stable/fix-crashcom-issue'] will be made
Processing...|
Ready to release!
Revision 358 of 'webdb' created.

Track Arch      Channel                   Version         Revision Expires at
4.0   amd64     stable                    4.0.59          357
                candidate                 ^               ^
                beta                      ^               ^
                edge                      ^               ^
                stable/fix-crashcom-issue 4.0.59-crashcom 358      2017-01-01T00:00:00.0

The '4.0/stable/fix-crashcom-issue' channel is now open.

The customer can install it with:

snap install webdb --channel 4.0/stable/fix-crashcom-issue

Once the customer confirms the fix works well, DataCorp can integrate the fix directly in the stable 4.0 channel as version 4.0.60:

snapcraft push webdb-4.0_359_amd64.snap --release 4.0/stable

Pushing webdb-4.0_359_amd64.snap
After pushing, an attempt to release to ['4.0/stable'] will be made
Processing...|
Ready to release!
Revision 359 of 'webdb' created.

Track Arch  Channel                   Version         Revision Expires at
4.0   amd64 stable                    4.0.60          359
            candidate                 ^               ^
            beta                      ^               ^
            edge                      ^               ^
            stable/fix-crashcom-issue 4.0.59-crashcom 358      2017-01-01T00:00:00.0

And then close the branch:

snapcraft close webdb 4.0/stable/fix-crashcom-issue

Track Arch  Channel   Version Revision Expires at
4.0   amd64 stable    4.0.60  359
            candidate ^       ^
            beta      ^       ^
            edge      ^       ^

The 4.0/stable/fix-crashcom-issue channel is now closed.

Customers who were using the branch will be automatically returned to 4.0/stable. Of course, DataCorp can simply let the branch expire which should have a similar effect.

Meanwhile, DataCorp can add the fix to the current 5.0 releases (which exist in the latest track) and ask customers with that brand of network card to give it a try:

snapcraft push webdb-5.0_526_amd64.snap --release latest/stable/fix-crashcom-issue

Pushing webdb-5.0_526_amd64.snap
After pushing, an attempt to release to ['latest/stable/fix-crashcom-issue'] will be made
Processing...|
Ready to release!
Revision 526 of 'webdb' created.

Track  Arch  Channel                   Version        Revision Expires at
latest amd64 stable                    5.0.1          525
             candidate                 ^              ^
             beta                      ^              ^
             edge                      ^              ^
             stable/fix-crashcom-issue 5.0.1-crashcom 526      2017-01-01T00:00:00.0

The 'latest/stable/fix-crashcom-issue' channel is now open.

Note this example uses the explicit latest/stable/fix-crashcom-issue channel specification. As we saw above, this is equivalent to:

snapcraft push webdb-5.0-with-crashcom-fix.snap --release stable/fix-crashcom-issue

Conclusion

As you can see, the three elements provided by channels (track, risk and branch) provide useful mechanisms by which a publisher can control which revisions of a snap are available to different groups of specific users. By combining them, developers can have one or more “stable” series of their software, each with a progression of stability levels, along with ways to release targeted code fixes for specific purposes.

This helps maintain users up to date, allows them to make conscious choices about which series of software to follow, and reduces the developer’s need to provide side channels for distributing snaps. The use of native snap facilities like channels helps maintain a consistent user experience and unburdens the developer from having to invent distribution mechanisms.

More information

The reference documentation on channels, tracks, risks and branches is here. Please find us on the forum if you have any questions about leveraging channels for your project.

Posted in: