Skip to content

Commit a1ecf65

Browse files
committed
add python script for running novnc
1 parent f206e36 commit a1ecf65

6 files changed

Lines changed: 654 additions & 19 deletions

File tree

‎README.md‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ Build the Debian 12 desktop image with:
1818
podman-hpc build -f container/debian-12-vnc-novnc.Dockerfile -t ghcr.io/dingp/debian:12-vnc-novnc .
1919
```
2020

21-
Run it with the helper script:
21+
Run it with a helper script:
2222

2323
```sh
24-
scripts/run-vnc-novnc.sh
24+
scripts/run-vnc-novnc.py
2525
```
2626

27-
The helper generates a one-time VNC password, chooses a random localhost noVNC port, and does not expose the VNC server port by default. It prints the noVNC URL and password before starting the container.
27+
Run it with the default NERSC-oriented YAML config:
28+
29+
```sh
30+
scripts/run-vnc-novnc.py --config scripts/run-vnc-novnc.yaml
31+
```
32+
33+
The helper generates a one-time VNC password, chooses a random localhost noVNC port, and does not expose the VNC server port by default. It prints the noVNC URL and password before starting the container. A shell version is also available at `scripts/run-vnc-novnc.sh`.
2834

2935
See [RUN_VNC_NOVNC.md](RUN_VNC_NOVNC.md) for full usage details.
3036

‎RUN_VNC_NOVNC.md‎

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Using `run-vnc-novnc.sh`
1+
# Using the VNC/noVNC Helpers
22

3-
`scripts/run-vnc-novnc.sh` starts the Debian 12 VNC/noVNC desktop image with safer defaults for interactive use on NERSC systems, especially from Jupyter.
3+
`scripts/run-vnc-novnc.sh` and `scripts/run-vnc-novnc.py` start the Debian 12 VNC/noVNC desktop image with safer defaults for interactive use on NERSC systems, especially from Jupyter. The Python helper has the same default behavior as the shell helper and adds command-line options for bind mounts, environment passthrough, user namespace settings, and extra `podman-hpc` arguments.
44

55
## What It Does
66

@@ -23,7 +23,13 @@ Inside the container, the VNC server listens on `VNC_PORT` and noVNC listens on
2323
From the repository root:
2424

2525
```sh
26-
scripts/run-vnc-novnc.sh
26+
scripts/run-vnc-novnc.py
27+
```
28+
29+
To use the default NERSC-oriented YAML config:
30+
31+
```sh
32+
scripts/run-vnc-novnc.py --config scripts/run-vnc-novnc.yaml
2733
```
2834

2935
The script prints output like:
@@ -56,15 +62,35 @@ https://jupyter.nersc.gov/user/your-user-name/muller-login-node-base/proxy/49967
5662
If the helper is not running inside Jupyter, provide the server path explicitly:
5763

5864
```sh
59-
JUPYTER_PROXY_USER="${USER}" \
60-
JUPYTER_PROXY_SERVER=perlmutter-login-node \
61-
scripts/run-vnc-novnc.sh
65+
scripts/run-vnc-novnc.py --jupyter-proxy-server perlmutter-login-node
6266
```
6367

6468
The server name is the Jupyter server type, such as `muller-login-node-base` or `perlmutter-login-node`.
6569

6670
## Configuration
6771

72+
The Python helper can read defaults from a YAML config file:
73+
74+
```sh
75+
scripts/run-vnc-novnc.py --config scripts/run-vnc-novnc.yaml
76+
```
77+
78+
The included `scripts/run-vnc-novnc.yaml` uses `--userns=keep-id`, `--group-add=keep-groups`, and bind mounts `$HOME`, `$SCRATCH`, and `$CFS` into the same paths inside the container. Environment variables in YAML strings are expanded on the host when the script starts.
79+
80+
YAML keys use the long option names with underscores instead of dashes. For example:
81+
82+
```yaml
83+
userns: keep-id
84+
keep_groups: true
85+
86+
volume:
87+
- "${HOME}:${HOME}:rw"
88+
- "${SCRATCH}:${SCRATCH}:rw"
89+
- "${CFS}:${CFS}:rw"
90+
```
91+
92+
Precedence is: built-in defaults, YAML config, environment variables, then command-line arguments. Repeated list options such as `volume`, `mount`, `env`, `group_add`, and `extra_podman_args` are initialized from YAML, and additional command-line occurrences are appended.
93+
6894
Common settings:
6995

7096
| Variable | Default | Purpose |
@@ -77,6 +103,21 @@ Common settings:
77103
| `EXPOSE_VNC` | `0` | Set to `1` to also publish the raw VNC server port. |
78104
| `VNC_PASSWORD_LENGTH` | `8` | Length of the generated one-time VNC password. |
79105

106+
Python helper container options:
107+
108+
| Option | Purpose |
109+
| --- | --- |
110+
| `-v`, `--volume HOST:CONTAINER[:OPTIONS]` | Add a bind mount or volume spec. May be repeated. |
111+
| `--mount SPEC` | Add a Podman `--mount` spec. May be repeated. |
112+
| `-e`, `--env NAME[=VALUE]` | Pass an environment variable into the container. May be repeated. |
113+
| `--config FILE` | Read default values from a YAML config file. |
114+
| `--userns=keep-id` | Pass `--userns=keep-id` to `podman-hpc`. |
115+
| `--userns-keep-id` | Shorthand for `--userns=keep-id`. |
116+
| `--group-add=keep-groups` | Pass `--group-add=keep-groups` to `podman-hpc`. |
117+
| `--keep-groups` | Shorthand for `--group-add=keep-groups`. |
118+
| `--dry-run` | Print the generated command without running the container. |
119+
| `--` | Pass following arguments directly to `podman-hpc run` before the image name. |
120+
80121
Jupyter URL settings:
81122

82123
| Variable | Default | Purpose |
@@ -100,33 +141,69 @@ Raw VNC exposure settings:
100141
Use a fixed noVNC host port:
101142

102143
```sh
103-
HOST_NOVNC_PORT=49967 scripts/run-vnc-novnc.sh
144+
scripts/run-vnc-novnc.py --host-novnc-port 49967
104145
```
105146

106147
Use a locally built image:
107148

108149
```sh
109-
IMAGE=localhost/debugging-container-vnc-novnc:latest scripts/run-vnc-novnc.sh
150+
scripts/run-vnc-novnc.py --image localhost/debugging-container-vnc-novnc:latest
110151
```
111152

112153
Run outside Jupyter but still print a Jupyter proxy URL:
113154

114155
```sh
115-
JUPYTER_PROXY_USER="${USER}" \
116-
JUPYTER_PROXY_SERVER=muller-login-node-base \
117-
scripts/run-vnc-novnc.sh
156+
scripts/run-vnc-novnc.py --jupyter-proxy-server muller-login-node-base
118157
```
119158

120159
Expose the raw VNC server port in addition to noVNC:
121160

122161
```sh
123-
EXPOSE_VNC=1 scripts/run-vnc-novnc.sh
162+
scripts/run-vnc-novnc.py --expose-vnc
124163
```
125164

126165
Use a custom raw VNC host port:
127166

128167
```sh
129-
EXPOSE_VNC=1 VNC_HOST_PORT=5905 scripts/run-vnc-novnc.sh
168+
scripts/run-vnc-novnc.py --expose-vnc --vnc-host-port 5905
169+
```
170+
171+
Mount host directories into the container:
172+
173+
```sh
174+
scripts/run-vnc-novnc.py \
175+
-v "${HOME}:${HOME}:rw" \
176+
-v "${SCRATCH}:${SCRATCH}:rw"
177+
```
178+
179+
Use the included YAML config for common NERSC mounts and identity handling:
180+
181+
```sh
182+
scripts/run-vnc-novnc.py --config scripts/run-vnc-novnc.yaml
183+
```
184+
185+
Run with host identity/group handling:
186+
187+
```sh
188+
scripts/run-vnc-novnc.py --userns=keep-id --group-add=keep-groups
189+
```
190+
191+
The shorthand form is equivalent:
192+
193+
```sh
194+
scripts/run-vnc-novnc.py --userns-keep-id --keep-groups
195+
```
196+
197+
Pass environment variables into the container:
198+
199+
```sh
200+
scripts/run-vnc-novnc.py -e NERSC_HOST -e MY_SETTING=value
201+
```
202+
203+
Pass extra `podman-hpc run` arguments:
204+
205+
```sh
206+
scripts/run-vnc-novnc.py -- --ipc=host
130207
```
131208

132209
## Security Notes

‎container/debian-12-vnc-novnc.Dockerfile‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ RUN \
4040
curl --fail --location --show-error "${SSHPROXY_URL}" --output /tmp/sshproxy.tar.gz && \
4141
tar -xzf /tmp/sshproxy.tar.gz -C /usr/local/bin sshproxy && \
4242
chmod 0755 /usr/local/bin/sshproxy && \
43-
mkdir -p /root/.fvwm && \
43+
mkdir -p /etc/vnc-novnc /root/.fvwm && \
4444
apt-get clean && \
4545
rm -rf /var/lib/apt/lists/* /tmp/sshproxy.tar.gz
4646

4747
COPY container/vnc/vnc-novnc-entrypoint /usr/local/bin/vnc-novnc-entrypoint
48+
COPY container/vnc/fvwm3-config /etc/vnc-novnc/fvwm3-config
4849
COPY container/vnc/fvwm3-config /root/.fvwm/config
4950

5051
RUN \

‎container/vnc/vnc-novnc-entrypoint‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,37 @@ vnc_port="${VNC_PORT}"
3030
novnc_vnc_port="${NOVNC_VNC_PORT:-$vnc_port}"
3131
vnc_localhost="$(normalize_bool "${VNC_LOCALHOST}")"
3232

33-
mkdir -p /root/.vnc /root/.fvwm
34-
chmod 700 /root/.vnc
33+
ensure_writable_dir() {
34+
local dir="$1"
35+
mkdir -p "${dir}" >/dev/null 2>&1 && [[ -w "${dir}" ]]
36+
}
37+
38+
runtime_home="${VNC_RUNTIME_HOME:-${HOME:-/root}}"
39+
if ! ensure_writable_dir "${runtime_home}"; then
40+
runtime_home="/tmp/vnc-home-$(id -u)"
41+
if ! ensure_writable_dir "${runtime_home}"; then
42+
printf 'Unable to create writable VNC runtime home: %s\n' "${runtime_home}" >&2
43+
exit 1
44+
fi
45+
fi
46+
47+
export HOME="${runtime_home}"
48+
vnc_dir="${HOME}/.vnc"
49+
fvwm_dir="${HOME}/.fvwm"
50+
mkdir -p "${vnc_dir}" "${fvwm_dir}"
51+
chmod 700 "${vnc_dir}"
52+
53+
if [[ "${VNC_PASSWORD_FILE}" == "/root/.vnc/passwd" && ! -w "/root" ]]; then
54+
VNC_PASSWORD_FILE="${vnc_dir}/passwd"
55+
fi
56+
57+
if [[ "${VNC_XSTARTUP}" == "/root/.vnc/xstartup" && ! -w "/root" ]]; then
58+
VNC_XSTARTUP="${vnc_dir}/xstartup"
59+
fi
60+
61+
if [[ ! -e "${fvwm_dir}/config" && -r /etc/vnc-novnc/fvwm3-config ]]; then
62+
cp /etc/vnc-novnc/fvwm3-config "${fvwm_dir}/config"
63+
fi
3564

3665
if [[ ! -x "${VNC_XSTARTUP}" ]]; then
3766
cat > "${VNC_XSTARTUP}" <<'EOF'

0 commit comments

Comments
 (0)