diff --git a/scripts/src/deploy.ts b/scripts/src/deploy.ts index c6eb9ebf..036ca32c 100644 --- a/scripts/src/deploy.ts +++ b/scripts/src/deploy.ts @@ -200,6 +200,12 @@ function candidateRepoUrls(repo: string): string[] { return [...new Set(urls)]; } +function providerSourceRepoUrl(repo: string): string { + const slug = repoSlug(repo); + if (slug === null || !slug.startsWith("github.com/")) return repo; + return sshUrlForSlug(slug) ?? repo; +} + function localResolvedCommitForDesired(desired: DeployManifestService): string | null { const desiredSlug = repoSlug(desired.repo); if (desiredSlug === null || desired.commitId.length !== 40) return null; @@ -453,6 +459,69 @@ function sourceProxyPrelude(service: UniDeskMicroserviceConfig): string { `build_proxy=${shellQuote(providerGatewayWsEgressProxyUrl)}`, "export HTTP_PROXY=\"$build_proxy\" HTTPS_PROXY=\"$build_proxy\" ALL_PROXY=\"$build_proxy\"", "export NO_PROXY=\"localhost,127.0.0.1,::1,host.docker.internal\"", + "git_ssh_proxy=/tmp/unidesk-git-ssh-http-connect.py", + "cat > \"$git_ssh_proxy\" <<'UNIDESK_GIT_SSH_PROXY'", + String.raw`#!/usr/bin/env python3 +import os +import select +import socket +import sys +from urllib.parse import urlparse + +if len(sys.argv) != 3: + raise SystemExit("usage: unidesk-git-ssh-http-connect.py host port") + +target_host = sys.argv[1] +target_port = int(sys.argv[2]) +proxy = urlparse(os.environ.get("UNIDESK_GIT_SSH_HTTP_PROXY", "http://127.0.0.1:18789")) +proxy_host = proxy.hostname or "127.0.0.1" +proxy_port = proxy.port or 80 + +sock = socket.create_connection((proxy_host, proxy_port), timeout=20) +sock.sendall(f"CONNECT {target_host}:{target_port} HTTP/1.1\r\nHost: {target_host}:{target_port}\r\n\r\n".encode("ascii")) +header = b"" +while b"\r\n\r\n" not in header: + chunk = sock.recv(4096) + if not chunk: + raise SystemExit("proxy closed before CONNECT response") + header += chunk +head, rest = header.split(b"\r\n\r\n", 1) +if not (head.startswith(b"HTTP/1.1 200") or head.startswith(b"HTTP/1.0 200")): + sys.stderr.write(head.decode("latin1", "replace") + "\n") + raise SystemExit(1) +if rest: + os.write(1, rest) + +stdin_open = True +sock.setblocking(False) +while True: + readers = [sock] + if stdin_open: + readers.append(sys.stdin.buffer) + ready, _, _ = select.select(readers, [], []) + if sock in ready: + try: + data = sock.recv(65536) + except BlockingIOError: + data = b"" + if not data: + break + os.write(1, data) + if stdin_open and sys.stdin.buffer in ready: + data = os.read(0, 65536) + if data: + sock.sendall(data) + else: + stdin_open = False + try: + sock.shutdown(socket.SHUT_WR) + except OSError: + pass +`, + "UNIDESK_GIT_SSH_PROXY", + "chmod 700 \"$git_ssh_proxy\"", + "export UNIDESK_GIT_SSH_HTTP_PROXY=\"$build_proxy\"", + "export GIT_SSH_COMMAND=\"ssh -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts -i $HOME/.ssh/id_ed25519 -o 'ProxyCommand=$git_ssh_proxy %h %p'\"", "curl -fsSI --max-time 20 -x \"$build_proxy\" https://github.com >/dev/null", "echo target_source_proxy=provider-gateway-ws-egress:$build_proxy", "echo target_build_proxy=provider-gateway-ws-egress:$build_proxy", @@ -491,7 +560,7 @@ function prepareSourceScript(service: UniDeskMicroserviceConfig, desired: Deploy "set -euo pipefail", sourceProxyPrelude(service), `repo=${shellQuote(targetRepoDir(service))}`, - `repo_url=${shellQuote(desired.repo)}`, + `repo_url=${shellQuote(providerSourceRepoUrl(desired.repo))}`, `commit=${shellQuote(desired.commitId)}`, `export_dir=${shellQuote(exportDir)}`, "mkdir -p \"$(dirname \"$repo\")\" \"$(dirname \"$export_dir\")\"",