Skip to content

Commit a2a1ad6

Browse files
committed
Update sandcat
1 parent ec25c5e commit a2a1ad6

3 files changed

Lines changed: 34 additions & 55 deletions

File tree

.devcontainer/Dockerfile.app

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ RUN mise use -g node@lts \
2323
RUN mise use -g java@21
2424
RUN mise use -g sbt
2525

26+
# If Java was installed above, bake JAVA_HOME and JAVA_TOOL_OPTIONS into
27+
# .bashrc so VS Code's env probe picks them up before the entrypoint runs.
28+
# Without JAVA_HOME, JVM tooling like Metals fails to find the JDK.
29+
# JAVA_TOOL_OPTIONS points to a trust store copy that the entrypoint will
30+
# populate with the mitmproxy CA at runtime; until then it holds the default
31+
# Java CAs (harmless — equivalent to not setting it at all).
32+
# A version-independent symlink is used so .bashrc doesn't need updating
33+
# when the Java version changes — only the symlink target is updated.
34+
RUN if MISE_JAVA=$(mise where java 2>/dev/null); then \
35+
dir="$HOME/.local/share/sandcat"; mkdir -p "$dir"; \
36+
ln -sfn "$MISE_JAVA" "$dir/java-home"; \
37+
cp "$MISE_JAVA/lib/security/cacerts" "$dir/cacerts" 2>/dev/null || true; \
38+
{ echo ''; \
39+
echo '# sandcat-java-env'; \
40+
echo '[ -L "$HOME/.local/share/sandcat/java-home" ] && export JAVA_HOME="$HOME/.local/share/sandcat/java-home"'; \
41+
echo '[ -f "$HOME/.local/share/sandcat/cacerts" ] && export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=$HOME/.local/share/sandcat/cacerts -Djavax.net.ssl.trustStorePassword=changeit"'; \
42+
} >> "$HOME/.bashrc"; \
43+
fi
44+
2645
# Pre-create the Claude config directory and seed onboarding flag so Claude
2746
# Code can use an API key from the environment without interactive setup.
2847
RUN mkdir -p /home/vscode/.claude \

.devcontainer/sandcat/scripts/app-init.sh

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
#!/bin/bash
22
#
33
# Entrypoint for containers that share the wg-client's network namespace.
4-
# Installs the mitmproxy CA cert, loads env vars and secret placeholders
5-
# from sandcat.env, then hands off to the container's main command.
4+
# Installs the mitmproxy CA cert, disables commit signing, loads env vars
5+
# and secret placeholders from sandcat.env, runs vscode-user setup (git
6+
# identity, Java trust store, Claude Code update), then drops to vscode
7+
# and exec's the container's main command.
68
#
79
set -e
810

911
CA_CERT="/mitmproxy-config/mitmproxy-ca-cert.pem"
1012

11-
# The CA cert should already exist (wg-client depends_on mitmproxy healthy),
12-
# but wait briefly in case of a slight race on the shared volume.
13-
elapsed=0
14-
while [ ! -f "$CA_CERT" ]; do
15-
if [ "$elapsed" -ge 30 ]; then
16-
echo "Timed out waiting for mitmproxy CA cert" >&2
17-
exit 1
18-
fi
19-
sleep 1
20-
elapsed=$((elapsed + 1))
21-
done
13+
# The CA cert is guaranteed to exist: app depends_on wg-client (healthy),
14+
# which depends_on mitmproxy (healthy), whose healthcheck requires the
15+
# WireGuard config — generated after the CA.
16+
if [ ! -f "$CA_CERT" ]; then
17+
echo "mitmproxy CA cert not found at $CA_CERT" >&2
18+
exit 1
19+
fi
2220

2321
cp "$CA_CERT" /usr/local/share/ca-certificates/mitmproxy.crt
2422
update-ca-certificates
@@ -55,24 +53,9 @@ else
5553
echo "No $SANDCAT_ENV found — env vars and secret substitution disabled"
5654
fi
5755

58-
# Run vscode-user tasks: git identity and Claude Code update.
56+
# Run vscode-user tasks: git identity, Java trust store, Claude Code update.
5957
su - vscode -c /usr/local/bin/app-user-init.sh
6058

61-
# If app-user-init.sh set up Java (symlink + trust store), export JAVA_HOME
62-
# and JAVA_TOOL_OPTIONS for shells and child processes of PID 1.
63-
SANDCAT_JAVA_HOME="/home/vscode/.local/share/sandcat/java-home"
64-
if [ -L "$SANDCAT_JAVA_HOME" ]; then
65-
export JAVA_HOME="$SANDCAT_JAVA_HOME"
66-
echo "export JAVA_HOME=\"$SANDCAT_JAVA_HOME\"" > /etc/profile.d/sandcat-java.sh
67-
fi
68-
if [ -f /tmp/sandcat-java-cacerts-path ]; then
69-
SANDCAT_CACERTS=$(cat /tmp/sandcat-java-cacerts-path)
70-
JAVA_TRUST_OPTS="-Djavax.net.ssl.trustStore=$SANDCAT_CACERTS -Djavax.net.ssl.trustStorePassword=changeit"
71-
export JAVA_TOOL_OPTIONS="$JAVA_TRUST_OPTS"
72-
echo "export JAVA_TOOL_OPTIONS=\"$JAVA_TRUST_OPTS\"" >> /etc/profile.d/sandcat-java.sh
73-
rm -f /tmp/sandcat-java-cacerts-path
74-
fi
75-
7659
# Source all sandcat profile.d scripts from /etc/bash.bashrc so env vars
7760
# are available in non-login shells (e.g. VS Code integrated terminals).
7861
# Guard with a marker to avoid duplicating on container restart.

.devcontainer/sandcat/scripts/app-user-init.sh

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ git config --global commit.gpgsign false
2323
# store. Java uses its own cacerts and ignores the system CA store.
2424
CA_CERT="/mitmproxy-config/mitmproxy-ca-cert.pem"
2525

26-
# Ensure mise is on PATH. `su - vscode` resets the environment and sources
26+
# Ensure mise is on PATH. `su - vscode` resets the environment and sources
2727
# only the first of ~/.bash_profile, ~/.bash_login, ~/.profile. If
2828
# ~/.bash_profile exists (e.g. created by VS Code on a persistent volume),
2929
# ~/.profile — where the Dockerfile adds mise — is never read.
@@ -33,8 +33,8 @@ fi
3333

3434
MISE_JAVA_HOME="$(mise where java 2>/dev/null || true)"
3535
if [ -n "$MISE_JAVA_HOME" ] && [ -f "$CA_CERT" ]; then
36-
# Create a version-independent symlink so JAVA_HOME (exported via
37-
# /etc/profile.d/) doesn't depend on the mise Java version.
36+
# Create a version-independent symlink so JAVA_HOME doesn't depend
37+
# on the mise Java version.
3838
SANDCAT_DIR="$HOME/.local/share/sandcat"
3939
mkdir -p "$SANDCAT_DIR"
4040
ln -sfn "$MISE_JAVA_HOME" "$SANDCAT_DIR/java-home"
@@ -69,30 +69,7 @@ if [ -n "$MISE_JAVA_HOME" ] && [ -f "$CA_CERT" ]; then
6969
}
7070
}
7171
EOFJSON
72-
fi
73-
74-
# Signal to app-init.sh (which runs as root) where the cacerts copy is,
75-
# so it can set JAVA_TOOL_OPTIONS. Written on every start since /tmp
76-
# is cleared on container restart.
77-
if [ -f "$SANDCAT_CACERTS" ]; then
78-
echo "$SANDCAT_CACERTS" > /tmp/sandcat-java-cacerts-path
79-
fi
80-
81-
# Write Java env vars to ~/.bashrc (on the persistent app-home volume)
82-
# so VS Code's userEnvProbe picks them up even after container rebuild.
83-
# /etc/profile.d/ is ephemeral and works for shells, but VS Code may
84-
# probe the environment before the entrypoint recreates those files.
85-
BASHRC_JAVA_MARKER="# sandcat-java-env"
86-
if ! grep -q "$BASHRC_JAVA_MARKER" "$HOME/.bashrc" 2>/dev/null; then
87-
cat >> "$HOME/.bashrc" << 'BASHRC_JAVA'
8872

89-
# sandcat-java-env
90-
_sc_java="$HOME/.local/share/sandcat/java-home"
91-
_sc_cacerts="$HOME/.local/share/sandcat/cacerts"
92-
[ -L "$_sc_java" ] && export JAVA_HOME="$_sc_java"
93-
[ -f "$_sc_cacerts" ] && export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=$_sc_cacerts -Djavax.net.ssl.trustStorePassword=changeit"
94-
unset _sc_java _sc_cacerts
95-
BASHRC_JAVA
9673
fi
9774
fi
9875

0 commit comments

Comments
 (0)