maintainers.md 16 KB

Concerning Repository Owners and Package Maintainers

There's also a tutorial with example commands.

[[TOC]]

For Repository Owners

  1. Create a plain text file with the list of package metainfo URLs. Make sure you end the last URL too with a newline character.

  2. Create a certificate with cert --repo, and append it to the text file.

  3. Upload the file to a static webserver (you can have multiple files with different lists using the same cert, like "base.txt", "community.txt", etc.).

  4. If your repo is open, accept requests and URLs from developers (via email, github/gitlab issues whatever), sign their certs with cert --sign, send it back to them and add their metainfo URLs to the list.

  5. Generate a signed url list with build (and optionally an html for a webpage frontend).

Generating HTML Package Catalog

By specifying a html file name on the command line, build will generate a searchable package catalog too for you.

$ syspkg build repolist.txt index.html url=https://somewhere.com/repolist.txt

The page will be generated for packages using the system's locale, but the translatable labels must be specified for non-English pages. For that, you can use the following command line options: | Label | Description | |------------------|---------------------------------------------------------------------------------| | url | the real url of the repository (if the first argument to build is a local file) | | title | title of the page (default's to canonical name in the repository certificate) | | Repository | text of the repository link | | Search | search input field's placeholder | | Package Size | name of the package size coloumn | | Installed Size | name of the installed size coloumn | | Download | name of the coloumn with the download links | | Homepage | label for the package's homepage | | Bugtracker | label for the package's bugtracker | | Maintainer | label for the package's maintainer | | License | label for the package's license | | Depends | label for the package's mandatory dependencies list | | Suggests | label for the package's optional dependencies list | | Conflicts | label for the package's blocking dependencies list | | any other | translated package category name |

Create and Announce a Package

  1. First of all, if you don't have a developer cert already, create one with cert. You can have it signed with a repository owner. Users can only install packages which are signed by a trusted cert or by a cert issued by the repository's cert.

  2. Create a metainfo JSON, describing your package (name, version, description, etc.).

  3. Run syspkg's build command, this will create the payloads and add or update fields in the metainfo as well as the signature. You can use a git branch and then rely on github's or gitlab's "Download ZIP" feature. Otherwise upload your payloads to a static webserver.

  4. Upload your metainfo file to a static webserver next to the payloads (or to github, gitlab etc.)

  5. If you haven't done already, add your metainfo URL to one of the repositories, or create your own repository file and upload it to a static webserver.

For a new release, one need to repeat steps 3. and 4.

To check your certificate, simply do

$ syspkg cert | openssl x509 -text

Using syspkg build to Build Packages

You must specify an UTF-8 encoded, local JSON file with the package metainfo. Don't care about all the fields, build will add some of them.

Required fields

Field Description
id unix name of your package, must only contain the letters a-zA-Z0-9_-.
description an array with three string objects, language code, name, description
version canonical version string, (major).(featureset).(bugfix/patch)
release free form version string, could contain "-beta", "-pre", "-stable" etc.
url payload URL mask, may contain $VERSION, $RELEASE, $ARCH, $OSVER strings
category exactly one of the available category ids
license your project's license (MIT, GPLv3 etc.)

Optional fields

Field Description
depends list of required dependencies (optional)
suggests list of optional dependencies (optional)
conflits list of packages that this package is conflicting (optional)
eula your project's End User License Agreement URL (optional)
homepage your project's homepage URL with additional information (optional)
bugtracker your project's online bugtracker's URL (optional)
screenshots array of URLs, must be PNG (preferably with quantized palette, optional)
override struct for overriding default file categories (optional, see below)
postinst.env postinstall environment variables configuration (optional, see below)
postinst.commands postinstall commands to be executed (optional, see below)

The URL fields eula, homepage, bugtracker and screenshots might contain $LANG, this will be substituted by the user's locale two letter language code. If there's no such description translation in the json, then the first description's language code will be used.

This local json file is the first parameter to syspkg's build, and if no more arguments given, or they are in (arch)=(url) form, then the payloads are downloaded and checked (also with (arch)=(zipfile)). If they are given in the form (arch)=(dir), then payloads are generated to the current working directory by the name (packageid)-(version)-(arch).zip. This is preferred over github's and gitlab's "Download ZIP" URLs, because it generates a much better compressed ZIP64 files (using zstd instead of deflate).

Notes: for packages without native binaries, $ARCH is "any". If the "id" contains a "." dot, then only the first part of the name will be used when checking for dependencies.

$ syspkg build mypackage.json any=builddir

When you specify a directory as payload, a ZIP will be created for you in the current working directory.

$ syspkg build mypackage.json any=mypackage.zip

When you specify a local payload file, it will be scanned for files.

$ syspkg build mypackage.json any=https://some.org/mypackage.zip

Similarly to local payload files, you can specify a remote URL which will be downloaded and scanned for files.

If you have architecture specific payloads, you must list them all. You can mix the different payload methods. Example:

$ syspkg build mypackage.json x86_64=mypackage-x64.zip aarch64=build/arm64 riscv64=https://some.org/mypackage-rv64.zip

Running this command will add (or update) the payloads and files json fields and signature after. First field is an array of structs, each element with architecture, compressed payload size, uncompressed size, SHA checksum fields. The second is just an array of file sizes and string with file names.

Example

{
    "id": "myproject",
    "description": [
        { "en_US", "My Project", "English description\nanother line\nthird line" },
        { "en_GB", "Me Project", "British description" },
        { "de", "Meine Projekt", "Deutche Beschreibung" },
        { "es", "Mi Proyecto", "Español descripción" }
    ],
    "version": "1.0.1",
    "release": "1.0-beta-rc",
    "url": "https://github.com/myuser/myproject/archive/$VERSION-$ARCH.zip",
    "category": "tools",
    "depends": [ "libc 1.0.0", "libx11 6.0.0" ],
    "suggests": [ "libpng", "libjpeg 2.0.0" ],
    "license": "MIT",
    "eula": "https://github.com/myuser/myproject/raw/master/LICENSE",
    "homepage": "https://myuser.github.io/myproject",
    "bugtracker": "https://github.com/myuser/myproject/issues",
    "screenshots": [
        "https://github.com/myuser/myproject/raw/master/docs/screen1.png",
        "https://github.com/myuser/myproject/raw/master/docs/screen2.png"
    ],
    "postinst": {
        "env": [
            { "name": "FEAT1",   "type": "chk(disable,enable)", "desc": [ { "en", "Some feature", "Adds X feature" } ] },
            { "name": "CFLAGS",  "type": "str(-ansi -Wall)",    "desc": [ { "en", "Compiler flags", "Specify gcc flags" } ] },
            { "name": "LDFLAGS", "type": "str(-nostdlibs)",     "desc": [ { "en", "Linker flags", "Specify ld flags" } ] },
            { "name": "MAKEJ",   "type": "num(1,16,2)",         "desc": [ { "en", "Threads", "Number of threads" } ] }
        ],
        "commands": [
            "$SRCDIR/configure --with-cflags=$CFLAGS --with-ldflags=$LDFLAGS --$FEAT1-somefeature",
            "make -C $SRCDIR -j $MAKEJ all",
            "make -C $SRCDIR install"
        ]
    },
    "payloads": [
        { "x86_64", 1234, 23456, "be82deeabe8f4a38cdd6d5b195c287f32f7287d6861ca591b88b180d29b87f78" },
        { "aarch64", 1245, 23567, "d4056f2ff1a01ac23cbed8ad767f61f421f60a4d54ffab14c724ce1bd7000d13" },
        { "riscv64", 1256, 23678, "c0e8b735574fbd2261b1c738c1949fb6f35aae38cc05ab6661c00eaf1add81a9" }
    ],
    "files": [
        { 128, "bin/myproject" },
        { 256, "inc/myproject/myproject.h" },
        { 256, "inc/myproject/myproject.hpp" },
        { 512, "lib/libmyproject.so" }
    ]
}
------BEGIN SIGNATURE------
MIIE8jCCAtqgAwIBAgIEYBDuvzANBgkqhkiG9w0BAQsFADAwMQwwCgYDVQQDDANi
enQxEzARBgNVBAoMCm1haW50YWluZXIxCzAJBgNVBAYTAkhVMCAXDTIxMDEwMTAw
   ... more lines like these ...
1DzRRdPpbwviuVczINx7lr+qzjB13IFhlfh60AYhPtxkLof/qcqHlUT/EAhn9Hfx
cpZ2Wq/ehpYw=
------END SIGNATURE------

Building Binary Packages

In this case you should specify directories with compiled executables for syspkg build. If no payloadspec given, syspkg will use the "url" field in the metajson and will iterate on all available architectures (given in config.h) to find payloads.

Building Source Packages

Here you must specify a playload for architecture "any". The files in the payload must be source files, and you must specify "postinst" in the metajson describing how to compile the source.

Payload Contents and Format

Only ZIP (and ZIP64) supported. ZIP is standardized, well-supported on all operating systems, and code hosting servers can generate it dynamically out of a git branch. Supported compression methods: 0 - store, 8 - deflate (compatibility) and 93 - zstd (prefered).

The payload might contain a main directory (like "myproject-master/"), or it can include the specific directories in its root.

To simplify the package management significantly, syspkg expects special directory names in the payloads to categorize installed files. Where these should be extracted is configurable at compilation time, see config.h. There's one exception to the rule, the package that provides "base" (in json "id": "base"). That package is extracted to the root directory as-is, and cannot be uninstalled. It is a special package for updating the base operating system.

File Categories

It is very important to understand that top level directories in payloads do not represent the directory structure that's going to be installed (only sub-directories do). Instead top level directories are categories. There's only one exception to this rule, when the package is called "base".

Content Destination Description
bin/* BINDIR executable binaries and scripts
lib/* LIBDIR dynamically linkable, shared libraries (.so, .dll)
inc/* INCDIR include files
etc/* ETCDIR configuration files
shr/* SHRDIR shared files
var/* VARDIR variable files (if any, could be empty)
man/* DOCDIR manual pages and other help files
src/* SRCDIR source files

The payload directories (first coloumn above) is also configurable in config.h in general with BINPDR, LIBPDR etc. defines. If this does not suit a specific payload (because it comes from a 3rd party), you can override the category directories in the metajson with the override field, like this:

{
    "id": "myproject",
    "description": [
        { "en_US", "My Project", "English description" }
    ],
    "version": "1.0.1",
    "release": "1.0-beta-rc",
    "url": "https://github.com/myuser/myproject/archive/$VERSION-$ARCH.zip",
    "category": "tools",
    "license": "MIT",
    "override": {
        "bin": "build/cli",
        "lib": "build/so",
        "src": "code",
        "inc": "code/headers"
    }
}

Package Configuration

If postinst exists, it's a form definition and list of commands in json. The packager will generate a form according to that spec and the field's values (provided by the user) will be passed as environment variables to the commands (along with the actual destination directories), which in turn can create further configuration files (based on the user input), or they can compile the sources by calling configure / cmake and then make etc. Whatever needed to properly set up the package.

The environment variables' type can be:

Type Description
str(default) a string, defaults to default
num(min,max,default) a decimal numeric value
chk(unchecked,checked) a checkbox, string unchecked or checked is used as value
sel(opt1,opt2, ...) a selectbox, selects one of the optX strings

With string arguments, \\, \, and \) can be used to escape special characters in the strings.

Creating Meta-Packages

It is possible to create a meta-package, that is a package which doesn't have payloads, only dependencies. Such a package can be used to install a group of packages at once.

Example:

{
    "id": "gui",
    "description": [
        { "en_US", "Graphical desktop", "Installs the entire graphical environment" }
    ],
    "version": "1.0.0",
    "category": "tools",
    "depends": [ "libc", "libx11", "xorg-xserver", "xterm", "openbox", "xbill", "xroach" ]
}

Package Alternatives

Package unix names may contain one dot, and it represents an alternative. For example, if the package "id": "cron.vixie" is installed, that satisfies all packages that depend on "cron".