move-server.sh: --tools-dir for agent installs and /tmp on a separate disk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6b1d7f91b8
commit
eef17eb591
3 files changed
+36
-4
No files matched your search
@@ -3,6 +3,12 @@
|
|||||||
All notable changes to CodeCraft. Versions follow [Semantic Versioning](https://semver.org/);
|
All notable changes to CodeCraft. Versions follow [Semantic Versioning](https://semver.org/);
|
||||||
until 1.0, minor versions may contain breaking changes.
|
until 1.0, minor versions may contain breaking changes.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `scripts/move-server.sh --tools-dir DIR`: agent home, users' homes and `/tmp` on a separate disk.
|
||||||
|
|
||||||
## [v202611-00005] – 2026-11-09
|
## [v202611-00005] – 2026-11-09
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ copies the workspace, stops CodeCraft, streams the data volume to `<dir>/data`,
|
|||||||
`docker-compose.yml` (and a `start.sh` for hosts without Compose) with bind mounts, starts the
|
`docker-compose.yml` (and a `start.sh` for hosts without Compose) with bind mounts, starts the
|
||||||
published image there and runs `scripts/smoke-test.sh`. The old container is only stopped, so
|
published image there and runs `scripts/smoke-test.sh`. The old container is only stopped, so
|
||||||
you can roll back. `--help` lists the options (owner, port, bind address, dry run).
|
you can roll back. `--help` lists the options (owner, port, bind address, dry run).
|
||||||
|
`--tools-dir /mnt/disks/ssd/codecraft` puts everything agents install or download – the agent
|
||||||
|
home (`/data/home`: toolchains, pip/npm/cargo packages, caches), the users' homes and `/tmp` – on
|
||||||
|
a separate disk; the data folder keeps only the database, configuration and backups.
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
|||||||
+27
-4
@@ -23,6 +23,9 @@
|
|||||||
#
|
#
|
||||||
# Options:
|
# Options:
|
||||||
# --workspace DIR project folder on the target (default <dir>/workspace)
|
# --workspace DIR project folder on the target (default <dir>/workspace)
|
||||||
|
# --tools-dir DIR separate disk for what agents install and download: the agent home
|
||||||
|
# (/data/home), the users' homes (/data/users) and /tmp are bind
|
||||||
|
# mounts from DIR/home, DIR/users and DIR/tmp (default: inside <dir>/data)
|
||||||
# --uid N --gid N owner of data and workspace on the target (default: UID/GID of .env)
|
# --uid N --gid N owner of data and workspace on the target (default: UID/GID of .env)
|
||||||
# --port N host port on the target (default: PORT of .env)
|
# --port N host port on the target (default: PORT of .env)
|
||||||
# --bind ADDR bind address on the target (default: BIND_ADDR of .env or 127.0.0.1)
|
# --bind ADDR bind address on the target (default: BIND_ADDR of .env or 127.0.0.1)
|
||||||
@@ -34,11 +37,12 @@
|
|||||||
# --dry-run show the steps only
|
# --dry-run show the steps only
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
target="" ws_target="" uid="" gid="" port="" bind="" name="codecraft"
|
target="" ws_target="" tools_dir="" uid="" gid="" port="" bind="" name="codecraft"
|
||||||
src_container="codecraft" src_volume="codecraft-data" ws_source="" stop=1 dry=0
|
src_container="codecraft" src_volume="codecraft-data" ws_source="" stop=1 dry=0
|
||||||
while (($#)); do
|
while (($#)); do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--workspace) ws_target="$2"; shift ;;
|
--workspace) ws_target="$2"; shift ;;
|
||||||
|
--tools-dir) tools_dir="$2"; shift ;;
|
||||||
--uid) uid="$2"; shift ;;
|
--uid) uid="$2"; shift ;;
|
||||||
--gid) gid="$2"; shift ;;
|
--gid) gid="$2"; shift ;;
|
||||||
--port) port="$2"; shift ;;
|
--port) port="$2"; shift ;;
|
||||||
@@ -97,10 +101,15 @@ step "Checking source and target"
|
|||||||
docker volume inspect "$src_volume" >/dev/null || fail "volume $src_volume not found"
|
docker volume inspect "$src_volume" >/dev/null || fail "volume $src_volume not found"
|
||||||
[[ -d "$ws_source" ]] || fail "workspace $ws_source not found"
|
[[ -d "$ws_source" ]] || fail "workspace $ws_source not found"
|
||||||
echo "source: container $src_container, volume $src_volume, workspace $ws_source"
|
echo "source: container $src_container, volume $src_volume, workspace $ws_source"
|
||||||
echo "target: $host:$dir (data in $dir/data, workspace $ws_target), uid $uid:$gid, ${bind}:${port}, image $image_repo:$version"
|
tools_dir="${tools_dir%/}"
|
||||||
|
echo "target: $host:$dir (data in $dir/data, workspace $ws_target${tools_dir:+, agent installs and /tmp in $tools_dir}), uid $uid:$gid, ${bind}:${port}, image $image_repo:$version"
|
||||||
remote "command -v docker >/dev/null && command -v tar >/dev/null && command -v rsync >/dev/null" || fail "the target needs docker, tar and rsync"
|
remote "command -v docker >/dev/null && command -v tar >/dev/null && command -v rsync >/dev/null" || fail "the target needs docker, tar and rsync"
|
||||||
remote "mkdir -p $(q "$dir/data") $(q "$dir/docker") $(q "$ws_target") && test -z \"\$(ls -A $(q "$dir/data"))\"" \
|
remote "mkdir -p $(q "$dir/data") $(q "$dir/docker") $(q "$ws_target") && test -z \"\$(ls -A $(q "$dir/data"))\"" \
|
||||||
|| fail "$dir/data on the target is not empty – refusing to overwrite (move it away first)"
|
|| fail "$dir/data on the target is not empty – refusing to overwrite (move it away first)"
|
||||||
|
if [[ -n "$tools_dir" ]]; then
|
||||||
|
remote "mkdir -p $(q "$tools_dir") && test ! -e $(q "$tools_dir/home") && test ! -e $(q "$tools_dir/users")" \
|
||||||
|
|| fail "$tools_dir already has home/ or users/ – refusing to overwrite (move them away first)"
|
||||||
|
fi
|
||||||
|
|
||||||
step "Copying the workspace (first pass, CodeCraft keeps running)"
|
step "Copying the workspace (first pass, CodeCraft keeps running)"
|
||||||
sync_workspace
|
sync_workspace
|
||||||
@@ -118,9 +127,22 @@ else
|
|||||||
| remote "tar -C $(q "$dir/data") -xpf -"
|
| remote "tar -C $(q "$dir/data") -xpf -"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$tools_dir" ]]; then
|
||||||
|
step "Moving the agent home and the users' homes to $tools_dir"
|
||||||
|
remote "mkdir -p $(q "$tools_dir/tmp") $(q "$dir/data/home") $(q "$dir/data/users") \
|
||||||
|
&& mv $(q "$dir/data/home") $(q "$tools_dir/home") && mv $(q "$dir/data/users") $(q "$tools_dir/users") \
|
||||||
|
&& mkdir -p $(q "$dir/data/home") $(q "$dir/data/users") && chmod 1777 $(q "$tools_dir/tmp")"
|
||||||
|
fi
|
||||||
|
|
||||||
step "Copying the workspace (changes since the first pass)"
|
step "Copying the workspace (changes since the first pass)"
|
||||||
sync_workspace
|
sync_workspace
|
||||||
remote "chown -R $uid:$gid $(q "$dir/data") $(q "$ws_target") 2>/dev/null || echo 'note: could not chown (not root) – check file owners'"
|
remote "chown -R $uid:$gid $(q "$dir/data") $(q "$ws_target") ${tools_dir:+$(q "$tools_dir/home") $(q "$tools_dir/users")} 2>/dev/null || echo 'note: could not chown (not root) – check file owners'"
|
||||||
|
# Bind mounts for the tools disk (compose lines and docker run flags).
|
||||||
|
tool_mounts="" tool_flags=""
|
||||||
|
if [[ -n "$tools_dir" ]]; then
|
||||||
|
tool_mounts=$(printf ' - %s/home:/data/home\n - %s/users:/data/users\n - %s/tmp:/tmp\n' "$tools_dir" "$tools_dir" "$tools_dir")
|
||||||
|
tool_flags="-v $tools_dir/home:/data/home -v $tools_dir/users:/data/users -v $tools_dir/tmp:/tmp "
|
||||||
|
fi
|
||||||
|
|
||||||
step "Writing docker-compose.yml, .env and start.sh"
|
step "Writing docker-compose.yml, .env and start.sh"
|
||||||
put_file "$dir/docker/seccomp-sandbox.json" <docker/seccomp-sandbox.json
|
put_file "$dir/docker/seccomp-sandbox.json" <docker/seccomp-sandbox.json
|
||||||
@@ -145,6 +167,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- $dir/data:/data
|
- $dir/data:/data
|
||||||
- \${WORKSPACE}:/workspace
|
- \${WORKSPACE}:/workspace
|
||||||
|
$tool_mounts
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
- "host.docker.internal:host-gateway"
|
- "host.docker.internal:host-gateway"
|
||||||
shm_size: "1gb"
|
shm_size: "1gb"
|
||||||
@@ -163,7 +186,7 @@ val() { sed -n "s/^\$1=//p" .env | tail -1; }
|
|||||||
docker rm -f $name >/dev/null 2>&1 || true
|
docker rm -f $name >/dev/null 2>&1 || true
|
||||||
exec docker run -d --name $name --restart unless-stopped --user "\$(val UID):\$(val GID)" \\
|
exec docker run -d --name $name --restart unless-stopped --user "\$(val UID):\$(val GID)" \\
|
||||||
-p "\$(val BIND_ADDR):\$(val PORT):8787" --env-file .env \\
|
-p "\$(val BIND_ADDR):\$(val PORT):8787" --env-file .env \\
|
||||||
-v $dir/data:/data -v "\$(val WORKSPACE):/workspace" \\
|
-v $dir/data:/data -v "\$(val WORKSPACE):/workspace" $tool_flags\\
|
||||||
--add-host host.docker.internal:host-gateway --shm-size 1g \\
|
--add-host host.docker.internal:host-gateway --shm-size 1g \\
|
||||||
--security-opt seccomp=$dir/docker/seccomp-sandbox.json \\
|
--security-opt seccomp=$dir/docker/seccomp-sandbox.json \\
|
||||||
--security-opt apparmor=unconfined --security-opt systempaths=unconfined \\
|
--security-opt apparmor=unconfined --security-opt systempaths=unconfined \\
|
||||||
|
|||||||
Reference in new issue
Block a user