Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions plugins/code-server/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ permissions:
ports:
- 8080 # code-server web UI (listens on loopback; reach via tunnel/Tailscale)
files:
- /home/ec2-user/.config/code-server/config.yaml
- ~/.config/code-server/config.yaml # in the login user's home

config:
port:
Expand Down Expand Up @@ -53,31 +53,40 @@ remote:
set -eu
PORT={{ config.port }}
PASSWORD={{ config.password }}
# code-server reads ~/.config/code-server/config.yaml of the service user.
install -d -o ec2-user -g ec2-user /home/ec2-user/.config/code-server
cat > /home/ec2-user/.config/code-server/config.yaml <<EOF
LOGIN_USER={{ instance.login_user }}
HOME_DIR=$(getent passwd "$LOGIN_USER" | cut -d: -f6)
# code-server reads ~/.config/code-server/config.yaml of the service user
# (the login user, via the code-server@<user> systemd template unit).
install -d -o "$LOGIN_USER" -g "$LOGIN_USER" "$HOME_DIR/.config/code-server"
cat > "$HOME_DIR/.config/code-server/config.yaml" <<EOF
bind-addr: 127.0.0.1:$PORT
auth: password
password: $PASSWORD
cert: false
EOF
chown ec2-user:ec2-user /home/ec2-user/.config/code-server/config.yaml
chmod 600 /home/ec2-user/.config/code-server/config.yaml
chown "$LOGIN_USER:$LOGIN_USER" "$HOME_DIR/.config/code-server/config.yaml"
chmod 600 "$HOME_DIR/.config/code-server/config.yaml"

start:
- type: run
run: |
systemctl enable --now code-server@ec2-user
set -eu
LOGIN_USER={{ instance.login_user }}
systemctl enable --now "code-server@$LOGIN_USER"

health:
interval: 15s
steps:
- type: run
run: systemctl is-active code-server@ec2-user
run: |
LOGIN_USER={{ instance.login_user }}
systemctl is-active "code-server@$LOGIN_USER"

stop:
- type: run
run: systemctl stop code-server@ec2-user
run: |
LOGIN_USER={{ instance.login_user }}
systemctl stop "code-server@$LOGIN_USER"

outputs:
url:
Expand Down
5 changes: 3 additions & 2 deletions plugins/docker/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license: Apache-2.0
# the service, so a long-lived (non-ephemeral) instance can build/run containers.
# (spawn's `task run --container` installs docker on demand for a single job; this
# plugin is for an interactive/persistent box where you want docker always ready.)
# The login user (ec2-user) is added to the docker group so it can run docker
# The instance's login user is added to the docker group so it can run docker
# without sudo after reconnecting.

permissions:
Expand Down Expand Up @@ -46,9 +46,10 @@ remote:
- type: run
run: |
set -eu
LOGIN_USER={{ instance.login_user }}
# Let the login user run docker without sudo. Takes effect on the next
# login/reconnect (group membership is read at session start).
usermod -aG docker ec2-user || true
usermod -aG docker "$LOGIN_USER" || true

start:
- type: run
Expand Down
8 changes: 5 additions & 3 deletions plugins/github-actions-runner/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ remote:
rm -f runner.tar.gz
# The runner refuses to run as root, so its files must be owned by the
# login user that configures/runs it.
chown -R ec2-user:ec2-user /opt/actions-runner
LOGIN_USER={{ instance.login_user }}
chown -R "$LOGIN_USER:$LOGIN_USER" /opt/actions-runner

configure:
# config.sh refuses to run as root — run it as the login user.
Expand All @@ -135,12 +136,13 @@ remote:

start:
# svc.sh installs + starts a systemd service; this part runs as root but the
# service itself is configured to run as ec2-user by svc.sh.
# service itself is configured to run as the login user by svc.sh.
- type: run
run: |
set -eu
LOGIN_USER={{ instance.login_user }}
cd /opt/actions-runner
./svc.sh install ec2-user
./svc.sh install "$LOGIN_USER"
./svc.sh start

health:
Expand Down
17 changes: 10 additions & 7 deletions plugins/jupyterlab/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ config:
notebook_dir:
type: string
required: false
default: "/home/ec2-user"
description: "Root directory JupyterLab opens in"
default: ""
description: "Root directory JupyterLab opens in (default: the login user's home)"

conditions:
remote:
Expand Down Expand Up @@ -70,10 +70,13 @@ remote:
PORT={{ config.port }}
TOKEN={{ config.token }}
NBDIR={{ config.notebook_dir }}
# Runs as ec2-user (spawn's default AL2023 login user), bound to loopback.
# A non-empty token requires it in the URL; an empty token disables token
# auth entirely — acceptable ONLY because the server binds to 127.0.0.1 and
# is reached over an authenticated SSH tunnel / Tailscale, never public.
LOGIN_USER={{ instance.login_user }}
# Default the notebook dir to the login user's home when unset.
[ -n "$NBDIR" ] || NBDIR=$(getent passwd "$LOGIN_USER" | cut -d: -f6)
# Runs as the instance's LOGIN USER (not a hardcoded ec2-user), bound to
# loopback. A non-empty token requires it in the URL; an empty token
# disables token auth entirely — acceptable ONLY because the server binds
# to 127.0.0.1 and is reached over an SSH tunnel / Tailscale, never public.
cat > /etc/systemd/system/jupyterlab.service <<EOF
[Unit]
Description=JupyterLab
Expand All @@ -82,7 +85,7 @@ remote:

[Service]
Type=simple
User=ec2-user
User=$LOGIN_USER
WorkingDirectory=$NBDIR
ExecStart=/opt/jupyterlab/bin/jupyter lab --no-browser --ip=127.0.0.1 --port=$PORT --ServerApp.token=$TOKEN
Restart=on-failure
Expand Down
18 changes: 11 additions & 7 deletions plugins/rclone/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,21 @@ remote:
run: |
set -eu
CONF={{ pushed.rclone_conf }}
install -d -o ec2-user -g ec2-user /home/ec2-user/.config/rclone
printf '%s' "$CONF" > /home/ec2-user/.config/rclone/rclone.conf
chown ec2-user:ec2-user /home/ec2-user/.config/rclone/rclone.conf
chmod 600 /home/ec2-user/.config/rclone/rclone.conf
LOGIN_USER={{ instance.login_user }}
HOME_DIR=$(getent passwd "$LOGIN_USER" | cut -d: -f6)
install -d -o "$LOGIN_USER" -g "$LOGIN_USER" "$HOME_DIR/.config/rclone"
printf '%s' "$CONF" > "$HOME_DIR/.config/rclone/rclone.conf"
chown "$LOGIN_USER:$LOGIN_USER" "$HOME_DIR/.config/rclone/rclone.conf"
chmod 600 "$HOME_DIR/.config/rclone/rclone.conf"
- type: run
run: |
set -eu
REMOTE={{ config.remote }}
RPATH={{ config.path }}
MOUNT_PATH={{ config.mount_path }}
install -d -o ec2-user -g ec2-user "$MOUNT_PATH"
LOGIN_USER={{ instance.login_user }}
HOME_DIR=$(getent passwd "$LOGIN_USER" | cut -d: -f6)
install -d -o "$LOGIN_USER" -g "$LOGIN_USER" "$MOUNT_PATH"
# allow_other lets other users see the mount; requires user_allow_other in
# /etc/fuse.conf, which we ensure.
grep -q '^user_allow_other' /etc/fuse.conf 2>/dev/null || echo user_allow_other >> /etc/fuse.conf
Expand All @@ -107,8 +111,8 @@ remote:

[Service]
Type=notify
User=ec2-user
ExecStart=/usr/bin/rclone mount ${REMOTE}:${RPATH} $MOUNT_PATH --config /home/ec2-user/.config/rclone/rclone.conf --allow-other --vfs-cache-mode writes
User=$LOGIN_USER
ExecStart=/usr/bin/rclone mount ${REMOTE}:${RPATH} $MOUNT_PATH --config $HOME_DIR/.config/rclone/rclone.conf --allow-other --vfs-cache-mode writes
ExecStop=/bin/fusermount -u $MOUNT_PATH
Restart=on-failure

Expand Down
7 changes: 4 additions & 3 deletions plugins/vscode-tunnel/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ remote:
run: |
set -eu
NAME={{ config.name }}
LOGIN_USER={{ instance.login_user }}
NAME_ARG=""
[ -n "$NAME" ] && NAME_ARG="--name $NAME"
# Per-user service: runs `code tunnel` as ec2-user so the device-login
# token and tunnel state persist under /home/ec2-user/.vscode-cli.
# Per-user service: runs `code tunnel` as the login user so the
# device-login token + tunnel state persist under that user's ~/.vscode-cli.
cat > /etc/systemd/system/vscode-tunnel.service <<EOF
[Unit]
Description=VS Code Remote Tunnel
Expand All @@ -73,7 +74,7 @@ remote:

[Service]
Type=simple
User=ec2-user
User=$LOGIN_USER
ExecStart=/usr/local/bin/code tunnel --accept-server-license-terms $NAME_ARG
Restart=on-failure

Expand Down