feat(release): stage GitWorkshop and next node updates
This commit is contained in:
@@ -6,7 +6,7 @@ After=archipelago.service
|
||||
Type=oneshot
|
||||
# Runs as root: needs to kill orphaned conmon processes, fix permissions
|
||||
User=root
|
||||
ExecStart=/home/archipelago/archy/scripts/container-doctor.sh --local
|
||||
ExecStart=/opt/archipelago/scripts/container-doctor.sh --local
|
||||
TimeoutStartSec=300
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
# Install the exact ngit runtime validated for Archipelago source hosting.
|
||||
#
|
||||
# The GitHub release archive contains both `ngit` and `git-remote-nostr`.
|
||||
# Keep version, filenames, and SHA-256 values together so image builds and
|
||||
# OTA updates cannot silently resolve a newer upstream release.
|
||||
|
||||
set -eu
|
||||
|
||||
NGIT_VERSION="2.6.3"
|
||||
NGIT_RELEASE_BASE="https://github.com/DanConwayDev/ngit-cli/releases/download/v${NGIT_VERSION}"
|
||||
X86_64_ASSET="ngit-v${NGIT_VERSION}-x86_64-unknown-linux-gnu.2.17.tar.gz"
|
||||
X86_64_SHA256="81dd9b6a11a4a0feb946e56f55d557dc24075f1dcdda00ac35f9fd01920b9779"
|
||||
AARCH64_ASSET="ngit-v${NGIT_VERSION}-aarch64-unknown-linux-gnu.2.17.tar.gz"
|
||||
AARCH64_SHA256="e9d9437b7574e729b5a5d5cd800ebd668b73e6eb5c5859d52f83114c2f4b08b8"
|
||||
|
||||
install_root="${ARCHIPELAGO_NGIT_INSTALL_ROOT:-}"
|
||||
case "$install_root" in
|
||||
""|/*) ;;
|
||||
*)
|
||||
echo "ARCHIPELAGO_NGIT_INSTALL_ROOT must be empty or absolute" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
install_dir="${install_root}/usr/bin"
|
||||
ngit_bin="${install_dir}/ngit"
|
||||
helper_bin="${install_dir}/git-remote-nostr"
|
||||
|
||||
if [ -x "$ngit_bin" ] && [ -x "$helper_bin" ] && \
|
||||
[ "$($ngit_bin --version 2>/dev/null || true)" = "ngit ${NGIT_VERSION}" ] && \
|
||||
[ "$($helper_bin --version 2>/dev/null || true)" = "v${NGIT_VERSION}" ]; then
|
||||
echo "ngit ${NGIT_VERSION} already installed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
machine="${ARCHIPELAGO_NGIT_ARCH:-$(uname -m)}"
|
||||
case "$machine" in
|
||||
x86_64|amd64)
|
||||
asset="$X86_64_ASSET"
|
||||
expected_sha256="$X86_64_SHA256"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
asset="$AARCH64_ASSET"
|
||||
expected_sha256="$AARCH64_SHA256"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported ngit architecture: $machine" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
download_dir=$(mktemp -d -t archipelago-ngit.XXXXXX)
|
||||
cleanup() {
|
||||
rm -rf -- "$download_dir"
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
archive="$download_dir/$asset"
|
||||
curl --fail --silent --show-error --location \
|
||||
--proto '=https' --tlsv1.2 \
|
||||
--retry 3 --connect-timeout 20 \
|
||||
--output "$archive" "$NGIT_RELEASE_BASE/$asset"
|
||||
|
||||
actual_sha256=$(sha256sum "$archive" | awk '{print $1}')
|
||||
if [ "$actual_sha256" != "$expected_sha256" ]; then
|
||||
echo "ngit archive checksum mismatch for $asset" >&2
|
||||
echo "expected: $expected_sha256" >&2
|
||||
echo "actual: $actual_sha256" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract only the two expected top-level files. Unexpected archive content is
|
||||
# never copied into the host filesystem.
|
||||
tar -xzf "$archive" -C "$download_dir" ngit git-remote-nostr
|
||||
mkdir -p "$install_dir"
|
||||
install -m 0755 "$download_dir/ngit" "$ngit_bin"
|
||||
install -m 0755 "$download_dir/git-remote-nostr" "$helper_bin"
|
||||
|
||||
[ "$($ngit_bin --version)" = "ngit ${NGIT_VERSION}" ]
|
||||
[ "$($helper_bin --version)" = "v${NGIT_VERSION}" ]
|
||||
echo "installed ngit ${NGIT_VERSION} for $machine"
|
||||
@@ -52,6 +52,17 @@ server {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Dashboard-origin Nostr signer for apps opened as their own browser tab or
|
||||
# companion WebView. This document alone may be framed by another port on
|
||||
# the same node; signing RPCs still require an authenticated node session.
|
||||
location = /nostr-signer {
|
||||
try_files /index.html =404;
|
||||
add_header Cache-Control "no-store" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self' http://$host:* https://$host:*; base-uri 'none'; form-action 'none';" always;
|
||||
}
|
||||
|
||||
# AIUI SPA (Chat mode iframe) — SPA fallback for client-side routing
|
||||
#
|
||||
# /aiui/-scoped CSP (AIUI-04, D-19 unaffected — this is a build-time/
|
||||
@@ -691,13 +702,32 @@ server {
|
||||
sub_filter "src='/" "src='/app/botfights/";
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script><script>window.addEventListener("message",function(e){var d=e.data;if(d&&d.type==="arcade-input"&&d.key){var t=d.action==="up"?"keyup":"keydown";document.dispatchEvent(new KeyboardEvent(t,{key:d.key,bubbles:true}))}})</script></head>';
|
||||
}
|
||||
# GitWorkshop follows the dashboard origin so every supported ingress
|
||||
# works without separately publishing an app port. The app gate on
|
||||
# 127.0.0.2 preserves session authentication before forwarding to the
|
||||
# loopback-only container.
|
||||
location /app/archipelago-source/ {
|
||||
proxy_pass http://127.0.0.2:8337/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Cookie $http_cookie;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Prefix /app/archipelago-source;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
location /app/gitea/ {
|
||||
proxy_pass http://127.0.0.1:3001/;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 1G;
|
||||
client_max_body_size 10G;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
# Override parent add_header to allow iframe embedding
|
||||
@@ -1037,6 +1067,16 @@ server {
|
||||
return 504 '{"error":{"code":"BACKEND_TIMEOUT","message":"Service did not respond in time"}}';
|
||||
}
|
||||
|
||||
# Dashboard-origin Nostr signer for apps opened as their own browser tab or
|
||||
# companion WebView. Keep this aligned with the HTTP server block.
|
||||
location = /nostr-signer {
|
||||
try_files /index.html =404;
|
||||
add_header Cache-Control "no-store" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self' http://$host:* https://$host:*; base-uri 'none'; form-action 'none';" always;
|
||||
}
|
||||
|
||||
# AIUI SPA (Chat mode iframe) — SPA fallback for client-side routing
|
||||
#
|
||||
# /aiui/-scoped CSP — see the HTTP server block above for the full
|
||||
@@ -1479,4 +1519,3 @@ server {
|
||||
proxy_read_timeout 86400s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +33,27 @@ location /app/uptime-kuma/ {
|
||||
sub_filter_once on;
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
||||
}
|
||||
# GitWorkshop follows the dashboard origin; the app gate keeps the route
|
||||
# session-authenticated before it reaches the loopback-only container.
|
||||
location /app/archipelago-source/ {
|
||||
proxy_pass http://127.0.0.2:8337/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Cookie $http_cookie;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Prefix /app/archipelago-source;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
location /app/gitea/ {
|
||||
proxy_pass http://127.0.0.1:3001/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_request_buffering off;
|
||||
client_max_body_size 10G;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
Reference in New Issue
Block a user