Justfile
Rama main · réplica de lectura del repositorio original.
# tcfs project Justfile
# Run `just --list` to see all recipes
# cargo is expected to come from the pinned rust-toolchain or Nix devShell.
set shell := ["bash", "-euo", "pipefail", "-c"]
# Default: list recipes
default:
@just --list
# ── Infrastructure ──────────────────────────────────────────────────────────
# Initialize OpenTofu for an environment (defaults to current on-prem)
tofu-init env="onprem":
cd infra/tofu/environments/{{env}} && tofu init
# Plan OpenTofu changes
tofu-plan env="onprem":
cd infra/tofu/environments/{{env}} && tofu plan
# Apply OpenTofu changes (requires explicit env)
tofu-apply env="":
@test -n "{{env}}" || (echo "pass env=onprem, env=local, or env=civo explicitly" >&2; exit 2)
cd infra/tofu/environments/{{env}} && tofu apply
# Validate OpenTofu configuration
tofu-validate env="onprem":
cd infra/tofu/environments/{{env}} && tofu validate
# ── Kubernetes ──────────────────────────────────────────────────────────────
# Show pod and service status
k8s-status ns="tcfs":
kubectl get pods -n {{ns}}
@echo "---"
kubectl get svc -n {{ns}}
# Read-only on-prem authority/mobility check for tcfs
onprem-preflight:
bash scripts/tcfs-onprem-preflight.sh
# Regression test the read-only on-prem authority/mobility check
onprem-preflight-test:
bash scripts/test-tcfs-onprem-preflight.sh
# Read-only on-prem data inventory for NATS and SeaweedFS migration planning
onprem-data-inventory:
bash scripts/tcfs-onprem-data-inventory.sh
# Render non-mutating downtime migration facts, import Pods, or copy commands
onprem-migration-plan *ARGS:
bash scripts/tcfs-onprem-migration-plan.sh {{ARGS}}
# Render the non-mutating downtime cutover packet after window/owners are named
onprem-cutover-packet:
bash scripts/tcfs-onprem-cutover-packet.sh
# Regression test the non-mutating TCFS cutover packet renderer
onprem-cutover-packet-test:
bash scripts/test-tcfs-onprem-cutover-packet.sh
# Regression test the non-mutating TCFS migration command renderer
onprem-migration-plan-test:
bash scripts/test-tcfs-onprem-migration-plan.sh
# Validate on-prem OpenTofu migration surfaces without applying live changes
onprem-tofu-validate:
bash scripts/tcfs-onprem-tofu-validate.sh
# Static safety checks for source-owned on-prem candidate workload selectors
onprem-tofu-candidate-test:
bash scripts/test-tcfs-onprem-tofu-candidate-workloads.sh
# Regression test the TIN-5136 honey pause: chart replicas 0, no revival commands or retired manifests
tcfs-backend-paused-test:
bash scripts/test-tcfs-backend-paused-replicas.sh
# Tail logs from a workload
k8s-logs app="tcfsd" ns="tcfs":
kubectl logs -l app.kubernetes.io/name={{app}} -n {{ns}} --tail=50
# Describe a pod (for debugging)
k8s-describe app="tcfsd" ns="tcfs":
kubectl describe pods -l app.kubernetes.io/name={{app}} -n {{ns}}
# ── DNS ────────────────────────────────────────────────────────────────────
# Show current legacy/standby Civo DNS records for tummycrypt.dev
dns-status:
@echo "NATS Tailscale IP:"
@kubectl get svc nats-tailscale -n tcfs -o jsonpath='{.status.loadBalancer.ingress[?(@.ip)].ip}'
@echo ""
@echo "DNS record:"
@dig +short nats.tcfs.tummycrypt.dev
# Fresh cluster (no CRDs installed yet):
# just deploy-fresh # Installs operators without CRD consumers
# just deploy # Second run creates ServiceMonitors + ScaledObject
# Import existing DNS record first if needed:
# cd infra/tofu/environments/civo && tofu import 'module.nats_dns[0].porkbun_dns_record.this' 'tummycrypt.dev:RECORD_ID'
# Full deploy: infra + DNS (legacy civo-era helper; requires explicit env)
deploy env="":
@test -n "{{env}}" || (echo "pass env=onprem, env=local, or env=civo explicitly" >&2; exit 2)
cd infra/tofu/environments/{{env}} && tofu apply
# First-apply on fresh cluster: skip CRD consumers (ServiceMonitor, ScaledObject)
deploy-fresh env="":
@test -n "{{env}}" || (echo "pass env=onprem, env=local, or env=civo explicitly" >&2; exit 2)
cd infra/tofu/environments/{{env}} && tofu apply -var='enable_crds=false'
# ── NATS ────────────────────────────────────────────────────────────────────
# Check legacy/standby Civo NATS server info via Tailscale
nats-status server="nats://nats.tcfs.tummycrypt.dev:4222":
nats server info --server {{server}}
# List legacy/standby Civo JetStream streams
nats-streams server="nats://nats.tcfs.tummycrypt.dev:4222":
nats stream ls --server {{server}}
# Publish a test ping to verify connectivity
nats-ping server="nats://nats.tcfs.tummycrypt.dev:4222":
@echo "Pinging NATS via Tailscale..."
nats pub STATE.ping '{"from":"operator","ts":"'$(date -Iseconds)'"}' --server {{server}}
# ── Fleet ───────────────────────────────────────────────────────────────────
# Check fleet NATS connectivity from this machine
fleet-check:
@echo "Checking fleet NATS connectivity..."
nats server info --server nats://nats.tcfs.tummycrypt.dev:4222
# Installed-runtime filesystem acceptance. Add --execute in ARGS to apply the
# exact printed plan and require a converged second plan.
installed-runtime-acceptance platform tcfs_bin root *ARGS:
bash scripts/installed-runtime-acceptance.sh --platform {{platform}} --tcfs-bin {{tcfs_bin}} --root {{root}} {{ARGS}}
installed-runtime-acceptance-test:
bash scripts/test-installed-runtime-acceptance.sh
# Read-only alpha productionization gate classifier
alpha-gate-preflight *ARGS:
@bash scripts/tcfs-alpha-gate-preflight.sh {{ARGS}}
# Regression test the alpha productionization gate classifier
alpha-gate-preflight-test:
@bash scripts/test-tcfs-alpha-gate-preflight.sh
# Static regression test for the Linux package post-install smoke workflow
linux-postinstall-workflow-test:
@bash scripts/test-linux-postinstall-workflow.sh
# Static regression test for the Linux package container smoke workflow
linux-package-container-workflow-test:
@bash scripts/test-linux-package-container-smoke-workflow.sh
# Static regression test for the storage large restore canary workflow
storage-large-restore-workflow-test:
@bash scripts/test-storage-large-restore-canary-workflow.sh
# Regression test the storage large restore SLO evaluator
storage-large-restore-slo-test:
@bash scripts/test-evaluate-storage-large-restore-slo.sh
# Read-only inventory packet for a candidate large workdir
large-workdir-inventory ROOT *ARGS:
python3 scripts/large-workdir-inventory.py {{ROOT}} {{ARGS}}
# Regression test the large workdir inventory helper
large-workdir-inventory-test:
python3 scripts/test-large-workdir-inventory.py
# Installed-binary smoke for release surfaces that ship tcfsd (and optionally tcfs)
install-smoke *ARGS:
bash scripts/install-smoke.sh {{ARGS}}
# Regression test the installed-binary smoke helper with fake installed binaries
install-smoke-test:
bash scripts/test-install-smoke.sh
# ── Nix ─────────────────────────────────────────────────────────────────────
# Build tcfsd via Nix
nix-build:
nix build .#tcfsd
# Run nix flake check
nix-check:
nix flake check
# Enter the dev shell
nix-devshell:
nix develop
# Show active toolchain and local environment helpers
toolchain-status:
rustc --version
cargo --version
just --version
@if command -v nix >/dev/null 2>&1; then nix --version; else echo "nix: not installed"; fi
@if command -v direnv >/dev/null 2>&1; then direnv version; else echo "direnv: not installed"; fi
# ── Cargo ───────────────────────────────────────────────────────────────────
# Build workspace
build:
cargo build --workspace
# Run all tests
test:
cargo test --workspace
# Lint (clippy + fmt check)
lint:
cargo clippy --workspace --all-targets
cargo fmt --all -- --check
# cargo-deny license and advisory check
deny:
cargo deny check
# ── iOS (TestFlight) ─────────────────────────────────────────────────────
# Pipeline: Rust staticlib → xcodegen → archive → export IPA → TestFlight
# All ios-* recipes must run on PZM from Terminal.app (keychain access).
# Full iOS release: build Rust, archive, export, upload
ios-release:
#!/usr/bin/env bash
set -euo pipefail
echo "==> TCFS iOS Release Pipeline"
echo ""
echo "==> [1/3] Rust staticlib + UniFFI..."
nix develop -c bash swift/ios/Scripts/build-rust.sh --clean
echo ""
echo "==> [2/3] Xcode archive + export..."
bash swift/ios/Scripts/xcode-pipeline.sh
echo ""
echo "==> [3/3] TestFlight upload..."
bash swift/ios/Scripts/upload.sh
echo ""
echo "==> Release pipeline complete!"
# Build Rust staticlib + UniFFI bindings (inside nix devshell)
ios-rust *FLAGS:
nix develop -c bash swift/ios/Scripts/build-rust.sh {{FLAGS}}
# Archive + export IPA (must NOT be inside nix devshell)
ios-archive *FLAGS:
bash swift/ios/Scripts/xcode-pipeline.sh {{FLAGS}}
# Export from existing archive + upload (resume after archive succeeded)
ios-upload:
bash swift/ios/Scripts/xcode-pipeline.sh --skip-archive
bash swift/ios/Scripts/upload.sh
# Upload an existing IPA to TestFlight
ios-upload-ipa ipa="swift/ios/build/export/TCFS.ipa":
bash swift/ios/Scripts/upload.sh {{ipa}}
# Setup signing certs (one-time, from Terminal.app)
ios-signing:
bash swift/ios/Scripts/setup-signing.sh
# Clean iOS build artifacts
ios-clean:
rm -rf swift/ios/build swift/ios/TCFS.xcodeproj
# Clean everything including Rust iOS target
ios-clean-all: ios-clean
rm -rf target/aarch64-apple-ios
# ── FileProvider (Darwin) ──────────────────────────────────────────────────
# Build FileProvider .appex bundle (macOS only, requires Xcode CLT)
fileprovider-build:
#!/usr/bin/env bash
set -euo pipefail
if [ "$(uname)" != "Darwin" ]; then
echo "FileProvider extension only builds on macOS" >&2
exit 1
fi
echo "==> Building Rust staticlib..."
cargo build -p tcfs-file-provider --release -j 4
HEADER=$(find target/release/build -name "tcfs_file_provider.h" | head -1)
if [ -z "$HEADER" ]; then
echo "ERROR: cbindgen header not found" >&2
exit 1
fi
echo "==> Building Swift .appex bundle..."
bash swift/fileprovider/build.sh "target/release" "$HEADER" "build/fileprovider"
echo "==> Output: build/fileprovider/TCFSProvider.app"
# Provision FileProvider config (writes S3 creds to App Group container)
fileprovider-provision:
bash swift/fileprovider/provision-config.sh
# Install FileProvider .appex to ~/Applications (macOS only)
fileprovider-install: fileprovider-build fileprovider-provision
#!/usr/bin/env bash
set -euo pipefail
mkdir -p ~/Applications
rm -rf ~/Applications/TCFSProvider.app
cp -R build/fileprovider/TCFSProvider.app ~/Applications/
echo "==> Installed to ~/Applications/TCFSProvider.app"
echo "==> Launching to register FileProvider domain..."
open ~/Applications/TCFSProvider.app