* build: use dynamic local tunnels for ssh debugging Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * weeee Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com> * that'll do Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com> * chore: pretty output Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com> * build: allow ssh input Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
146 lines
4.6 KiB
Bash
Executable file
146 lines
4.6 KiB
Bash
Executable file
#!/bin/bash -e
|
|
|
|
if [ "${TUNNEL}" != "true" ]; then
|
|
echo "SSH tunneling is disabled. Set enable-tunnel: true to enable remote access."
|
|
echo "Local SSH server would be available on localhost:2222 if this were a local environment."
|
|
exit 0
|
|
fi
|
|
|
|
echo ::group::Configuring Tunnel
|
|
|
|
echo "SSH tunneling enabled. Setting up remote access..."
|
|
|
|
EXTERNAL_DEPS="curl jq ssh-keygen"
|
|
|
|
for dep in $EXTERNAL_DEPS; do
|
|
if ! command -v "${dep}" > /dev/null 2>&1; then
|
|
echo "Command ${dep} not installed on the system!" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
cd "$GITHUB_ACTION_PATH"
|
|
|
|
bashrc_path=$(pwd)/bashrc
|
|
|
|
# Source `bashrc` to auto start tmux on SSH login.
|
|
if ! grep -q "${bashrc_path}" ~/.bash_profile; then
|
|
echo >> ~/.bash_profile # On macOS runner there's no newline at the end of the file
|
|
echo "source \"${bashrc_path}\"" >> ~/.bash_profile
|
|
fi
|
|
|
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
ARCH=$(uname -m)
|
|
|
|
if [ "${ARCH}" = "x86_64" ]; then
|
|
ARCH="amd64"
|
|
elif [ "${ARCH}" = "aarch64" ]; then
|
|
ARCH="arm64"
|
|
fi
|
|
|
|
if [ "${OS}" = "darwin" ] && ! command -v tmux > /dev/null 2>&1; then
|
|
echo "Installing tmux..."
|
|
brew install tmux
|
|
fi
|
|
|
|
if [ "$OS" = "darwin" ]; then
|
|
cloudflared_url="https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-${OS}-${ARCH}.tgz"
|
|
echo "Downloading \`cloudflared\` from <$cloudflared_url>..."
|
|
curl --location --silent --output cloudflared.tgz "${cloudflared_url}"
|
|
tar xf cloudflared.tgz
|
|
rm cloudflared.tgz
|
|
fi
|
|
|
|
chmod +x cloudflared
|
|
|
|
echo 'Creating SSH server key...'
|
|
ssh-keygen -q -f ssh_host_rsa_key -N ''
|
|
|
|
echo 'Creating SSH server config...'
|
|
sed "s,\$PWD,${PWD},;s,\$USER,${USER}," sshd_config.template > sshd_config
|
|
|
|
echo 'Starting SSH server...'
|
|
sudo /usr/sbin/sshd -f sshd_config -D &
|
|
sshd_pid=$!
|
|
|
|
echo "SSH server started successfully (PID: ${sshd_pid})"
|
|
|
|
echo 'Starting tmux session...'
|
|
(cd "${GITHUB_WORKSPACE}" && tmux new-session -d -s debug)
|
|
|
|
mkdir ~/.cloudflared
|
|
CLEAN_TUNNEL_CERT=$(printf '%s\n' "${CLOUDFLARE_TUNNEL_CERT}" | tr -d '\r' | sed '/^[[:space:]]*$/d')
|
|
|
|
echo "${CLEAN_TUNNEL_CERT}" > ~/.cloudflared/cert.pem
|
|
|
|
CLEAN_USER_CA_CERT=$(printf '%s\n' "${CLOUDFLARE_USER_CA_CERT}" | tr -d '\r' | sed '/^[[:space:]]*$/d')
|
|
|
|
echo "${CLEAN_USER_CA_CERT}" | sudo tee /etc/ssh/ca.pub > /dev/null
|
|
sudo chmod 644 /etc/ssh/ca.pub
|
|
|
|
random_suffix=$(openssl rand -hex 5 | cut -c1-10)
|
|
tunnel_name="${GITHUB_SHA}-${GITHUB_RUN_ID}-${random_suffix}"
|
|
tunnel_url="${tunnel_name}.${CLOUDFLARE_TUNNEL_HOSTNAME}"
|
|
|
|
if ./cloudflared tunnel list | grep -q "${tunnel_name}"; then
|
|
echo "Deleting existing tunnel: ${tunnel_name}"
|
|
./cloudflared tunnel delete ${tunnel_name}
|
|
fi
|
|
|
|
echo "Creating new cloudflare tunnel: ${tunnel_name}"
|
|
./cloudflared tunnel create ${tunnel_name}
|
|
|
|
credentials_file=$(find ~/.cloudflared -name "*.json" | head -n 1)
|
|
if [ -z "${credentials_file}" ]; then
|
|
echo "Error: Could not find tunnel credentials file"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Found credentials file: ${credentials_file}"
|
|
|
|
echo 'Creating tunnel configuration...'
|
|
cat > tunnel_config.yml << EOF
|
|
tunnel: ${tunnel_name}
|
|
credentials-file: ${credentials_file}
|
|
|
|
ingress:
|
|
- hostname: ${tunnel_url}
|
|
service: ssh://localhost:2222
|
|
- service: http_status:404
|
|
EOF
|
|
|
|
echo 'Setting up DNS routing for tunnel...'
|
|
./cloudflared tunnel route dns ${tunnel_name} ${tunnel_url}
|
|
|
|
echo 'Running cloudflare tunnel...'
|
|
./cloudflared tunnel --no-autoupdate --config tunnel_config.yml run 2>&1 | tee cloudflared.log | sed -u 's/^/cloudflared: /' &
|
|
cloudflared_pid=$!
|
|
|
|
echo ::endgroup::
|
|
|
|
echo ::notice title=SSH Debug Session Ready::ssh ${tunnel_url}
|
|
|
|
|
|
(
|
|
echo ' '
|
|
echo ' '
|
|
echo '🔗 SSH Debug Session Ready!'
|
|
echo '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'
|
|
echo ' '
|
|
echo '📋 Infra WG can copy and run this command to connect:'
|
|
echo ' '
|
|
echo "ssh ${tunnel_url}"
|
|
echo ' '
|
|
echo "⏰ Session expires automatically in ${TIMEOUT} seconds"
|
|
echo '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'
|
|
echo ' '
|
|
echo ' '
|
|
) | cat
|
|
|
|
echo ::group::Starting Background Session
|
|
echo 'Starting SSH session in background...'
|
|
./ssh-session.sh "${sshd_pid}" "${cloudflared_pid}" "${TIMEOUT}" "${tunnel_name}" &
|
|
|
|
echo 'SSH session is running in background. GitHub Action will continue.'
|
|
echo 'Session will auto-cleanup after timeout or when processes end.'
|
|
echo ::endgroup::
|