mount now detects already-unlocked and already-mounted devices, returning the existing mount point instead of failing. unmount handles already-locked devices gracefully and skips unmount if not mounted before locking. Adds IsMounted helper to udisks client. Updates PLAN.md with refined v1.0.0 milestones. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.4 KiB
arca — v1.0.0 Plan
Current State (v0.1.0)
Working proof of concept. FIDO2 unlock via cryptsetup with passphrase fallback, privileged mount/unmount, config aliases with method sequencing, init and status commands.
M1: Idempotent mount/unmount
mount and unmount should be safe to run at any point in a device's
lifecycle without producing confusing errors.
Files changed
cmd/mount.gocmd/unmount.gointernal/udisks/client.go
Work
-
In
runMount, afterFindDevice, check if the device is already unlocked (CleartextDevicesucceeds). If the cleartext device is already mounted, print the existing mount point and return success. If unlocked but not mounted, skip unlock and go straight to mount. -
In
runUnmount, handle each failure case:CleartextDevicefails (already locked): print "already locked" and return success.Unmountfails because not mounted: proceed to lock anyway.Lockfails because already locked: return success.
-
Add
client.IsMounted(dev)helper that returns(mountpoint, bool)to reduce duplicated mount-point checking logic.
M2: Error messages
Replace generic D-Bus errors with actionable messages.
Files changed
internal/udisks/client.gocmd/mount.go,cmd/unmount.go,cmd/init.go,cmd/status.go
Work
-
Wrap the
dbus.SystemBus()error inNewClientto detect "connection refused" or "no such file" and print:"cannot connect to udisks2 — is the udisks2 service running?" -
In
FindDevice, when no device matches, include what was searched and suggestarca statusorarca init:"device /dev/sda1 not found (run 'arca status' to list devices)" -
In the unlock sequencer, prefix each method error with context:
"fido2: cryptsetup open --token-only: exit status 5 (is the FIDO2 key plugged in?)"
M3: Unit tests
Cover pure logic that doesn't need D-Bus or real devices.
Files changed
internal/config/config_test.go(new)internal/cryptsetup/cryptsetup_test.go(new)
Work
-
config_test.go — test cases:
ResolveDevicewith exact alias matchResolveDevicewith device path match (/dev/sda1->sda1)ResolveDevicewith unknown name returns default methodsResolveDevicewith empty methods list defaults to[passphrase]AliasForfinds alias by UUIDAliasForreturns "" for unknown UUIDLoadwith nonexistent file returns empty configLoadwith valid YAML parses correctly
-
cryptsetup_test.go — test cases:
MapperName("/dev/sda1")=="arca-sda1"MapperName("/dev/nvme0n1p2")=="arca-nvme0n1p2"hasTokenPluginswith a temp dir containing a matching .sohasTokenPluginswith an empty temp dir
M4: CLI polish
Small usability improvements.
Files changed
cmd/root.gocmd/mount.gocmd/init.gomain.go.gitignore(new)
Work
-
Add
var version = "dev"tomain.go. SetrootCmd.Versionincmd/root.go. Build with-ldflags "-X main.version=..."inflake.nix. -
Add
--mountpoint/-mflag tomountsubcommand. When set, pass it tocryptsetup.Mount(privileged path) or log a warning that udisks2 doesn't support custom mount points. -
In
init, use first 8 chars of UUID as alias instead of device path basename. Example:b8b2f8e3instead ofsda1. UUIDs are stable across boots; device paths are not. -
Create
.gitignorecontaining/arca.
M5: Documentation and packaging
Make the project installable and the README trustworthy.
Files changed
README.mdflake.nix
Work
-
Update
README.md:- Replace placeholder UUIDs with realistic examples from actual tested usage.
- Add "NixOS notes" section documenting the
LD_LIBRARY_PATHrequirement for FIDO2/TPM2 and why--external-tokens-pathdoesn't work. - Add "Troubleshooting" section: no FIDO2 token enrolled, udisks2 not running, permission denied on mount.
- Document
initsubcommand.
-
Verify
flake.nix:- Run
nix buildand confirm it produces a working binary. - Add
-ldflagsfor version injection fromself.revor aversionvariable. - Test the flake output:
./result/bin/arca --version.
- Run
-
Tag
v1.0.0.
Non-goals for v1.0.0
--dry-runflag--jsonoutput forstatus- udev auto-mount on plug
- Keyfile creation/management
- Multiple config files or config includes