feat(furtka): ship resource manager + fileshare app on the ISO — slice 3
Closes the loop end-to-end. The ISO build now bundles the furtka/
package and the apps/ tree as a tarball; webinstaller hands it to
archinstall via custom_commands; the installed system gets the
`furtka` CLI, a boot-scan systemd unit, and the fileshare app
ready to install.
- iso/build.sh: stages furtka/ + apps/ into a tmpdir, drops
__pycache__, tarballs into airootfs/opt/furtka-resource-manager.tar.gz.
- webinstaller/app.py: _resource_manager_commands() reads the staged
payload at request-time, base64-encodes it into a single untar
command, and writes /usr/local/bin/furtka (PYTHONPATH wrapper, no
pip needed) + furtka-reconcile.service. Python pacstrapped so the
wrapper has an interpreter.
- Graceful degradation: dev box / CI without an ISO build has no
payload tarball, so those commands are skipped (logs a warning).
Tests cover both branches.
- furtka-reconcile.service is conditionally enabled only if the unit
file actually landed — keeps the systemctl enable line green when
the payload was absent.
- apps/fileshare/: first real Furtka app. dperson/samba on host
network, single named volume, .env.example with placeholder creds.
Manifest matches the schema locked in slice 1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:06:01 +02:00
|
|
|
# Furtka fileshare — SMB share via dperson/samba.
|
|
|
|
|
#
|
|
|
|
|
# The volume `furtka_fileshare_files` is created by the Furtka reconciler
|
|
|
|
|
# from the manifest's "volumes" list before this compose file is brought up;
|
|
|
|
|
# it's referenced as `external: true` here so docker compose doesn't try
|
|
|
|
|
# to manage its lifecycle.
|
2026-04-15 10:17:00 +02:00
|
|
|
#
|
|
|
|
|
# TODO(image-pin): `:latest` is shaky for production — pin to a digest
|
|
|
|
|
# (`dperson/samba@sha256:...`) or a stable tag once we've verified one
|
|
|
|
|
# against the upstream registry. For the MVP run we accept the drift
|
|
|
|
|
# risk to keep the install reproducible against whatever the upstream
|
|
|
|
|
# image happens to be on test day; revisit before any non-developer
|
|
|
|
|
# touches this.
|
feat(furtka): ship resource manager + fileshare app on the ISO — slice 3
Closes the loop end-to-end. The ISO build now bundles the furtka/
package and the apps/ tree as a tarball; webinstaller hands it to
archinstall via custom_commands; the installed system gets the
`furtka` CLI, a boot-scan systemd unit, and the fileshare app
ready to install.
- iso/build.sh: stages furtka/ + apps/ into a tmpdir, drops
__pycache__, tarballs into airootfs/opt/furtka-resource-manager.tar.gz.
- webinstaller/app.py: _resource_manager_commands() reads the staged
payload at request-time, base64-encodes it into a single untar
command, and writes /usr/local/bin/furtka (PYTHONPATH wrapper, no
pip needed) + furtka-reconcile.service. Python pacstrapped so the
wrapper has an interpreter.
- Graceful degradation: dev box / CI without an ISO build has no
payload tarball, so those commands are skipped (logs a warning).
Tests cover both branches.
- furtka-reconcile.service is conditionally enabled only if the unit
file actually landed — keeps the systemctl enable line green when
the payload was absent.
- apps/fileshare/: first real Furtka app. dperson/samba on host
network, single named volume, .env.example with placeholder creds.
Manifest matches the schema locked in slice 1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:06:01 +02:00
|
|
|
|
|
|
|
|
services:
|
|
|
|
|
smbd:
|
|
|
|
|
image: dperson/samba:latest
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
network_mode: host
|
|
|
|
|
environment:
|
|
|
|
|
- USERID=1000
|
|
|
|
|
- GROUPID=1000
|
|
|
|
|
- TZ=Europe/Berlin
|
|
|
|
|
command: >
|
|
|
|
|
-u "${SMB_USER};${SMB_PASSWORD}"
|
|
|
|
|
-s "files;/mount;yes;no;no;${SMB_USER}"
|
|
|
|
|
-p
|
|
|
|
|
volumes:
|
|
|
|
|
- furtka_fileshare_files:/mount
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
furtka_fileshare_files:
|
|
|
|
|
external: true
|