Atreides Services 0.0.3: datamap verplaatsbaar naar USB (umbrelOS 2.0)
storage: dataRoot: data in het manifest, zodat de gebruiker de datamap in de app-instellingen naar een USB-schijf met ext4 kan verplaatsen. Geen netwerkshare: umbrelOS weigert dat voor app-opslag, en de SQLite-bestanden in WAL-stand horen er ook niet op. test_appstore_vorm.py kent de nieuwe veldvolgorde (storage, folderAccess en environment direct na id) en toetst dat storage precies dataRoot: data is en dat de mounts onder data/ door umbreld om te leiden zijn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
103f8c456a
commit
26e36de417
3 files changed
+81
-4
No files matched your search
@@ -44,8 +44,12 @@ STORE = os.path.join(REPO, "umbrel-app-store.yml")
|
||||
|
||||
# De volgorde uit de packaging-documentatie. Wat de spec niet noemt (icon,
|
||||
# backupIgnore, submitter, submission) mag erachter, niet ertussen.
|
||||
#
|
||||
# `storage`, `folderAccess` en `environment` zijn er sinds umbrelOS 2.0 bij en
|
||||
# staan direct na `id` (skill umbrel-package-app, opgehaald 09-10-2026).
|
||||
VOORGESCHREVEN = [
|
||||
"manifestVersion", "id", "category", "name", "version", "tagline",
|
||||
"manifestVersion", "id", "storage", "folderAccess", "environment",
|
||||
"category", "name", "version", "tagline",
|
||||
"description", "releaseNotes", "developer", "website", "dependencies",
|
||||
"repo", "support", "port", "gallery", "path",
|
||||
]
|
||||
@@ -327,6 +331,63 @@ def test_data_onder_data(u, app):
|
||||
not ontbreekt, "ontbreekt: %r" % ontbreekt)
|
||||
|
||||
|
||||
# De mount-opties die umbreld toestaat op een bron onder ${APP_DATA_DIR}/data
|
||||
# zodra de datamap verplaatsbaar is. Elke andere optie laat de compose falen met
|
||||
# [apps-data-root-invalid-compose]. Uit app.ts van umbreld, 09-10-2026.
|
||||
DATAROOT_OPTIES = {
|
||||
"ro", "rw", "private", "rprivate", "shared", "rshared", "slave", "rslave",
|
||||
"z", "Z", "consistent", "cached", "delegated",
|
||||
}
|
||||
|
||||
|
||||
def test_verplaatsbare_opslag(u, app):
|
||||
"""Een app met `storage:` heeft precies `dataRoot: data`, en mounts die umbreld kan omleiden.
|
||||
|
||||
Dit is het enige manifestveld dat umbreld wél streng valideert: elke andere
|
||||
waarde dan `data` maakt het manifest ongeldig, en dan verschijnt de app niet.
|
||||
Met het veld erin herschrijft umbreld elke bron onder ${APP_DATA_DIR}/data naar
|
||||
de plek die de gebruiker kiest, en weigert dan een pad dat uit data/ ontsnapt
|
||||
of een mount-optie die niet in DATAROOT_OPTIES staat.
|
||||
|
||||
Een app zonder `storage:` valt hier buiten; het veld is optioneel. Maar het
|
||||
kan er niet meer uit als het er eenmaal in staat: een installatie die al
|
||||
verplaatst is, start dan niet meer.
|
||||
"""
|
||||
tekst = lees(os.path.join(REPO, app, "umbrel-app.yml"))
|
||||
regels = tekst.splitlines()
|
||||
if not any(r.startswith("storage:") for r in regels):
|
||||
return
|
||||
|
||||
i = next(i for i, r in enumerate(regels) if r.startswith("storage:"))
|
||||
blok = []
|
||||
for r in regels[i + 1:]:
|
||||
if r and not r[0].isspace():
|
||||
break
|
||||
if r.strip() and not r.strip().startswith("#"):
|
||||
blok.append(r.strip())
|
||||
u.check("%s: storage heeft precies dataRoot: data" % app,
|
||||
blok == ["dataRoot: data"], "gevonden: %r" % blok)
|
||||
|
||||
pad = os.path.join(REPO, app, "docker-compose.yml")
|
||||
if not os.path.isfile(pad):
|
||||
return
|
||||
fout = []
|
||||
for regel in lees(pad).splitlines():
|
||||
kaal = regel.strip()
|
||||
if not kaal.startswith("- ${APP_DATA_DIR}/data"):
|
||||
continue
|
||||
delen = kaal[2:].strip().strip('"').split(":")
|
||||
bron = delen[0][len("${APP_DATA_DIR}/"):]
|
||||
if ".." in bron.split("/"):
|
||||
fout.append(kaal)
|
||||
if len(delen) > 2:
|
||||
opties = delen[2].split(",")
|
||||
if any(o not in DATAROOT_OPTIES for o in opties):
|
||||
fout.append(kaal)
|
||||
u.check("%s: elke mount onder data/ kan umbreld omleiden" % app,
|
||||
not fout, "geweigerd: %r" % fout)
|
||||
|
||||
|
||||
def test_containernamen_zijn_volledig(u, app):
|
||||
"""Verwijzingen tussen containers gebruiken de volledige naam.
|
||||
|
||||
@@ -534,6 +595,7 @@ def main():
|
||||
test_compose_bestaat_en_hangt_samen(u, app)
|
||||
test_image_tag_is_de_gebouwde(u, app)
|
||||
test_data_onder_data(u, app)
|
||||
test_verplaatsbare_opslag(u, app)
|
||||
test_containernamen_zijn_volledig(u, app)
|
||||
test_geen_werkbestanden_in_de_app_map(u, app)
|
||||
test_templates_hebben_geen_losse_dollars(u, app)
|
||||
|
||||
@@ -57,4 +57,10 @@ services:
|
||||
# De datamap: db.sqlite, de minuutbestanden per maand en secrets.json. Een
|
||||
# koersreeks per moment is niet opnieuw op te halen, dus dit is de map die
|
||||
# in de back-up van umbrelOS hoort.
|
||||
#
|
||||
# Sinds `storage: dataRoot: data` in het manifest (0.0.3) herschrijft
|
||||
# umbrelOS 2.0 deze bron naar de plek die de gebruiker kiest, en zet hij
|
||||
# er `create_host_path: false` bij. Daarom moet data/app in de repo staan
|
||||
# (.gitkeep), en mag hier geen mount-optie bij die umbreld niet kent.
|
||||
# Staat de map op een USB-schijf, dan gaat hij NIET mee in de back-up.
|
||||
- ${APP_DATA_DIR}/data/app:/data
|
||||
@@ -6,9 +6,17 @@
|
||||
# Wat de spec niet noemt, staat onderaan dit bestand en niet ertussen.
|
||||
manifestVersion: 1
|
||||
id: whatsnext-atreides-services
|
||||
# umbrelOS 2.0: de gebruiker kan de hele datamap (${APP_DATA_DIR}/data) in de
|
||||
# app-instellingen naar een USB-schijf verplaatsen. Alleen ext4 en geen
|
||||
# netwerkshare; die laatste weigert umbrelOS voor app-opslag, en de SQLite-
|
||||
# bestanden in WAL-stand horen er ook niet op. De waarde moet letterlijk `data`
|
||||
# zijn, en het veld kan er niet meer uit: een installatie die al verplaatst is,
|
||||
# start dan niet meer. Zie Umbrel-appstore-spec.md §7.
|
||||
storage:
|
||||
dataRoot: data
|
||||
category: finance
|
||||
name: Atreides Services
|
||||
version: "0.0.2"
|
||||
version: "0.0.3"
|
||||
tagline: Your own price feed, recorded around the clock
|
||||
description: >-
|
||||
A price service that runs on your Umbrel and keeps what it records. It fetches prices day
|
||||
@@ -26,8 +34,9 @@ description: >-
|
||||
mempool.space, and brings the administration app with its System page and an optional
|
||||
login of its own. The API for other apps follows in a later version.
|
||||
releaseNotes: >-
|
||||
First version in this store: spot prices every minute from Bitvavo and mempool.space, and
|
||||
the administration app. The API for other apps is not there yet.
|
||||
On umbrelOS 2.0 the app's storage can now be moved to a USB drive (ext4) in the app
|
||||
settings. Keep in mind that umbrelOS does not back up an app whose storage is on a USB
|
||||
drive.
|
||||
developer: "WhatsNext?"
|
||||
website: https://sc.kamenier-hamer.nl/sysop/UmbrelApps
|
||||
dependencies: []
|
||||
|
||||
Reference in new issue
Block a user