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
28 changes: 28 additions & 0 deletions .github/actions/dgoss/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Validate an image with goss
description: >-
Boots a loaded image the way the drukbox docker provider boots a druks box
and checks the goss.yaml beside its Dockerfile inside it.
inputs:
image:
description: The loaded image to boot.
required: true
files-path:
description: The directory that holds goss.yaml.
required: true
runs:
using: composite
steps:
- shell: bash
env:
GOSS_VERSION: 0.4.10
GOSS_FILES_PATH: ${{ inputs.files-path }}
GOSS_OPTS: -r 30s -s 1s --format documentation
IMAGE: ${{ inputs.image }}
run: |
curl -fsSL "https://github.com/goss-org/goss/releases/download/v$GOSS_VERSION/goss_${GOSS_VERSION}_linux_x86_64.tar.gz" \
| tar -xz -C "$RUNNER_TEMP" goss
curl -fsSL -o "$RUNNER_TEMP/dgoss" "https://github.com/goss-org/goss/releases/download/v$GOSS_VERSION/dgoss"
chmod +x "$RUNNER_TEMP/dgoss"
GOSS_PATH="$RUNNER_TEMP/goss" "$RUNNER_TEMP/dgoss" run \
-e DRUKBOX_SSH_USER=druks -e 'DRUKBOX_AUTHORIZED_KEY=ssh-ed25519 AAAA goss' \
"$IMAGE"
25 changes: 10 additions & 15 deletions .github/workflows/on-pull-request-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,10 @@ jobs:
load: true
tags: druks-sandbox:pr
cache-from: type=gha,scope=sandbox
# dgoss boots the image the way the drukbox docker provider does and
# checks deploy/sandbox/goss.yaml inside it.
- name: Validate the sandbox image
env:
GOSS_VERSION: 0.4.10
GOSS_FILES_PATH: deploy/sandbox
GOSS_OPTS: -r 30s -s 1s --format documentation
run: |
curl -fsSL "https://github.com/goss-org/goss/releases/download/v$GOSS_VERSION/goss_${GOSS_VERSION}_linux_x86_64.tar.gz" \
| tar -xz -C "$RUNNER_TEMP" goss
curl -fsSL -o "$RUNNER_TEMP/dgoss" "https://github.com/goss-org/goss/releases/download/v$GOSS_VERSION/dgoss"
chmod +x "$RUNNER_TEMP/dgoss"
GOSS_PATH="$RUNNER_TEMP/goss" "$RUNNER_TEMP/dgoss" run \
-e DRUKBOX_SSH_USER=druks -e 'DRUKBOX_AUTHORIZED_KEY=ssh-ed25519 AAAA goss' \
druks-sandbox:pr
- uses: ./.github/actions/dgoss
with:
image: druks-sandbox:pr
files-path: deploy/sandbox

# The Docker Sandboxes template must keep its base's boot contract after
# the toolchain layers: `sbx create` sends no environment variables, drukbox
Expand Down Expand Up @@ -108,4 +97,10 @@ jobs:
context: deploy/browser
platforms: linux/amd64
push: false
load: true
tags: druks-browser:pr
cache-from: type=gha,scope=browser
- uses: ./.github/actions/dgoss
with:
image: druks-browser:pr
files-path: deploy/browser
7 changes: 4 additions & 3 deletions deploy/browser/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
# vault session and drive it — over CDP or pinchtab, both loopback-only,
# reached through SSH like every sandbox. No harness ever runs here.
#
# Built from the drukbox sandbox base (Ubuntu + sshd); the entrypoint
# seeds a non-root user and starts the display stack.
# Built from the drukbox sandbox base (Ubuntu + sshd). The image adds a
# non-root user; its entrypoint starts the display stack, then the base
# entrypoint seeds that user's key and runs sshd.
#
# Published by .github/workflows/publish-sandbox-image.yml as
# ghcr.io/czpython/druks/browser.
FROM ghcr.io/czpython/drukbox/sandbox:latest@sha256:72c6ab246c53481051d8d4ec9ed34e9aff47f539f989f625cf20ba82e9b3f311
FROM ghcr.io/czpython/drukbox/sandbox:latest@sha256:cccf324cada9c1b0df409858dac8188e0ed2591ed88ee3d5fb59db9055a75244

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

Expand Down
22 changes: 4 additions & 18 deletions deploy/browser/entrypoint
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
#!/usr/bin/env bash
# First-boot entrypoint. Seeds the non-root ``druks`` user like the sandbox
# entrypoint, then the display stack: Xvfb for the browser to render into,
# loopback-only VNC for the login window's bridge. SSH stays the only ingress.
# The display stack, then the drukbox base entrypoint boots the box: Xvfb for
# the browser to render into, loopback-only VNC for the login window's bridge.
# SSH stays the only ingress.
set -euo pipefail

: "${DRUKBOX_AUTHORIZED_KEY:?DRUKBOX_AUTHORIZED_KEY is required}"

install -d -m 700 -o druks -g druks /home/druks/.ssh
printf '%s\n' "$DRUKBOX_AUTHORIZED_KEY" > /home/druks/.ssh/authorized_keys
chmod 600 /home/druks/.ssh/authorized_keys
chown druks:druks /home/druks/.ssh/authorized_keys

# Persist caller-supplied env for SSH sessions: pam_env reads /etc/environment.
for name in ${DRUKBOX_ENV_KEYS:-}; do
printf '%s=%s\n' "$name" "${!name-}" >> /etc/environment
done

Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp -ac &
# The VNC port binds loopback only and is reached solely over the authenticated
# SSH channel, so SSH is the gate and x11vnc runs without its own password.
Expand All @@ -24,6 +12,4 @@ Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp -ac &
x11vnc -display :99 -loop -forever -listen 127.0.0.1 -rfbport 5900 \
-nopw -noxdamage -shared &

ssh-keygen -A

exec /usr/sbin/sshd -D -e
exec /usr/local/bin/drukbox-entrypoint
26 changes: 26 additions & 0 deletions deploy/browser/goss.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The boot contract of the browser image: the drukbox base entrypoint seeds
# the ``druks`` user this image adds, and the display stack is up on loopback.
# dgoss checks it in CI with DRUKBOX_SSH_USER=druks and
# DRUKBOX_AUTHORIZED_KEY="ssh-ed25519 AAAA goss".
file:
/home/druks/.ssh/authorized_keys:
exists: true
mode: "0600"
owner: druks
group: druks
contents:
- ssh-ed25519 AAAA goss
process:
sshd:
running: true
Xvfb:
running: true
x11vnc:
running: true
port:
tcp:22:
listening: true
tcp:5900:
listening: true
ip:
- 127.0.0.1
Loading