unos-repository

APK repository for unos
git clone git://git.finwo.net/misc/unos-repository
Log | Files | Refs | README

README.md (5603B)


      1 unos-repository
      2 ===============
      3 
      4 The UNOS package repository: every `.apk` that makes up the OS, the tooling
      5 that builds and signs them, and the CI pipeline that publishes them.
      6 
      7 This repo produces a signed apk repository. It does not assemble a rootfs, an
      8 image or an installer -- that is the `unos` repo, which consumes what is
      9 published here over HTTP. The `unosd` daemon's source lives in its own repo and
     10 arrives here as a tag-pinned tarball like any other dependency.
     11 
     12 Published to `https://repo.unos.finwo.net/<arch>`.
     13 
     14 
     15 Layout
     16 ------
     17 
     18     packages/<name>/template     build recipe (sourced by mk/build.sh)
     19     packages/<name>/files/       static files installed by the template
     20     packages/<name>/patches/     *.patch, applied in order to WRKSRC
     21     mk/                          the build driver and its tooling
     22     .conductor.yml               CI pipeline, GENERATED from the dep graph
     23 
     24 
     25 Building
     26 --------
     27 
     28     ./mk/bootstrap-host.sh       build pinned muon + apk into build/host/bin
     29     ./mk/build.sh <pkg>          build one package
     30     ./mk/build-all.sh            build everything in dependency order
     31     ./mk/repo-index.sh           (re)generate and sign APKINDEX.tar.gz
     32 
     33 `mk/bootstrap-host.sh` must run first: `apk-tools` declares `muon` as a
     34 hostmakedepends, and it is built here rather than installed from a
     35 distribution, so `mk/deps.sh check` reports it missing until bootstrap has
     36 produced it.
     37 
     38 See `mk/README.md` for the full tooling reference and `packages/README.md` for
     39 the template format.
     40 
     41 
     42 Where source comes from
     43 -----------------------
     44 
     45 Two mutually exclusive mechanisms, kept apart deliberately:
     46 
     47 `distfiles=` is third-party upstream source. It **must** carry a matching
     48 `checksum=` sha256; `mk/build.sh` refuses to build without one. We are trusting
     49 a server nobody here controls, so the tarball is pinned by content.
     50 
     51 `srcfiles=` is our own source, fetched by tag from `git.finwo.net`. It carries
     52 no checksum: the tag is the pin and TLS is the transport, and a forge
     53 regenerates tag archives, so they are not byte-stable and a sha256 would fail
     54 for reasons indistinguishable from tampering. Only `unosd` uses this today.
     55 
     56 Keeping them separate means "no checksum" can never silently apply to an
     57 upstream tarball.
     58 
     59 Cached source lives in `build/work/sources/`, and is only fetched when absent.
     60 `srcfiles` entries are cached under `<pkg>-<basename>` because these URLs end
     61 in the tag, so the bare basename is often just `v0.1.0.tar.gz` and two
     62 first-party packages at the same version would otherwise share one entry.
     63 
     64 **While git.finwo.net does not yet serve tag archives**, seed the cache by
     65 hand and the fetch is skipped:
     66 
     67     git -C ../unosd archive --format=tar --prefix=unosd/ HEAD \
     68       | gzip -n > build/work/sources/unosd-v0.1.0.tar.gz
     69 
     70 
     71 Signing
     72 -------
     73 
     74 Packages and the index are signed with RSA-4096 (apk mandates RSA). The key is
     75 resolved by `mk/sign-key.inc`, in order:
     76 
     77     $UNOS_KEY_APK_RSA_PRI    provided by the unos-sign-key CI worker feature
     78     $UNOS_SIGN_KEY           manual override
     79     ./.sign-key              local selection, via mk/keymgmt.sh use
     80     the single *.rsa in ~/.unos-keys/
     81 
     82 `mk/build.sh` names the signature record after the key that signed it
     83 (`.SIGN.RSA.<keyname>.rsa.pub`), and the apk client verifies it against
     84 `/etc/apk/keys/<keyname>.rsa.pub`, shipped by `packages/unos-keys`.
     85 
     86 **Every CI worker has a distinct keypair**, so the signer is whichever worker
     87 the conductor scheduled the build on. `packages/unos-keys` therefore trusts all
     88 four. Ship fewer and verification fails for an arbitrary subset of packages
     89 that changes run to run -- a failure that looks like corruption rather than a
     90 missing key. Adding a worker means publishing `unos-keys` *before* that worker
     91 builds anything.
     92 
     93 Any one worker can consequently sign packages every client trusts. The intended
     94 end state is a release step that re-signs with a single key and merely accepts
     95 these as inputs; it does not exist yet.
     96 
     97 
     98 CI
     99 --
    100 
    101 `.conductor.yml` is **generated** -- do not edit it:
    102 
    103     ./mk/gen-pipeline.sh --write     regenerate
    104     ./mk/gen-pipeline.sh --check     fail if stale (run by tests/unit/test_deps.sh)
    105 
    106 The conductor treats the pipeline as data and will not execute repository code
    107 to build its task graph, so the per-package `needs` edges have to be written
    108 out literally. Generating them from `makedepends` keeps the templates the
    109 single source of truth; drift is a test failure rather than a package building
    110 against a stale dependency.
    111 
    112 Tasks run in ephemeral containers with no mounts and no artifact sharing, so
    113 each package seeds its sysroot from the published repo (`mk/sysroot.sh`) and
    114 publishes its own result (`mk/publish.sh`). `needs` provides ordering only.
    115 
    116 The pipeline requires a worker advertising the **`unos-sign-key`** feature,
    117 which mounts the signing key and exports `UNOS_KEY_APK_RSA_PRI`,
    118 `UNOS_KEY_APK_RSA_PUB`, `UNOS_KEY_SUPERCOP_PRI` and `UNOS_KEY_SUPERCOP_PUB`.
    119 Feature names are global to the conductor, which hosts more than UNOS, hence
    120 the project prefix. A task requiring a feature no worker advertises is never
    121 scheduled -- it does not fail, it silently never runs.
    122 
    123 S3 credentials arrive as `BUCKET_ACCESS_KEY`, `BUCKET_SECRET_KEY`,
    124 `BUCKET_NAME`, `BUCKET_ENDPOINT` (a URL) and `BUCKET_REGION` (a region name).
    125 
    126 
    127 Testing
    128 -------
    129 
    130     ./tests/run.sh
    131 
    132 Graph validation, pipeline freshness, applet policy and packaging layout. Tests
    133 that need a package built will skip rather than fail when it is absent, so the
    134 suite is meaningful in a fresh container; anything needing a booted machine
    135 lives in the `unos` repo.