Ctrl K
ComunidadGuías…

scripts/ferry-up.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env sh
# Get Ferryman current and this repository attached, in one command.
#
#   curl -fsSL https://raw.githubusercontent.com/estejosh/ferryman/main/scripts/ferry-up.sh | sh
#   ferry-up.sh                     # from a checkout
#
# # What this is for
#
# The first outside upgrade report said it plainly: there is no documented upgrade path
# for a channel-mode worker. `docs/UPGRADING.md` describes a SQLite server with a
# `/healthz` endpoint that does not exist in this mode, and `docs/UPDATES.md` describes
# an updater that does not apply. The agent had to read the source of
# `ferryman-channel` to convince itself its signing key would survive before it dared
# upgrade. A real user will not do that.
#
# So: one command, safe to run repeatedly, in any repository. It installs or updates
# `ferry`, attaches the repository if it is not attached, and then tells you where you
# stand - including the one fact a fleet actually needs, which is whether this machine
# is on the same build as the others.
#
# # What it will not do
#
# It does not touch your signing keys, your channel, or your work. Upgrading has never
# rotated a key - that is deliberate, and the reason is in `ferryman-channel`: rotating
# on upgrade would invalidate every signature that machine has already published. This
# script prints the key fingerprint before and after so you can see that for yourself
# rather than take it on faith.
set -eu

say()  { printf 'ferry-up: %s\n' "$1"; }
warn() { printf 'ferry-up: %s\n' "$1" >&2; }
die()  { printf 'ferry-up: %s\n' "$1" >&2; exit 1; }

EMAIL="${FERRYMAN_EMAIL:-}"
ENABLE=1
for arg in "$@"; do
  case "$arg" in
    --email=*) EMAIL="${arg#--email=}" ;;
    --no-enable) ENABLE=0 ;;
    --help|-h)
      cat <<'USAGE'
ferry-up: install or update ferry, attach this repository, and report status.

  --email=you@example.com   contact email for `ferry enable` (or set FERRYMAN_EMAIL)
  --no-enable               update the binary only; do not attach this repository

Safe to run twice. Never rotates a signing key.
USAGE
      exit 0 ;;
    *) die "unknown option: $arg (try --help)" ;;
  esac
done

# ---------------------------------------------------------------- before

# Recorded BEFORE anything changes, because "did my identity survive?" is the question
# an upgrade has to be able to answer, and it cannot be answered afterwards from memory.
BEFORE_VERSION="$(ferry --version 2>/dev/null || echo 'not installed')"
BEFORE_KEYS=""
if [ -d .ferryman/keys ]; then
  # Fingerprints only. The key never leaves the machine and must not appear in a log.
  if command -v sha256sum >/dev/null 2>&1; then
    BEFORE_KEYS="$(sha256sum .ferryman/keys/*.key 2>/dev/null | cut -c1-16 || true)"
  elif command -v shasum >/dev/null 2>&1; then
    BEFORE_KEYS="$(shasum -a 256 .ferryman/keys/*.key 2>/dev/null | cut -c1-16 || true)"
  fi
fi

say "before: $BEFORE_VERSION"

# ---------------------------------------------------------------- install

say 'installing or updating ferry...'
if command -v curl >/dev/null 2>&1; then
  curl -fsSL https://raw.githubusercontent.com/estejosh/ferryman/main/scripts/install.sh | sh
elif command -v wget >/dev/null 2>&1; then
  wget -qO- https://raw.githubusercontent.com/estejosh/ferryman/main/scripts/install.sh | sh
else
  die 'need curl or wget'
fi

command -v ferry >/dev/null 2>&1 || die 'ferry is still not on PATH; add the install directory to PATH and re-run'

AFTER_VERSION="$(ferry --version 2>&1)"
say "after:  $AFTER_VERSION"
if [ "$BEFORE_VERSION" = "$AFTER_VERSION" ] && [ "$BEFORE_VERSION" != 'not installed' ]; then
  # Not an error. Worth saying out loud, because the previous release reported an
  # identical version string before and after a day of changes, and "nothing appears to
  # have happened" was indistinguishable from "nothing happened".
  say 'the version and commit are unchanged, so this machine was already current'
fi

# ---------------------------------------------------------------- attach

if [ "$ENABLE" -eq 1 ]; then
  if [ -f .ferryman/bridge.toml ]; then
    say 'this repository is already attached; leaving its configuration alone'
  elif [ -z "$EMAIL" ]; then
    warn 'this repository is not attached, and no email was given'
    warn 'run:  ferry-up.sh --email=you@example.com   (or FERRYMAN_EMAIL=...)'
  else
    say "attaching this repository as $(basename "$(pwd)")..."
    # `enable` never prompts and is safe to run twice; it is built to be run by an agent
    # with nobody watching.
    ferry enable --email "$EMAIL"
  fi
fi

# ---------------------------------------------------------------- after

printf '\n'
if [ -f .ferryman/bridge.toml ]; then
  say 'where this repository stands:'
  ferry channel status 2>&1 || true
  printf '\n'
  ferry channel agents 2>&1 || true
  printf '\n'
  # The one that matters after an upgrade: every artifact should still read `Valid`. A
  # new binary that cannot verify signatures written by the old one is the failure this
  # whole check exists to catch.
  say 'signature check on every artifact (all should read Valid):'
  ferry channel tasks 2>&1 || true
  printf '\n'
fi

AFTER_KEYS=""
if [ -d .ferryman/keys ]; then
  if command -v sha256sum >/dev/null 2>&1; then
    AFTER_KEYS="$(sha256sum .ferryman/keys/*.key 2>/dev/null | cut -c1-16 || true)"
  elif command -v shasum >/dev/null 2>&1; then
    AFTER_KEYS="$(shasum -a 256 .ferryman/keys/*.key 2>/dev/null | cut -c1-16 || true)"
  fi
fi
if [ -n "$BEFORE_KEYS" ]; then
  if [ "$BEFORE_KEYS" = "$AFTER_KEYS" ]; then
    say 'signing key unchanged (upgrading never rotates one)'
  else
    # Loud, and stop. A changed key means every artifact this machine has published
    # stops verifying for every other machine, and the roster will treat its next
    # registration as an impostor. Recovering is a restore, not a retry.
    warn ''
    warn '*** THE SIGNING KEY CHANGED. STOP. ***'
    warn 'Every artifact this machine published will now fail to verify elsewhere.'
    warn 'Restore .ferryman/keys from a backup before running anything else, and'
    warn 'please report this: https://github.com/estejosh/ferryman/issues'
    exit 1
  fi
fi

cat <<'NEXT'
next:
  ferry agent run        # this machine does work
  ferry agent review     # this machine judges results
  ferry soak             # a report to paste into an issue while we soak-test

Run this same command on every machine in the fleet, then compare the commit in
`ferry --version`. If they differ, they are not running the same Ferryman.
NEXT