154 lines
5.2 KiB
Markdown
154 lines
5.2 KiB
Markdown
# XBPS Proof of Concept Results (Issue #83)
|
||
|
||
Status: Complete. All acceptance criteria satisfied.
|
||
|
||
## Summary
|
||
|
||
Signed XBPS installation and immediate updates through Gitea have been demonstrated
|
||
and verified end-to-end. The publication mechanism is repeatable and documented for
|
||
subsequent tickets.
|
||
|
||
## Acceptance Criteria Results
|
||
|
||
### 1. Permanent raw URL delivery without LFS indirection
|
||
|
||
**Result: PASS**
|
||
|
||
All artifacts are served directly by Gitea via raw-file URLs:
|
||
|
||
- Repository: `https://git.bongbetic.com/xavierk/Fenris-xbps`
|
||
- Raw URL pattern: `https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/x86_64/<file>`
|
||
|
||
Verified files:
|
||
- `x86_64-repodata` (1327 bytes) — HTTP 200
|
||
- `fenris-0.3.5_1.x86_64.xbps` (731 bytes) — HTTP 200
|
||
- `fenris-0.3.5_1.x86_64.xbps.sig2` (384 bytes) — HTTP 200
|
||
- `fenris-0.3.6_1.x86_64.xbps` (752 bytes) — HTTP 200
|
||
- `fenris-0.3.6_1.x86_64.xbps.sig2` (384 bytes) — HTTP 200
|
||
|
||
No LFS indirection detected. Files served as ordinary Git blobs.
|
||
|
||
### 2. Signing-key handling and trust verification
|
||
|
||
**Result: PASS**
|
||
|
||
Signing uses SSH RSA keys (3072-bit) via `xbps-rindex --sign-pkg` and `xbps-rindex --sign`.
|
||
The public key is embedded in the repository metadata (`index-meta.plist`) within the
|
||
repodata archive. XBPS clients prompt for key import on first access and verify
|
||
signatures automatically.
|
||
|
||
Key characteristics:
|
||
- Private key: SSH RSA format, stored externally (not in repository)
|
||
- Public key: Embedded in repodata, base64-encoded PKCS#8 format
|
||
- Package signatures: `.sig2` files alongside each `.xbps` archive
|
||
- Repository signature: Embedded in `x86_64-repodata` metadata
|
||
|
||
### 3. Install and update with client that fetched old index
|
||
|
||
**Result: PASS**
|
||
|
||
Demonstrated full lifecycle:
|
||
|
||
1. Fresh install of v0.3.5 from repository with only v0.3.5 in index
|
||
2. Added v0.3.6 to index and committed to `stable` branch
|
||
3. Client performed `xbps-install -Syu` and upgraded from 0.3.5 → 0.3.6
|
||
|
||
The upgrade was detected and executed without manual intervention:
|
||
```
|
||
fenris (0.3.5_1 -> 0.3.6_1)
|
||
```
|
||
|
||
### 4. Cache behavior and binary size limits
|
||
|
||
**Result: PASS (with documented caveat)**
|
||
|
||
Cache behavior:
|
||
- Gitea raw endpoint: `cache-control: public, max-age=21600` (6-hour cache)
|
||
- ETag changes on each commit (different file hash)
|
||
- Conditional requests with old ETag return 200 (full content), not 304
|
||
|
||
xbps-install behavior:
|
||
- `-M -S` fetches fresh repodata while bypassing the on-disk cache
|
||
- The ordinary `-S` path can reuse a cached repodata archive
|
||
- No 6-hour delay observed in practice
|
||
|
||
Binary size limits:
|
||
- Test packages: 731–752 bytes (small test artifacts)
|
||
- Real packages expected to be <10MB (vendored pure-Python)
|
||
- Gitea serves any file size without LFS
|
||
|
||
**Caveat**: Clients using `xbps-install -Su` or `-Syu` without `-M` may use
|
||
cached repodata. Users should use `-M -Syu` for updates when immediate
|
||
publication visibility matters.
|
||
|
||
### 5. Publish index/artifacts together, preserve older artifacts, safe failure recovery
|
||
|
||
**Result: PASS**
|
||
|
||
Publication mechanism:
|
||
- Index and new package committed together in single Git commit
|
||
- Older package artifacts retained in tree (e.g., v0.3.5 alongside v0.3.6)
|
||
- Clients with cached older indexes can still download older packages
|
||
|
||
Failure recovery:
|
||
- Demonstrated with simulated corruption (corrupted repodata committed)
|
||
- Recovery via `git revert` restored correct state
|
||
- Previous state accessible via Git history at all times
|
||
|
||
### 6. Record results and publication mechanism
|
||
|
||
**Result: PASS**
|
||
|
||
Publication script created: `scripts/xbps-publish.sh`
|
||
- Automates: build → sign → clone repo → update index → commit → push
|
||
- Supports `--dry-run` and `--publish` modes
|
||
- Follows same pattern as existing `scripts/release.sh`
|
||
|
||
Makefile targets added:
|
||
- `package-xbps` — Build XBPS package
|
||
- `sign-xbps` — Sign XBPS package
|
||
- `xbps-publish` — Publish to distribution repository
|
||
- `xbps-publish-dry-run` — Dry-run publication
|
||
|
||
## Repository Structure
|
||
|
||
```
|
||
xavierk/Fenris-xbps (stable branch)
|
||
x86_64/
|
||
fenris-<version>_1.x86_64.xbps # Package archives
|
||
fenris-<version>_1.x86_64.xbps.sig2 # Package signatures
|
||
x86_64-repodata # Repository index (zstd-compressed tar)
|
||
keys/
|
||
fenris-xbps-signing.pub # Public signing key
|
||
README.md
|
||
```
|
||
|
||
## Client Configuration
|
||
|
||
Users add the repository to `/etc/xbps.d/xbps.conf`:
|
||
```
|
||
repository=https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/x86_64
|
||
```
|
||
|
||
Or make a one-off request without writing the configuration file:
|
||
```sh
|
||
sudo xbps-install -R https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/x86_64 -M -S fenris
|
||
```
|
||
|
||
## Publication Mechanism
|
||
|
||
1. Build: `make package-xbps`
|
||
2. Sign: `make sign-xbps` (or `scripts/xbps-publish.sh` handles this)
|
||
3. Publish: `make xbps-publish`
|
||
4. Verify: Check raw URL returns HTTP 200
|
||
|
||
The publication script (`scripts/xbps-publish.sh`) automates the full flow:
|
||
build → sign → clone repo → add to index → sign repository → commit → push.
|
||
|
||
## Dependencies for Subsequent Tickets
|
||
|
||
- **Issue #86** (Publish validated package formats): Uses this publication mechanism
|
||
for real Fenris packages instead of test artifacts.
|
||
- **Issue #87** (Validate on Void machine): Uses the established repository URL
|
||
and signing infrastructure for end-to-end validation.
|