Skip to content

Instantly share code, notes, and snippets.

@sergiusens
Last active August 29, 2015 14:14
Show Gist options
  • Save sergiusens/97e9ea2e31d5f0fcc09a to your computer and use it in GitHub Desktop.
Save sergiusens/97e9ea2e31d5f0fcc09a to your computer and use it in GitHub Desktop.
RFCs for snappy

OEM snappy package

The oem snappy package is a snappy package type that is used to setup and personalize the system according to an OEM.

It covers a broad range, such as the software stack with it’s configuration and hardware enablement.

There can only be one snappy package of type oem and it can only be installed during image provision.

Customization entry points

Default packages

The oem snap can provide a set of default packages to be installed during either provisioning or first boot. The former is interesting to IoT scenarios while the latter is useful for cloud deployments (although cloud-init directly also serves the purpose for pure clouds).

In the case of first boot provisioning, the data is just fed into cloud-init for the appropriate actions to take place.

For the preinstalled case, the provisioning tool will download the package selection from the store and provision onto the system.

Snappy package configuration

Each snappy part can be configured per package or feeding a full configuration with all the parts and types.

The oem package, in it’s initial version shall support providing a config.yaml describing each part that is to be configured.

On first boot of the system, this configuration file will be processed to apply such configuration. Take notice that a factory reset creates a first boot scenario.

Where possible and relevant, and specifically the ubuntu-core configuration part will feed into cloud-init.

Store ID

If a different sore is required, it can be set with the store-id entry, snappy will use the store id set to reach the appropriate store.

Branding

Branding can be set in the form of a slogan and an image, snappy and it’s webdm counterpart will use this information to brand the system accordingly.

Hardware

dtb

The default dtb can be overridden by a key entry point in the package.yaml for the oem.

During provisioning if a dtb is specified, it will be selected as the dtb to use for the system. When an update for the oem package arrives and in the case of an AB partition layout, if the dtb is updated, the update will be installed to the other partition and request a reboot.

An upgrade path must be calculated by snappy to determine the priority and ordering for an ubuntu-core update and an oem one.

Bootloaders

Each system boots differently, assets that are currenly provided in flashassets in the device part can be provided here, this is important if the system desires to use the default device part which is the fully supported Ubuntu kernel and initrds.

Examples of assets provided here are MLO, u-boot, UEnv.txt script.bin or anything external to the system that allows for a system to boot.

These assets are meant to be used during provisioning, but can also be used against a running system, updating these assets on a running system can lead to a broken system as there may not be redundancy or fallback here (unless provided by the OEM).

Description

This is basically what is currently provided in the hardware.yaml from the current device part sans init and kernel setup.

Structure and layout

TODO

The current situation

The current spec states that ports are a top level entry in the package.yaml as

    name: go-example-webserver
    vendor: Alexander Sack <[email protected]>
    architecture: amd64
    icon: meta/go.svg
    version: 1.0.1
    services:
     - name: webserver
       description: "snappy example: golang mini webserver"
       start: ./go-example-webserver
    ports:
       required: 80

Critique

The ports declaration in it's current form gives only an indication that somewhere in this package the port is used. It is not known if it used by a service, a web front or a short lived binary.

Proposal

The proposal, aligned to certain security features that are bound to happen, is to make ports part of the service or binary that wants to use them. Additionally, the description of their intended purpose to be more clear.

What this means is that ports are:

  • bound to a service (or binary).
  • have an associated protocol.
  • tagged in such a way that other components can use them.

With these requirements in mind, the package.yaml would look like:

    name: foo
    description: description for foo
    version: 1.0.1
    services:
        - name: webserver
          description:  description of webserver
          start: bin/webserver
          ports:
               internal: 
                   localcomm1:
                       port: 3306/tcp
                       negotiable: yes
               external:
                   ui:
                       port: 8080/tcp 
                       negotiable: no

In this description, the port tags are:

  • localcomm1: which can be used for local communication within the application.
  • ui: this is a special key which will also be picked up by the webdm.

Tags are free form, but some can gain special use, such as an external/ui one which would be picked up by the webdm and used to open the application through the web.

There's also a new key, negotiable, which means that if the intended port is in conflict as it has been used by another package it will allow for it to be bound to another port (there is no implementation for this yet).

Multiple ports, ranges of ports

Multiple lists of ports can be separated by commas (preferably with no intervening whitespace), e.g.:

          ports:
               internal: 
                   localcomm1:
                       port: 3306/tcp,3307/tcp,3308/udp
                       negotiable: yes
               external:
                   ui:
                       port: 80/tcp
                       negotiable: no

Ranges of ports can be defined by separating a start port and an end port with a dash (ASCII -, unicode U+002D, unicode figure dash U+2012 or unicode en-dash U+2013), e.g.:

          ports:
               internal: 
                   localcomm1:
                       port: 3306-3308/tcp
                       negotiable: yes
               external:
                   ui:
                       port: 8080-8089/tcp
                       negotiable: no
@1stvamp
Copy link

1stvamp commented Feb 19, 2015

Looking good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment