From ef6dbdd2ac273dc4a01c70437ee7984cea9f2a3c Mon Sep 17 00:00:00 2001 From: yyamashita Date: Sun, 17 May 2026 11:29:27 +0900 Subject: Reorganize repo into caddy/, git/, claude/ directories - caddy/: Caddyfile, docker-compose.yml, deploy.sh (hook runs this only) - git/: repos.txt, hooks/*/post-receive, install.sh, server-setup.sh - claude/: sessions.txt, systemd/claude-code@.service, sync.sh Post-receive hook is now: checkout + bash caddy/deploy.sh Co-Authored-By: Claude Sonnet 4.6 --- claude/sync.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100755 claude/sync.sh (limited to 'claude/sync.sh') diff --git a/claude/sync.sh b/claude/sync.sh new file mode 100755 index 0000000..26f3da1 --- /dev/null +++ b/claude/sync.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# サーバー上で root として手動実行する +# 各ユーザーの Claude Code systemd user service を sessions.txt に基づいて同期する +set -euo pipefail + +APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +TEMPLATE_SRC="$APP_DIR/claude/systemd/claude-code@.service" +SESSIONS_FILE="$APP_DIR/claude/sessions.txt" + +declare -A user_repos + +while IFS= read -r line; do + [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue + user="${line%%:*}" + repo="${line#*:}" + user_repos["$user"]+=" $repo" +done < "$SESSIONS_FILE" + +for user in "${!user_repos[@]}"; do + uid=$(id -u "$user" 2>/dev/null) || { echo "WARNING: user $user not found, skipping"; continue; } + runtime_dir="/run/user/$uid" + systemd_dir="/home/$user/.config/systemd/user" + + mkdir -p "$systemd_dir" + chown "$user:$user" "$systemd_dir" + + if ! diff -q "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" >/dev/null 2>&1; then + echo "[$user] Updating claude-code@.service template" + cp "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" + chown "$user:$user" "$systemd_dir/claude-code@.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user daemon-reload + fi + + desired=() + for repo in ${user_repos[$user]}; do + [[ -z "$repo" ]] && continue + desired+=("$repo") + repo_path="/home/$user/workspaces/repos/$repo" + if [[ ! -d "$repo_path" ]]; then + echo "[$user] WARNING: $repo_path not found, skipping $repo" + continue + fi + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user enable "claude-code@${repo}.service" 2>/dev/null || true + if ! runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user is-active "claude-code@${repo}.service" >/dev/null 2>&1; then + echo "[$user] Starting claude-code@${repo}.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user start "claude-code@${repo}.service" || true + fi + done + + while IFS= read -r unit; do + instance="${unit#claude-code@}" + instance="${instance%.service}" + if ! printf '%s\n' "${desired[@]}" | grep -qx "$instance"; then + echo "[$user] Disabling claude-code@${instance}.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user disable --now "claude-code@${instance}.service" || true + fi + done < <(runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user list-unit-files --plain --no-legend 'claude-code@*.service' 2>/dev/null \ + | awk '$2 == "enabled" {print $1}') +done + +echo "Claude Code session sync complete." -- cgit v1.2.3