feat(imp): pocket.relocate.<service> directive group #51

Merged
traveler merged 1 commit from gremlin/pocket-relocate-directive into main 2026-07-27 13:27:51 -05:00 AGit
Contributor

Adds imp/pocket-relocate.sh, the Pocket___Relocate n8n workflow, a
Relocate tab on the command bus, and the /relocate nginx proxy route --
modeled directly on the existing gremlin.pocket.dismount.* pattern per
this repo's conventions (pocket.* namespace, checker validation,
imp-actions.json logging, no ntfy, no Gatus).

Sequence: precheck (target reachable, source healthy, DockerVol
identical on both hosts) -> live arch-compat check per image
(docker buildx imagetools inspect vs actual target uname -m, not a
static table) -> deploy on target -> health-check via monitor.url
(5 retries) -> teardown source only once target confirmed healthy.
Deploy-then-verify-then-teardown ordering means a failed relocate at
any step leaves the source running untouched; every step is naturally
idempotent so a re-triggered failed run reconciles rather than
double-acting.

Two deviations from a literal reading of the request, both because the
live architecture doesn't match the assumption behind it:

  • No data-sync step. pocket and grimoire aren't independent storage --
    the SSD mounts on pocket, grimoire NFS-mounts the same /pocket tree
    from it (per Imp-Worker-Map.md). DockerVol/ is already
    identical on both hosts; the script verifies this live and refuses
    to proceed if it doesn't hold, rather than syncing data that's
    already shared.
  • n8n and webhost are hard-denylisted (script + workflow Validate node
    both refuse them) -- relocating either would tear down or move the
    automation running the relocate itself mid-operation, same reasoning
    gremlin.pocket.dismount.stop already uses to exclude them from its
    own stop loop.

NOT live-tested: neither pocket nor grimoire has been reachable since
the fleet went offline 2026-07-10, so this could only be built and
code-reviewed against the existing Pocket_Deploy.json/pocket-deploy.sh
patterns -- same caveat the original dismount.stop/.export carried
before their first real run. Workflow imported with active:false and
an explicit untested warning in its description; bus UI badge reads
"Untested" instead of "Live". Smoke-test on a low-stakes stack first.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1


Part A -- Multi-Arch Audit (inline summary; full table + methodology in Pocket-System-Reference.md)

Checked live via docker buildx imagetools inspect / direct registry query from znas against every image in _deploy-queue/ (no build: contexts exist in this repo -- all 14 stacks pull pre-built images).

Service Multi-arch? Notes
devdocs No (amd64 only) Single manifest, no arm64 tag found
dockhand Yes amd64+arm64
filebrowser Yes amd64+arm64
flame No (amd64 only) Single manifest, no arm64 tag found
imp-worker No (amd64 only) build-push.sh runs plain docker build, no buildx/platform flag -- confirmed in the script. Live registry query confirms single manifest, not a manifest list. This is why imp-worker already runs on grimoire not pocket -- now independently reverified rather than assumed from the docs.
it-tools Yes amd64+arm64
jellyfin Yes amd64+arm64
kiwix Yes amd64+arm64+arm/v7+arm/v6+386
n8n Yes amd64+arm64
nettools Yes amd64+arm64+arm/v7
stash Yes amd64+arm64+arm/v7+arm/v6
vault (kopia) Yes amd64+arm64+arm/v7
webhost (nginx+python) Yes (both) huge platform lists, incl arm64/v8
wikijs (postgres+wiki) Yes (both) amd64+arm64

11/14 confirmed multi-arch, zero-friction. 3/14 (devdocs, flame, imp-worker) are amd64-only and cannot run on pocket (arm64) without a rebuild. All three are low-stakes for this today: devdocs/flame have no persistent state worth relocating urgently, and imp-worker was already designed to live on grimoire for exactly this reason.

Caveat: grimoire'''s architecture (presumed x86_64) was not independently re-verified this session -- the host is unreachable. Treated as x86_64 per the existing Imp-Worker-Map.md finding.

Adds imp/pocket-relocate.sh, the Pocket___Relocate n8n workflow, a Relocate tab on the command bus, and the /relocate nginx proxy route -- modeled directly on the existing gremlin.pocket.dismount.* pattern per this repo's conventions (pocket.* namespace, checker validation, imp-actions.json logging, no ntfy, no Gatus). Sequence: precheck (target reachable, source healthy, DockerVol identical on both hosts) -> live arch-compat check per image (docker buildx imagetools inspect vs actual target uname -m, not a static table) -> deploy on target -> health-check via monitor.url (5 retries) -> teardown source only once target confirmed healthy. Deploy-then-verify-then-teardown ordering means a failed relocate at any step leaves the source running untouched; every step is naturally idempotent so a re-triggered failed run reconciles rather than double-acting. Two deviations from a literal reading of the request, both because the live architecture doesn't match the assumption behind it: - No data-sync step. pocket and grimoire aren't independent storage -- the SSD mounts on pocket, grimoire NFS-mounts the same /pocket tree from it (per Imp-Worker-Map.md). DockerVol/<name> is already identical on both hosts; the script verifies this live and refuses to proceed if it doesn't hold, rather than syncing data that's already shared. - n8n and webhost are hard-denylisted (script + workflow Validate node both refuse them) -- relocating either would tear down or move the automation running the relocate itself mid-operation, same reasoning gremlin.pocket.dismount.stop already uses to exclude them from its own stop loop. NOT live-tested: neither pocket nor grimoire has been reachable since the fleet went offline 2026-07-10, so this could only be built and code-reviewed against the existing Pocket_Deploy.json/pocket-deploy.sh patterns -- same caveat the original dismount.stop/.export carried before their first real run. Workflow imported with active:false and an explicit untested warning in its description; bus UI badge reads "Untested" instead of "Live". Smoke-test on a low-stakes stack first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1 --- ## Part A -- Multi-Arch Audit (inline summary; full table + methodology in Pocket-System-Reference.md) Checked live via `docker buildx imagetools inspect` / direct registry query from znas against every image in `_deploy-queue/` (no build: contexts exist in this repo -- all 14 stacks pull pre-built images). | Service | Multi-arch? | Notes | |---|---|---| | devdocs | **No (amd64 only)** | Single manifest, no arm64 tag found | | dockhand | Yes | amd64+arm64 | | filebrowser | Yes | amd64+arm64 | | flame | **No (amd64 only)** | Single manifest, no arm64 tag found | | **imp-worker** | **No (amd64 only)** | build-push.sh runs plain `docker build`, no buildx/platform flag -- confirmed in the script. Live registry query confirms single manifest, not a manifest list. This is *why* imp-worker already runs on grimoire not pocket -- now independently reverified rather than assumed from the docs. | | it-tools | Yes | amd64+arm64 | | jellyfin | Yes | amd64+arm64 | | kiwix | Yes | amd64+arm64+arm/v7+arm/v6+386 | | n8n | Yes | amd64+arm64 | | nettools | Yes | amd64+arm64+arm/v7 | | stash | Yes | amd64+arm64+arm/v7+arm/v6 | | vault (kopia) | Yes | amd64+arm64+arm/v7 | | webhost (nginx+python) | Yes (both) | huge platform lists, incl arm64/v8 | | wikijs (postgres+wiki) | Yes (both) | amd64+arm64 | **11/14 confirmed multi-arch, zero-friction. 3/14 (devdocs, flame, imp-worker) are amd64-only and cannot run on pocket (arm64) without a rebuild.** All three are low-stakes for this today: devdocs/flame have no persistent state worth relocating urgently, and imp-worker was already designed to live on grimoire for exactly this reason. **Caveat:** grimoire'''s architecture (presumed x86_64) was not independently re-verified this session -- the host is unreachable. Treated as x86_64 per the existing Imp-Worker-Map.md finding.
Adds imp/pocket-relocate.sh, the Pocket___Relocate n8n workflow, a
Relocate tab on the command bus, and the /relocate nginx proxy route --
modeled directly on the existing gremlin.pocket.dismount.* pattern per
this repo's conventions (pocket.* namespace, checker validation,
imp-actions.json logging, no ntfy, no Gatus).

Sequence: precheck (target reachable, source healthy, DockerVol
identical on both hosts) -> live arch-compat check per image
(docker buildx imagetools inspect vs actual target uname -m, not a
static table) -> deploy on target -> health-check via monitor.url
(5 retries) -> teardown source only once target confirmed healthy.
Deploy-then-verify-then-teardown ordering means a failed relocate at
any step leaves the source running untouched; every step is naturally
idempotent so a re-triggered failed run reconciles rather than
double-acting.

Two deviations from a literal reading of the request, both because the
live architecture doesn't match the assumption behind it:
- No data-sync step. pocket and grimoire aren't independent storage --
  the SSD mounts on pocket, grimoire NFS-mounts the same /pocket tree
  from it (per Imp-Worker-Map.md). DockerVol/<name> is already
  identical on both hosts; the script verifies this live and refuses
  to proceed if it doesn't hold, rather than syncing data that's
  already shared.
- n8n and webhost are hard-denylisted (script + workflow Validate node
  both refuse them) -- relocating either would tear down or move the
  automation running the relocate itself mid-operation, same reasoning
  gremlin.pocket.dismount.stop already uses to exclude them from its
  own stop loop.

NOT live-tested: neither pocket nor grimoire has been reachable since
the fleet went offline 2026-07-10, so this could only be built and
code-reviewed against the existing Pocket_Deploy.json/pocket-deploy.sh
patterns -- same caveat the original dismount.stop/.export carried
before their first real run. Workflow imported with active:false and
an explicit untested warning in its description; bus UI badge reads
"Untested" instead of "Live". Smoke-test on a low-stakes stack first.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZCa7HKzyLGzs8qsD3Y5i1
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
traveler/pocket!51
No description provided.