Migration to Debian style releases via the APT ecosystem

Introduction

At the time of this writing, MergeTB software is packaged as deb packages and are released in a single APT style repository.

But due to the need to sustain a development cadence that accommodates for long term maintenance alongside near term rapid prototyping and evolution, the decision has been made to move towards a more nuanced model of using APT style repositories and deb packaging.

This model would follow the stock Debian world view of testing/unstable/stable release versions along with other conventions/lessons lifted from the stock Debian release management world.

The purpose of this RFC is to iron out what these APT style repositories would look like to consumers of them, and what general release management/engineering model we should use to populate them. A separate RFC (albeit linked to this one) should be used to iron out the details of the CI/CD strategy and tactics for powering these releases.

Some initial conversations were recently held in the Factory Mattermost channel and some of the requirements captured here. They were mined for the starting material here.

Requirements

Functional

  • Be compatible with the following families of APT style distributions
    • Debian
      • Starting with buster and bullseye
    • Ubuntu
      • Starting with the 20.04 version
      • Examples of current software that would be candidates for this
        • mergexp (Python library, has no packaging at the moment)
        • mergetb cli
        • Raven
  • Allow for long term lines of development to be released as previews or for integration/system testing without interfering with production ready releases
  • Maintain independent packages for multiple releases for the same software
    • The motivating example here is the wgd package. On Buster it needs the wireguard-dkms package, but on Bullseye that package is on it’s way to becoming not a thing as wireguard is in the kernel proper as of 5.5.
  • Support efficient development workflows for creating packages for software under development
    • For example, being able to create draft versions of deb packages and overlay them onto production releases or releases-under-test

Non-Functional

  • Be loosely compatible with deployment environments which are isolated from the public internet
    • Account for the needs of isolated environments by providing hook points, or configuration alternatives that allow for adaptation with a reasonable cost.
    • Doesn’t mean wear a hair shirt trying to auto-magically switch gears between regular and isolated worlds. Just means make it possible with a modicum of reasonable effort and on a sustainable basis.
  • Be structured in a manner that allows leveraging FOSS tooling for APT
    • e.g. Don’t do something weird that pays lip service to APT’s conventions, but isn’t sufficiently compatible to allow you to use tools like reprepro etc.

Tech Design

This is in flux, incomplete, and will get updated as living document based on discussions in the thread

Goals here are to design what the MergeTB APT repositories should look like to downstream consumers, and what high level workflows should be used to curate them.

Based on past conversations with @ry and the lessons learned so far with the current MergeTB, the current intent is to replicate the Debian mental model of testing/unstable/stable/oldstable releases.

Reference Material

Will comment with factoids and add the links to the comments here.

Precis of the stock Debian mental model of release management.

Distribution codenames

  • Names for a particular releases of the Debian distribution
  • Examples: stretch, buster, bullseye, sid

Distribution releases

Release Name Current Code Name Release Purpose
oldstable stretch The previous stable release
stable buster The current stable release
testing bullseye The current development state of the next stable release
unstable sid A rolling development version, always code named sid

Progression tends to be

  1. New packages are introduced into unstable
  2. Once these new packages meet a certain criteria, they graduate to testing
  3. Once the testing release meets a certain criteria, it becomes the new stable, and the previous stable is renamed to oldstable
    Over time, different codenames are assigned to various incarnations of the releases. Though the unstable release is always codenamed sid.

A single repository is exposed for all releases, and APT components are used to delineate slices according to Debian release version: deb <base_uri>/debian/ {component} ...

In addition, the first “component” is used to denote different release channels:

  • The general pattern is:
    • <short_code_name>
    • <short_code_name>-security
  • For example, for the buster release:
    • buster
    • buster-security

Reference Material

More information can be found here:

Precis of the Ubuntu mental model for release management

Distribution codenames

  • Names for particular releases of the Ubuntu distribution
  • Examples: trusty, bionic, focal

Distribution releases

Release Version Short Code Name Purpose
16.04 xenial Long term support
18.04 bionic Long term support
19.04 disco Interim release
19.10 eoan Interim release
20.04 focal Long term support
  • Long term suport (LTS) releases are published every 2 years
    • They get hardware and maintenance updates for ~2 years after that
    • They get maintenance updates for the next ~2 years
    • They get extended security maintenance for the next ~4 years after that
  • Interim releases are published every six months and only supported for 9 months

A single repository is exposed for all releases, and APT components are used to delineate
slices according to Ubuntu release version: deb <base_uri>/ubuntu/ {component} ...

In addition, the first “component” is used to denote different release channels:

  • The general pattern is:
    • <short_code_name>
    • <short_code_name>-updates
    • <short_code_name>-backports
    • <short_code_name>-security
  • For example, for the xenial release:
    • xenial
    • xenial-updates
    • xenial-backports
    • xenial-security

Reference Material

More information can be found here:

Also, the last two posts were more of a “here’s some homework I did to improve my understanding, please let me know if its (a) wrong , or (b) incomplete” :slight_smile:

My intent was to enumerate them both, so that we’d be anchored with a common understanding before diving into how we want to evolve MergeTB’s approach.

Precis of the current MergeTB release mental model

YMMV this is incomplete and a work in progress, and I will update it in place. Please feel free to comment with additional information that I can roll into this.

Overview

The current MergeTB release model uses a single APT repository using the Debian-style “first component is the release code-name” convention:

deb https://pkg.mergetb.net/debian bullseye main

Snap packages are also used, but the mid-to-long term intent is to transition completely to deb packages as the common denominator.

Targeted distributions

Currently Debian bullseye is the preferred baseline for installation of most Merge software, with buster supported as well.

Workflow/lifecycle

details forthcoming, still doing the homework

Reference Material

GitLab repositories

As a purely mechanical note. We are currently using pkg.mergetb.net, however - when we make the transition to this new system I think we’ll make a clean break to deb.mergetb.net so the two can operate simultaneously in the transition period before we wind down pkg.mergetb.net.

Governing Package Migration Through Testing

A critical component of being successful with maintaining the universe concept is governing the migration of packages from unstable, to testing and on to stable through testing. In essence, one could view the entire point of the universe system as creating three distinct spaces where a set of packages are known to work well together at a given level of rigor and testing.

A sketch of what the testing requirements could look like (very much a starting point) follows.

Main Universes

Unstable

For unstable the bar is very low, basically does the code compile using other libraries in unstable and are interfaces such as gRPC/OpenAPI etc compatible. Unit tests should also be passing to be considered for unstable. Runtime issues arising from cross component interactions should be documented and fixed with time but not preclude inclusion in unstable.

Testing

To enter testing, the component should pass all integration tests alongside all the other packages in testing.

Stable

To enter stable, the component should pass all current integration tests as well as a suite of regression tests.

The Outerverses

Parallel universes? Perhaps. Much in the way MergeTB currently maintains it’s own side show that plugs into Debians stable/testing/unstable - it should be possible for developers, or teams of developers maintaining a parallel universe of Merge components for a specific set of requirements with as little friction from the primary universes as possible.

1 Like

Hotfix repos?

Something else to consider is front loading bug fixes in packages that impact Merge directly but have not surfaced in the regular Debian universe. This situation happened recently where a bug in systemd prevented bridge interfaces from being created correctly but the fix is slow to work through debian but we need something to keep the train moving.

My solution to this problem was to build and install the problematic package from upstream source at a commit after the fix had been applied. However, it would be much better if we could fix this out of band and push to something like a mergetb-hotfixes repo or somesuch it’s likely the repo would need to be universe specific, so something like

  • mergetb-stable-hotfixes
  • mergetb-testing-hotfixes

After re-reading your “outerverses” piece this morning, I came up with some additional questions for you about what you want to accomplish with it.

It seems like there are a couple scenarios for tailoring package distribution beyond the stock Debian baseline:

  1. Take one of the primary universes (unstable/testing/stable) and grab a subset of it using the a Debian “component” coordinate. e.g. “main” versus “non-free” in the upstream Debian world.
    • In this scenario, the developers would be beholden to the release cadence of the primary universe they were using, but in return, they would not have to invent and curate own of their own. And their packages stay aligned with the primary universes, and are easier to fold back into a “main” repository component if need be.
  2. Work with a parallel universe to on of the primaries
    • In this scenario, the developers’ parallel universe would have to have its own release cadence separate from that of the primary universes. This means that MergeTB would now have a full release channel to pay overhead on. It also means that this parallel universe is much more likely to drift away from the primary universes, and be more costly to reconcile.

Both of the above are possible using the available FOSS tools, but they have different short and long term costs-of-ownership for the maintainers, as well as for the consumers of them.

It would help if you could lay out some more specific developer use-cases if you had any in mind. Then we could see where they fit in the above scenarios, or if they represent an entirely different pattern.

@ry, in regards to your hotfix idea, I agree with the basic idea of it. I’m a bit fuzzy on how the Debian folks do it, but I think they currently route this stuff via their buster-updates and buster-security “components” in their stable/testing universes.

I will look into it further as I prototype.

So in an attempt to focus all of this here is the immediate use case I think we should focus on.

  1. Creating the 3 universes stable/testing/unstable
  2. Building a VTE environment from one of the 3 universes, this also means having tb-deploy be universe aware.
  3. Support for building packages within a particular universe. Primarily for merge this means code level dependencies that pull in protobufs and libraries. So while this is not really an APT thing it’s a critical part of the universe concept.
  4. Support for deploying development packages built within a universe context (but are ahead of the resident package in that universe) within various testing environments along side the other packages from that universe, including but not limited to the VTE.

So basically what this is saying from the developers perspective is the following. I need to work on packages X,Y and Z in universe U. So I create whatever testing environment I need based on U and I then build/deploy/test my development packages within that environment.

From the system level maintainers point of view, developers are working on packages as per above. When they are ready to propose a migration of the packages into a particular universe. We need an automated way to test those packages within the context of the target universe based on artifacts produced by CI. This is a gating function for package migration.

Preamble

Just trying to capture some take aways from a conversation that @ry and I had in side-band.


(EDITORIAL ASIDE)

@ry -> I took some liberties with the universe terminology to try to make the distinction between a “release channel” (e.g. Debian testing/stable/unstable) and a “universe” consisting of a set of packages composed from a combination of release channels and optional package filtering or overlays.

Please chime in if this doesn’t match your intended usage.


Universe terminology

A MergeTB “universe” would be composed from the following:

  • A release channel (testing/stable/unstable) as a baseline
  • Optional filtering of that to focus the testing context on a subset of the MergeTB ecosystem
  • Optional overlay of packages built out-of-band of the ci/cd system (for local development)

So an “end to end testing universe for release-candidates” might include:

  • The testing release channel

Whereas an “end to end testing universe for daily builds” might include

  • The unstable release channel

Or a “end to end testing of a single project’s release candidate” might include

  • The stable release channel
  • Overlaid with every package from the testing release channel that the single project depends on, or is delivered as

And a “end to end testing universe for a developer’s local draft of a single project” might include:

  • The testing release channel
  • An overlay of deb packages built on the developer’s local machine

Day to day developer experience

The idea development process we’d like to get to is one where a developer working on software artifact X can do the following:

cd `X`
make universe environment=VTE release_channel=testing
make universe-deploy
make test suite=full-integration

or

cd `X`
make universe environment=Mock-VTE release_channel=testing
make universe-deploy
make test suite=api-stress

Horizon line for moving forward

  1. putting a deb.mergetb.net package server in place that can support the stable/testing/unstable release channel model
  2. building devops machinery and processes to push artifacts into (1) at well defined points (like MRs onto specific tags)
  3. building devops machinery to construct various testing universes from (1), starting with the VTE as that is a well defined thing and later moving on to the Mock-VTE for stress testing
  4. building devops machinery that can be consumed by individual projects to deploy themselves into a universe-based testing environment.
  5. building e2e as well as capability-specif test suites to hammer on a particular universe instance in a testing environment

Looks great! #makeitso

:+1:

Based on last few weeks of prototyping and discussions with @ry


Release management design overview

Terminology

  • MergeTB release refers to a release of artifacts from the MergetB ecosystem
    • Could include both OS packages as well as machine images etc.
    • Not tightly coupled to an upstream OS release name

Ecosystem Releases

Maintain these channels of releases of the MergeTB ecosystem as a whole:

Release Channel Purpose
oldstable Frozen cut of previous production release
oldstable-updates Rolling updates for previous production release
oldstable-security Rolling security-fixes for previous production release
stable Frozen cut of current production release
stable-updates Rolling updates for current production release
stable-security Rolling security fixes for current production release
testing Rolling release of candidates for the next production release
testing-updates Mock of rolling updates for next production release
testing-security Mock of rolling security fixes for the next production release
unstable Rolling release of artifacts unassociated with any previous, future, or current release

Use code-names for releases of the MergeTB ecosystem as a whole (based on fruit names from Wikipedia):

Release Code Name Release Version Notes
tomato n/a This code name is permanently mapped to the release channel unstable
lotus n/a Placeholder for the mythical non-existent previous stable release
apricot 0.x Current production release
banana 1.x Next release candidate (e.g. Merge 1.0 on the roadmap)

OS Package Releases

Releases of MergeTB operating system packages are traced to the ecosystem-level code-names (above).

The idea being that folks will track the code-name, not the release channel name, in their sources.list.

Debian and Ubuntu

Distribution Names

Mapping from MergeTB release nomenclature to APT/.deb “Distribution” names:

MergeTB -Release Channel MergeTB - Release Code Name APT - Distribution
unstable tomato tomato
stable apricot apricot
stable-updates apricot apricot-updates
stable-security apricot apricot-security
testing banana banana
testing banana banana-updates
testing banana banana-security
oldstable lotus lotus
oldstable-updates lotus lotus-updates
oldstable-security lotus lotus-security

Repositories

Mapping to MergeTB’s Nexus hosted APT repositories:

MergeTB - Release Channel Nexus APT - Repo Name Nexus APT - Dist Name
unstable mtb-apt-tomato tomato
stable mtb-apt-apricot apricot
stable-updates mtb-apt-apricot-updates apricot-updates
stable-security mtb-apt-apricot-security apricot-security
testing mtb-apt-banana banana
testing-updates mtb-apt-banana-updates banana-updates
testing-security mtb-apt-banana-security banana-security
oldstable mtb-apt-lotus lotus
oldstable-updates mtb-apt-lotus-updates lotus-updates
oldstable-security mtb-apt-lotus-security lotus-security

Additional assumptions:

  • MergeTB will stand up a Sonatype Nexus repository server
  • There will be an Nginx reverse proxy for http requests to it
    • It will map public requests for http://apt.mergetb.net to specific APT repositories hosted by Nexus

Example name mappings that would be done by Nginx:

Release Channel Public Nginx URL Internal Nexus URL
tomato http://apt.mergetb.net/tomato http://<nexus>/repositories/mtb-apt-tomato
stable http://apt.mergetb.net/apricot http://<nexus>/repositories/mtb-apt-apricot
stable-updates http://apt.mergetb.net/apricot-updates http://<nexus>/repositories/mtb-apt-apricot-updates
stable-security http://apt.mergetb.net/apricot-security http://<nexus>/repositories/mtb-apt-apricot-security
testing http://apt.mergetb.net/banana http://<nexus>/repositories/mtb-apt-banana
testing-updates http://apt.mergetb.net/banana-updates http://<nexus>/repositories/mtb-apt-banana-updates
testing-security http://apt.mergetb.net/banana-security http://<nexus>/repositories/mtb-apt-banana-security
oldstable http://apt.mergetb.net/lotus http://<nexus>/repositories/mtb-apt-lotus
oldstable-updates http://apt.mergetb.net/lotus-updates http://<nexus>/repositories/mtb-apt-lotus-updates
oldstable-security http://apt.mergetb.net/lotus-security http://<nexus>/repositories/mtb-apt-lotus-security
Example sources.list entries

The sources.list examples below all use the public Nginx URL for the Nexus managed repositories.

Tomato

Permanent “unstable” release channel

deb http://apt.mergetb.net/tomato tomato main
deb-src http://apt.mergetb.net/tomato tomato main

Apricot

Current “stable” release channel

deb http://apt.mergetb.net/apricot apricot main
deb-src http://apt.mergetb.net/apricot apricot main

deb http://apt.mergetb.net/apricot-updates apricot-updates main
deb-src http://apt.mergetb.net/apricot-updates apricot-updates main

deb http://apt.mergetb.net/apricot-security apricot-security main
deb-src http://apt.mergetb.net/apricot-security apricot-security main

Banana

Current “testing” release channel

deb http://apt.mergetb.net/banana banana main
deb-src http://apt.mergetb.net/banana banana main

deb http://apt.mergetb.net/banana-updates banana-updates main
deb-src http://apt.mergetb.net/banana-updates banana-updates main

deb http://apt.mergetb.net/banana-security banana-security main
deb-src http://apt.mergetb.net/banana-security banana-security main

Lotus

Current “oldstable” release channel

Reminder that this is mock only, until banana is new stable, and apricot becomes oldstable.

deb http://apt.mergetb.net/lotus lotus main
deb-src http://apt.mergetb.net/lotus lotus main

deb http://apt.mergetb.net/lotus-updates lotus-updates main
deb-src http://apt.mergetb.net/lotus-updates lotus-updates main

deb http://apt.mergetb.net/lotus-security lotus-security main
deb-src http://apt.mergetb.net/lotus-security lotus-security main

Packages

The same “logical” artifact may be released as multiple instances of “physical” packages, but these physical packages should be uniquely identifiable via their package versioning.

Multiple versions of these packages can end up in different APT repositories at various times in the packge’s own life cycle.

Workflows

General workflows are as follows:

  • Experimental work
    • Drafts not intended for a release candidate or as an updates/fix for a previously released candidate, will get
      published to the unstable release channel.
  • Releasing the current release candidate
    • No package publication happens.
    • A new code-name is picked for the new “testing” release and Nexus APT repositories etc. are created for it
    • The GitLab ci/cd plumbing is reconfigured to change its aliasing between code names and the release channel
      names.
      • The code-name currently aliased by stable is now aliased by oldstable
      • The code-name currently aliased by testing is now aliased by stable
      • The new code-name for the next “testing” release is now aliased by testing
  • Updates and security fixes for the current released candidate
    • General updates get published to the stable-updates release channel
    • Security fixes get published to the stable-security release channel
    • In addition, if applicable, they should be published to the testing release channel for inclusion in the
      next release candidate.
  • Updates and security fixes for the previous released candidate
    • General updates get published to the oldstable-updates release channel
    • Security fixes get published to the oldstable-security release channel
    • In addition, if applicable, they should be published to the testing release channel for inclusion in the
      next release candidate.
Versioning

In general, follow the Debian package maintainer conventions for “upstream_version” versus “debian_version”.

  • The “upstream_version” should be tracable to a GitLab v<semver> release tag.
    • The source git tags do not include the packaging specific iteration numbers and “debian versions”
  • Packages should always explicitly state an iteration number, starting at 1
    • Based on advice from Debian maintainer docs etc.
  • The “debian-version” should reference Debian/Debian-derivative releases (e.g. Ubuntu) as per the guidelines
Example Source Git Tag Target OS Example package version Example package file name
v1.0 Any Debian or Debian-derived 1.0-1~1 strawman-1.0-1.deb
v1.0 Specific to Debian buster 1.0-1~1deb10 strawman-1.0-1~1deb10.deb
v1.0 Specific to Debian bullseye 1.0-1~1deb11 strawman-1.0-1~1deb11.deb
v1.0 Specific to Ubuntu focal 1.0-1~1ubuntu0.20.04 strawman-1.0-1~1ubuntu0.20.04.deb
Publication

Updates to current stable release channel:

Development Event GitLab Event Nexus Event
First releasable draft of the project has accumulated in master Maintainer creates release tag v1.0 based on master branch
CI/CD job builds deb package files based on the contents of v1.0 tag
CI/CD job publishes deb packages to the current unstable repo tomato repo gets updated
Changes are submitted for the next draft A merge request is submitted to master branch and accepted
Another releasable draft of has accumulated in master Maintainer creates release tag v1.2 based on master branch
CI/CD job builds deb package files based on the contents of v1.2 tag
CI/CD job publishes deb packages to the current unstable repo tomato repo gets updated
Draft is ready for integration/system testing Project maintainer creates releaset tag dist_testing based on v1.2 tag
CI/CD job builds deb package files based on the contents of dist_testing tag
CI/CD job publishes deb packages to the current testing repo banana repo gets updated
Draft is ready for inclusion in stable-updates Project maintainer creates releaset tag dist_stable-updates based on v1.2 tag
CI/CD job builds deb package files based on the contents of dist_stable-updates tag
CI/CD job publishes deb packages to the current stable-updates repo apricot-updates repo gets updated

Security fixes for current stable release channel:

Development Event GitLab Event Nexus Event
A security issue is found for a draft previously published to stable A feature branch, sec-issue-N is created based on the git tag of the affected release
A fix for the security issue is submitted A merge request is submitted to sec-issue-N branch and accepted
Staging security fix candidate for side-band integration/system testing Maintainer creates release tag v1.3 based on sec-issue-N branch
CI/CD job builds deb package files based on the contents of v1.3 tag
CI/CD job publishes deb packages to the current unstable repo tomato repo gets updated
Draft is ready for inclusion in stable-security Project maintainer creates releaset tag dist_stable-security based on v1.3 tag
CI/CD job builds deb package files based on the contents of dist_stable-security tag
CI/CD job publishes deb packages to the current stable-security repo apricot-security repo gets updated
The security fixes are rolled into current mainline of development Maintainer submits a merge request that brings the changes in from sec-issue-N branch
to master branch.

Security fixes for oldstable release channel:

Development Event GitLab Event Nexus Event
A security issue is found for a draft previously published to oldstable A feature branch, sec-issue-N is created based on the git tag of the affected release
A fix for the security issue is submitted A merge request is submitted to sec-issue-N branch and accepted
Staging security fix candidate for side-band integration/system testing Maintainer creates release tag v1.4 based on sec-issue-N branch
CI/CD job builds deb package files based on the contents of v1.4 tag
CI/CD job publishes deb packages to the current unstable repo tomato repo gets updated
Draft is ready for inclusion in stable-security Project maintainer creates releaset tag dist_oldstable-security based on v1.4 tag
CI/CD job builds deb package files based on the contents of dist_oldstable-security tag
CI/CD job publishes deb packages to the current oldstable-security repo lotus-security repo gets updated
The security fixes are rolled into current mainline of development If applicable, maintainer submits a merge request that brings the changes in
sec-issue-N to master branch.
1 Like

Note: if/when this proposal gets turned into the new normal, I’d document it with several forum wiki pages rather than overload a single one like I did above.

To re-iterate on the chat conversation in Factory, I’m fine with changing the code-names.

The fruit names were a placeholder.

However, any code-name scheme should meet the following criteria:

  • Goes a-z ordering
  • Doesn’t collide with an existing code-name namespace of a Debian or Debian derived distribution
  • Doesn’t have copyright or litigious IP owner issues (no Baby Yoda)
  • Won’t offend most of the globe
  • Short-ish names (less than or equal to 16 characters)
  • Can be expressed in the ASCII portion of UTF-8
    • No umlauts!
  • Only alphanumeric, no punctuation/whitespace
  • Case insensitive

Most of the above are constraints driven from:

  • Need for unambiguous names from a human perspective
    • Provide natural sorting orders to the names
    • Make it easy to visually discern name differences while tired or stressed
    • Make conversations easier without having to over qualify the names
  • Need for unambiguous names from a machine perspective
    • Mitigate issues with tooling that doesn’t grok non-ASCII

We’ll need code-names for:

  • The permanently unstable
  • The mock previous release (oldstable)
  • The grandfathered current release (stable)
  • The upcoming release (testing)

Some reference points from https://itsfoss.com/linux-code-names/

Linux mint

The major releases increment the alphabetical order of the codename while the minor ones carry the same starting alphabets but change the name.

For example, Linux Mint 17.1 is Rebecca, 17.2 is Rafaela and 17.3 is Rosa.

Elementary OS

elementary OS has version numbers that match the incremental pattern like 0.X. So, the first stable release of elementary OS was 0.1 and then came 0.2 and the current stable version is elementary OS 0.3.

As far as the codename is concerned, elementary OS prefers to have a mythological god’s or goddess’ name. Usually these names are taken from Roman/Nordic mythology. This gives us codenames like Jupiter, Luna, Freya (earlier ISIS) and perhaps the upcoming Loki.

There are no alphabetical constraints here.

0.1 — Jupiter
0.2 — Luna
0.3 — Freya

OpenSUSE

The first OpenSUSE release in 2005 was OpenSUSE 10.1. I do not know why it started with 10 and not 1. But ever since, the major release increases the version number before the decimal while the minor releases increase the version number after decimal points. This gives us version numbers like OpenSUSE 11.3, 11.4, 12.1, 12.2 etc.

Initial releases of OpenSUSE did not have a codename. It was with the release of OpenSUSE 11.2 that we start seeing a codename.

Needless to say that OpenSUSE has a green aura to it. This greenish touch is extended to the codenames as well. OpenSUSE codenames are actually a shade of the color green. That explains the codenames like Emerald, Teal etc for OpenSUSE.

11.3 — Teal
11.4 — Celadon
12.1 — Asparagus
12.2 — Mantis
12.3 — Dartmouth
13.1 — Bottle
13.2 — Harlequin
Leap 42.1 — Malachite

Following up to @ry 's ask in chat for more Zelda to match existing MergeTB nomenclature:

One exception is the Moa network emulator which must run Debian Kass. Kass is our own distro of Linux that has a specific kernel, libc and other low level components for doing high performance network emulation.

If we want to continue Zelda style, then the only potential confusion might be if we use “Kass” as the code-name of specific MergeTB release.

If we stick to using release code-names which are Zelda centric, but don’t collide with “Kass” , we can retain the zelda affinity without confusion between “a release of the MergeTB ecosystem as a whole” and “a name of a custom Linux distro in the MergeTB ecosystem”.

So based on [my quick read of the fandom wiki for legend of zelda … (I’m not a zelda aficionado so the names are new to me), our release code name queue could look like this:

Code Name Release Channel Notes
anju unstable Permanent mapping, anju is always unstable
bellum oldstable Mock previous stable release
carlov stable Grandfathered current MergeTB production
daruk testing Future MergeTB 1.x release
eldin n/a Next testing release code-name after daruk is released as stable

The above are just a strawman, Zelda fans are free to offer up alternatives, as long as they match the scheme requirements.