diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-16 08:06:09 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-16 08:06:09 -0500 |
| commit | a7dcb30c7a465d9fce72b7fc3e605470b2b59814 (patch) | |
| tree | 57a6436de34062773483dbd0cb745ac103c6bb48 /Omni/Ide | |
| parent | 4caefe45756fdc21df990b8d6e826c40db1b9c78 (diff) | |
feat(deploy): Complete mini-PaaS deployment system (t-266)
- Add Omni/Deploy/ with Manifest, Deployer, Systemd, Caddy modules
- Manifest CLI: show, update, add-service, list, rollback commands
- Deployer: polls S3 manifest, pulls closures, manages systemd units
- Caddy integration for dynamic reverse proxy routes
- bild: auto-cache to S3, outputs STORE_PATH for push.sh
- push.sh: supports both NixOS and service deploys
- Biz.nix: simplified to base OS + deployer only
- Services (podcastitlater-web/worker) now deployer-managed
- Documentation: README.md with operations guide
Diffstat (limited to 'Omni/Ide')
| -rwxr-xr-x | Omni/Ide/push.sh | 166 |
1 files changed, 132 insertions, 34 deletions
diff --git a/Omni/Ide/push.sh b/Omni/Ide/push.sh index ce1df3d..25c0ed6 100755 --- a/Omni/Ide/push.sh +++ b/Omni/Ide/push.sh @@ -1,35 +1,133 @@ #!/usr/bin/env bash -# Eventually convert to haskell, see: -# - https://github.com/awakesecurity/nix-deploy/blob/master/src/Main.hs -# - http://www.haskellforall.com/2018/08/nixos-in-production.html -prefix=${PWD/$CODEROOT} -if [[ "$prefix" == "" ]] -then - target="$1" -else - target="$prefix.$1" -fi -what=$(realpath "${CODEROOT:?}/_/nix/$target") -# hack: get the domain from the systemd service. there does not seem to be a way -# to get it from nix-instantiate. (or, maybe i should put this in bild --plan?) -where=$(rg --only-matching --replace '$2' --regexp '(domainname ")(.*)(")' \ - "$what/etc/systemd/system/domainname.service") -nix copy --to ssh://"$USER"@"$where" "$what" -ssh "$USER"@"$where" sudo nix-env --profile /nix/var/nix/profiles/system --set "$what" -switch_cmd=( - systemd-run - -E LOCALE_ARCHIVE - --setenv=XDG_RUNTIME_DIR="" - --collect - --no-ask-password - --pipe - --quiet - --service-type=exec - --unit=push-switch-to-configuration - --wait - "$what/bin/switch-to-configuration" - "switch" -) -# shellcheck disable=SC2029 -ssh "$USER"@"$where" sudo "${switch_cmd[@]}" -echo "${GRN}good: push: $target${NC}" +# Deployment script for both NixOS configs and individual services. +# +# Usage: +# push.sh Biz.nix # NixOS deploy (existing behavior) +# push.sh Biz/PodcastItLater/Web.py # Service deploy (new behavior) +# +# For service deploys: +# 1. Builds the target with bild (caches to S3 by default) +# 2. Updates the manifest.json in S3 with new store path +# 3. Deployer on target picks up change within 5 minutes +# +# Environment: +# CODEROOT - Root of the codebase (required) +# NIX_CACHE_KEY - Path to signing key (required for service deploys) + +set -euo pipefail + +# Colors +GRN='\033[0;32m' +YLW='\033[0;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Derive service name from target path +# Biz/PodcastItLater/Web.py -> podcastitlater-web +# Biz/Storybook.py -> storybook +derive_service_name() { + local target="$1" + # Remove extension + local base="${target%.*}" + # Remove Biz/ prefix if present + base="${base#Biz/}" + # Convert slashes to hyphens and lowercase + echo "$base" | tr '/' '-' | tr '[:upper:]' '[:lower:]' +} + +# NixOS deploy (existing behavior) +nixos_deploy() { + local target="$1" + prefix=${PWD/$CODEROOT} + if [[ "$prefix" == "" ]]; then + target="$1" + else + target="$prefix.$1" + fi + what=$(realpath "${CODEROOT:?}/_/nix/$target") + # hack: get the domain from the systemd service + where=$(rg --only-matching --replace '$2' --regexp '(domainname ")(.*)(")' \ + "$what/etc/systemd/system/domainname.service") + nix copy --to ssh://"$USER"@"$where" "$what" + ssh "$USER"@"$where" sudo nix-env --profile /nix/var/nix/profiles/system --set "$what" + switch_cmd=( + systemd-run + -E LOCALE_ARCHIVE + --setenv=XDG_RUNTIME_DIR="" + --collect + --no-ask-password + --pipe + --quiet + --service-type=exec + --unit=push-switch-to-configuration + --wait + "$what/bin/switch-to-configuration" + "switch" + ) + # shellcheck disable=SC2029 + ssh "$USER"@"$where" sudo "${switch_cmd[@]}" + echo -e "${GRN}good: push: $target${NC}" +} + +# Service deploy (new behavior) +service_deploy() { + local target="$1" + local service_name + service_name=$(derive_service_name "$target") + + echo -e "${YLW}info: push: deploying service $service_name${NC}" + + # 1. Build and cache (bild caches by default, outputs STORE_PATH=...) + echo -e "${YLW}info: push: building $target${NC}" + local bild_output + bild_output=$(bild "$target" 2>&1) || { + echo -e "${RED}fail: push: bild failed${NC}" + echo "$bild_output" + exit 1 + } + + # Extract store path from bild output + local store_path + store_path=$(echo "$bild_output" | grep '^STORE_PATH=' | cut -d= -f2) + + if [[ -z "$store_path" ]]; then + echo -e "${RED}fail: push: could not extract store path from bild output${NC}" + echo "$bild_output" + exit 1 + fi + + echo -e "${YLW}info: push: cached $store_path${NC}" + + # 2. Get git revision + local revision + revision=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + + # 3. Update manifest in S3 + echo -e "${YLW}info: push: updating manifest${NC}" + "${CODEROOT}/_/nix/deploy-manifest/bin/deploy-manifest" update "$service_name" "$store_path" "$revision" || { + echo -e "${RED}fail: push: manifest update failed${NC}" + exit 1 + } + + echo -e "${GRN}good: push: $service_name deployed (deployer will pick up in <5 min)${NC}" +} + +# Main +main() { + if [[ $# -lt 1 ]]; then + echo "Usage: push.sh <target>" + echo " target.nix -> NixOS deploy" + echo " target.py/.hs/.. -> Service deploy" + exit 1 + fi + + local target="$1" + + if [[ "$target" == *.nix ]]; then + nixos_deploy "$target" + else + service_deploy "$target" + fi +} + +main "$@" |
