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)
|
||||
|
||||
Reference in new issue
Block a user