summaryrefslogtreecommitdiff
path: root/Omni/Ide
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-16 08:06:09 -0500
committerBen Sima <ben@bensima.com>2025-12-16 08:06:09 -0500
commita7dcb30c7a465d9fce72b7fc3e605470b2b59814 (patch)
tree57a6436de34062773483dbd0cb745ac103c6bb48 /Omni/Ide
parent4caefe45756fdc21df990b8d6e826c40db1b9c78 (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-xOmni/Ide/push.sh166
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 "$@"