update docs
This commit is contained in:
+88
-98
@@ -1,117 +1,107 @@
|
||||
# Software cartridge format 1
|
||||
# Software cartridge format
|
||||
|
||||
[Build and use a cartridge](workstation.md) · [Original cartridge classes](cartridges.md)
|
||||
A PROGRAM cartridge is a complete GPT disk image with one EROFS metadata partition
|
||||
and one or more EROFS payload partitions. New media uses catalogue format 2 and
|
||||
stores installed Void package trees. Source recipes and build tools remain on
|
||||
the workstation; FDS executes the installed files directly.
|
||||
|
||||
A software cartridge is a complete GPT disk image with **1 + m** partitions,
|
||||
where `m` is 1–32. Partition 1 describes every software package in all payload
|
||||
partitions. All partitions use read-only EROFS. This format is the current
|
||||
PROGRAM creation format; existing single-partition PROGRAM media remain readable.
|
||||
SYSTEM, DATA and ENVIRONMENT layouts retain their existing meanings.
|
||||
|
||||
## Disk and filesystem layout
|
||||
|
||||
```text
|
||||
GPT protective MBR + primary GPT
|
||||
1 FDS_METADATA
|
||||
FDS/CARTRIDGE.TOML
|
||||
FDS/SOFTWARE.TOML
|
||||
2 FDS_PAYLOAD02
|
||||
bundles/demo.hello.tar.xz
|
||||
bundles/demo.editor.tar.xz
|
||||
3 FDS_PAYLOAD03
|
||||
bundles/demo.report.tar.xz
|
||||
...
|
||||
backup GPT
|
||||
```
|
||||
|
||||
Partition entries are consecutive, use Linux filesystem type GUIDs, unique
|
||||
nonzero partition UUIDs, no GPT attributes, and nonoverlapping MiB-aligned
|
||||
extents. Partition 1 starts at LBA 2048. Both GPT copies, their headers and CRCs
|
||||
must agree. A full-drive write to a larger USB device relocates the backup table
|
||||
and header. The existing on-target image parser and the workstation writer
|
||||
share these checks.
|
||||
|
||||
`FDS/CARTRIDGE.TOML` uses the existing format-1 identity with `class = "program"`
|
||||
and `media.writable = false`. It contains no startup command. A sample catalogue:
|
||||
## Software source recipe
|
||||
|
||||
```toml
|
||||
format = 1
|
||||
|
||||
[[software]]
|
||||
id = "demo.hello"
|
||||
name = "AArch64 hello"
|
||||
format = 2
|
||||
id = "example.hello"
|
||||
name = "Hello"
|
||||
version = "1.0"
|
||||
architecture = "aarch64"
|
||||
partition = 2
|
||||
archive_bytes = 2308
|
||||
unpacked_bytes = 70504
|
||||
entries = 2
|
||||
sha256 = "REPLACE_WITH_THE_64_CHARACTER_LOWERCASE_SHA256"
|
||||
[software.commands]
|
||||
hello = "bin/hello"
|
||||
|
||||
[commands]
|
||||
hello = "usr/bin/hello"
|
||||
|
||||
[source]
|
||||
package = "hello"
|
||||
```
|
||||
|
||||
Those lengths and the digest are illustrative. The builder generates actual
|
||||
values. IDs and command names use the existing restricted FDS identifier syntax.
|
||||
IDs are unique per cartridge. Every declared payload partition must contain
|
||||
exactly the catalogue's `bundles/<id>.tar.xz` archive names, and every payload
|
||||
partition must be represented. Multiple software entries may share a partition.
|
||||
The catalogue contains 1–128 software entries and at most 64 KiB of TOML.
|
||||
`package` names a source package in the selected `void-packages` checkout. For a
|
||||
custom package, also set `template = "void"`: that directory must contain a
|
||||
normal Void `template` and any `files/` or `patches/` directories it uses. Paths
|
||||
are relative to this recipe. The [included hello package](../examples/software/hello/void/template)
|
||||
is a complete example.
|
||||
|
||||
## Archive contract
|
||||
Custom sources are copied into an untracked `srcpkgs/PACKAGE` directory. Existing
|
||||
tracked Void sources are never overwritten. If a generated source copy differs,
|
||||
inspect it, preserve any independent edits, then remove that generated copy and
|
||||
retry. An unchanged copy can be reused.
|
||||
|
||||
Bundles are deterministic USTAR archives compressed with single-threaded xz.
|
||||
Entries are sorted, timestamps/UID/GID are zero, and permissions normalize to
|
||||
0755 for directories/executables or 0644 for ordinary data. Host source symlinks
|
||||
to regular files inside the root are flattened into regular files. Directory or
|
||||
escaping symlinks are rejected; the archive itself never contains links.
|
||||
`fds-cartridge` builds with `xbps-src -a aarch64`, installs the resulting package
|
||||
and runtime dependencies into a fresh tree, and records installed XBPS versions.
|
||||
Use package dependency declarations to request runtime libraries and utilities.
|
||||
Each software tree is self-contained with respect to its installed dependencies;
|
||||
there is no cross-cartridge package resolver.
|
||||
|
||||
The reader rejects:
|
||||
Software IDs and public command names use lowercase ASCII letters, digits,
|
||||
periods, hyphens and underscores, with a maximum length of 64. Command paths are
|
||||
relative to the installed root and must resolve to executable files within it.
|
||||
|
||||
- Absolute, parent-traversing, repeated-separator, non-UTF-8 or control-character paths.
|
||||
- Duplicate entries, file-as-parent conflicts, links, devices, sockets, FIFOs,
|
||||
privileged permissions, and GNU/PAX extension entries.
|
||||
- Incorrect SHA-256, compressed length, unpacked length, entry count, or command
|
||||
paths that do not name executable regular files.
|
||||
- ELF files that are not little-endian 64-bit AArch64, or any ELF in a bundle
|
||||
declared `architecture = "any"`.
|
||||
- Invalid xz data, nonzero material after the tar end marker, and resource-limit
|
||||
violations. Each archive is at most 512 MiB compressed, 1 GiB unpacked and
|
||||
65,536 entries. Xz decompression has a 256 MiB memory limit.
|
||||
## Cartridge recipe
|
||||
|
||||
A source path must fit USTAR's path fields. Packaging reports paths that cannot
|
||||
be represented rather than emitting an unsupported extension header.
|
||||
```toml
|
||||
format = 2
|
||||
id = "example.tools"
|
||||
name = "Example tools"
|
||||
version = "1.0"
|
||||
|
||||
## Guest lifecycle
|
||||
[[payload]]
|
||||
sources = ["hello/software.toml", "report/software.toml"]
|
||||
```
|
||||
|
||||
On insertion the daemon validates the complete GPT against kernel partition
|
||||
geometry and the current USB disk identity. It reads metadata without following
|
||||
symlinks, mounts every payload read-only/noexec/nosuid/nodev, and checks the
|
||||
archive inventory and lengths. `fds bay BAY` reports the full catalogue;
|
||||
`fds bays` stays compact. No archive command runs automatically on insertion.
|
||||
Each payload section creates one partition. Sources may be recipe paths or
|
||||
previously built directories containing `software.toml` and `root/`. The metadata
|
||||
partition records which software belongs to which partition. Software IDs and
|
||||
cartridge identity must satisfy the metadata validation rules.
|
||||
|
||||
`fds run BAY -- SOFTWARE-ID:COMMAND [ARGUMENT...]` verifies and extracts that
|
||||
package on first use. It creates a private temporary filesystem, applies the
|
||||
archive contract, then makes the finished tree read-only and accessible for
|
||||
execution. The runtime cache has a stricter **256 MiB per software tree** limit,
|
||||
including reserved inode overhead; a host-valid larger bundle may therefore
|
||||
need splitting before running. Caches live under `/run/fds/software/<bay>/` and
|
||||
vanish after eject, unplug, restart cleanup, or shutdown.
|
||||
## On-disk contents
|
||||
|
||||
Managed consumers run as UID/GID 1000 with no new privileges in the bay's cgroup.
|
||||
`FDS_APP`, `PATH`, `LD_LIBRARY_PATH` and `XDG_DATA_DIRS` point to that software
|
||||
root. DISPLAY/XAUTHORITY retain the established optional desktop integration.
|
||||
The xz utility is already an explicit dependency of the mandatory `fds-base`
|
||||
package; runtime extraction adds no target package.
|
||||
```text
|
||||
Partition 1: FDS_METADATA
|
||||
FDS/CARTRIDGE.TOML
|
||||
FDS/SOFTWARE.TOML
|
||||
Partition 2: FDS_PAYLOAD02
|
||||
programs/example.hello/usr/bin/hello
|
||||
programs/example.hello/usr/lib/...
|
||||
programs/example.hello/var/db/xbps/...
|
||||
programs/example.report/...
|
||||
```
|
||||
|
||||
Build recipes, compilers, installation hooks and privileged archive scripts are
|
||||
never part of this runtime path.
|
||||
The software catalogue records identity, architecture, commands, partition,
|
||||
installed package versions, entry count, byte count and SHA-256. `installed=true`
|
||||
selects the direct-tree contract. The retained `unpacked_bytes` field records
|
||||
installed file bytes; it does not imply an archive or guest extraction.
|
||||
|
||||
Safe eject stops consumers, rejects unexpected mount aliases, unmounts caches,
|
||||
payloads and metadata, then reports SAFE. Confirmed surprise removal permits
|
||||
lazy detachment after stopping consumers. Service restart removes stale mounts
|
||||
before rescanning. SYSTEM stays immutable throughout.
|
||||
The tree digest covers sorted paths, entry types, modes, contents and symlink
|
||||
targets. Root-relative package symlinks are relocated to relative in-tree links
|
||||
when building. Escaping links, special files, privileged/writeable executable
|
||||
trees, wrong-architecture ELF files and inconsistent metadata are rejected.
|
||||
Current per-tree bounds are 1 GiB of file data and 65,536 entries.
|
||||
|
||||
SHA-256 detects corruption and binds an archive to its catalogue; it does not
|
||||
establish a publisher's identity. Only run software you trust. Release signature
|
||||
verification remains the separate [release workflow](releases.md).
|
||||
## Runtime behavior
|
||||
|
||||
FDS verifies the cartridge's geometry, identity, inventory and tree integrity
|
||||
on insertion. Payloads are mounted read-only with `nosuid,nodev`. No software
|
||||
command runs automatically. Published command aliases appear in `/run/fds/bin`.
|
||||
|
||||
Programs run as UID/GID 1000 in the bay's managed process group. `FDS_APP` names
|
||||
the installed tree; PATH, library paths and data search paths include its
|
||||
`usr/bin`, `usr/lib` and `usr/share`. Dynamically linked ELF entry points use the
|
||||
package tree's own loader. Programs that hard-code unrelated system paths still
|
||||
need to be compatible with FDS; the tree is not a container or a writable root.
|
||||
|
||||
Safe eject stops consumers and releases every payload before reporting SAFE.
|
||||
A digest detects corruption, not publisher identity: choose software sources
|
||||
you trust. Distribution signatures are covered by [release verification](releases.md).
|
||||
|
||||
## Older media
|
||||
|
||||
The reader retains support for catalogue format 1 with xz payloads and legacy
|
||||
single-partition PROGRAM cartridges containing `app/`. Old xz payloads retain
|
||||
their temporary extraction behavior and limits. Creation commands produce only
|
||||
the installed-tree format. Rebuild old software from its Void source recipe to
|
||||
use direct execution.
|
||||
|
||||
Reference in New Issue
Block a user