forked from warpdotdev/warp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy_remote_server_to_test_vm
More file actions
executable file
·206 lines (173 loc) · 7.97 KB
/
Copy pathdeploy_remote_server_to_test_vm
File metadata and controls
executable file
·206 lines (173 loc) · 7.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env bash
#
# Builds the Integration-channel Oz CLI for Linux x86_64 (musl) and uploads it
# to the SSH integration testing VM so that remote-server integration tests run
# against the binary built from the current branch.
#
# This script is intended to be run once by CI before the integration test
# suite, not by individual test functions. The binary is placed at the
# versioned Integration channel path on the remote host, which is where the
# Integration channel's `check_binary` looks.
#
# Prerequisites (same as script/deploy_remote_server):
# On Linux, install curl, sha256sum, tar, and sshpass.
# rustup target add x86_64-unknown-linux-musl
# gcloud CLI authenticated for the warp-ssh-integration-testing project
#
# Usage:
# script/deploy_remote_server_to_test_vm
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
TARGET="x86_64-unknown-linux-musl"
CARGO_PROFILE="dev-remote"
FEATURES="crash_reporting,standalone,agent_mode_debug,remote_codebase_indexing"
WARP_BIN="integration"
# The integration test runner uses Channel::Integration, which maps to
# cli_command_name() = "oz-integration", remote_server_dir() = "~/.warp-dev/remote-server",
# and remote_server_binary() = "oz-integration-${pinned_version}".
# See crates/warp_core/src/channel/mod.rs, crates/remote_server/src/setup.rs,
# and crates/integration/src/bin/integration.rs.
#
# We intentionally build app/src/bin/integration.rs instead of the normal
# Local-channel app binary. The Local-channel release bundle requires
# warp-channel-config to generate local_config.json at compile time, but this CI
# path should not depend on private channel config. The Integration-channel
# binary embeds a static non-secret config instead.
REMOTE_DIR=".warp-dev/remote-server"
# Dedicated remote-server test VM, configured similarly to the SSH integration
# test VM but isolated from the general SSH integration suite.
REMOTE_USERS=(bash zsh)
REMOTE_HOST="ssh-remote-server-testing"
REMOTE_PORT="22"
PROXY_COMMAND="gcloud compute start-iap-tunnel ssh-remote-server-testing ${REMOTE_PORT} --listen-on-stdin --project=warp-ssh-integration-testing --zone=us-east4-b"
app_version() {
if [[ -n "${GIT_RELEASE_TAG:-}" ]]; then
echo "$GIT_RELEASE_TAG"
return
fi
cargo metadata --no-deps --format-version 1 \
| python3 -c 'import json, sys; print(next(p["version"] for p in json.load(sys.stdin)["packages"] if p["name"] == "remote_server" and p["manifest_path"].endswith("/crates/remote_server/Cargo.toml")))'
}
# ── Preflight checks ──────────────────────────────────────────────
source "$SCRIPT_DIR/linux/configure_musl_toolchain" "$TARGET"
if ! rustup target list --installed 2>/dev/null | grep -q "$TARGET"; then
echo "Error: $TARGET target not installed." >&2
echo "Install it with: rustup target add $TARGET" >&2
exit 1
fi
BUNDLE_VERSION="$(app_version)"
BUNDLE_BINARY_NAME="oz-integration"
BINARY_NAME="$BUNDLE_BINARY_NAME-$BUNDLE_VERSION"
# ── Build ─────────────────────────────────────────────────────────
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORKSPACE_ROOT/target}"
OUTPUT_DIR="$CARGO_TARGET_DIR/$TARGET/$CARGO_PROFILE"
BUILT_BINARY="$OUTPUT_DIR/$WARP_BIN"
LOCAL_BUNDLE_DIR="$OUTPUT_DIR/remote-server-integration-bundle"
LOCAL_BUNDLE_TARBALL="$OUTPUT_DIR/remote-server-integration-bundle.tar.gz"
echo "==> Building Integration-channel Oz CLI for $TARGET (profile=$CARGO_PROFILE)"
cargo build \
-p warp \
--bin "$WARP_BIN" \
--target "$TARGET" \
--profile "$CARGO_PROFILE" \
--features "$FEATURES"
if [[ ! -f "$BUILT_BINARY" ]]; then
echo "Error: Expected binary not found at $BUILT_BINARY" >&2
exit 1
fi
BINARY_SIZE=$(du -h "$BUILT_BINARY" | cut -f1)
echo "==> Build complete ($BINARY_SIZE)"
rm -rf "$LOCAL_BUNDLE_DIR"
mkdir -p "$LOCAL_BUNDLE_DIR"
cp "$BUILT_BINARY" "$LOCAL_BUNDLE_DIR/$BUNDLE_BINARY_NAME"
"$WORKSPACE_ROOT/script/prepare_bundled_resources" \
"$LOCAL_BUNDLE_DIR/resources" \
integration \
"$CARGO_PROFILE"
tar -czf "$LOCAL_BUNDLE_TARBALL" -C "$LOCAL_BUNDLE_DIR" .
# ── Upload via SCP through GCP IAP tunnel ─────────────────────────
# The test VM uses password auth (same as the SSH integration tests).
# sshpass provides the password non-interactively for SSH/SCP.
SSH_PASSWORD="password"
SSH_OPTS=(-p "$REMOTE_PORT" -o "ProxyCommand=$PROXY_COMMAND" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null)
if command -v sshpass &>/dev/null; then
export SSHPASS="$SSH_PASSWORD"
SSH_CMD=(sshpass -e ssh)
SCP_CMD=(sshpass -e scp)
else
echo "Warning: sshpass not found, SSH/SCP will prompt for password interactively." >&2
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "Install it with: brew install hudochenkov/sshpass/sshpass" >&2
elif [[ "$(uname -s)" == "Linux" ]]; then
echo "Install it with: sudo apt-get install sshpass" >&2
fi
SSH_CMD=(ssh)
SCP_CMD=(scp)
fi
for REMOTE_USER in "${REMOTE_USERS[@]}"; do
echo "==> Ensuring remote directory exists for ${REMOTE_USER}"
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p ~/$REMOTE_DIR"
echo "==> Stopping stale remote server daemons for ${REMOTE_USER}"
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" "bash -s -- '$REMOTE_DIR'" <<'REMOTE_SCRIPT'
set -euo pipefail
REMOTE_ROOT="$HOME/$1"
mkdir -p "$REMOTE_ROOT"
shopt -s nullglob
for PID_FILE in "$REMOTE_ROOT"/*/server.pid; do
DAEMON_DIR="$(dirname "$PID_FILE")"
PID="$(cat "$PID_FILE" 2>/dev/null || true)"
if [[ "$PID" =~ ^[0-9]+$ ]] && [[ -d "/proc/$PID" ]]; then
CMDLINE="$(tr '\0' ' ' < "/proc/$PID/cmdline" 2>/dev/null || true)"
if [[ "$CMDLINE" == *remote-server-daemon* ]]; then
echo "Stopping stale remote-server daemon pid $PID"
kill "$PID" 2>/dev/null || true
for _ in {1..50}; do
if ! kill -0 "$PID" 2>/dev/null; then
break
fi
sleep 0.1
done
if kill -0 "$PID" 2>/dev/null; then
echo "Force-stopping stale remote-server daemon pid $PID"
kill -9 "$PID" 2>/dev/null || true
fi
fi
fi
rm -f "$DAEMON_DIR/server.sock" "$DAEMON_DIR/server.pid"
done
rm -f "$REMOTE_ROOT"/remote-server-integration-bundle-*.tar.gz
REMOTE_SCRIPT
TMP_BUNDLE_NAME="remote-server-integration-bundle-${GITHUB_RUN_ID:-local}-$$-${REMOTE_USER}.tar.gz"
echo "==> Uploading bundle to ${REMOTE_USER}@${REMOTE_HOST}:~/$REMOTE_DIR/$TMP_BUNDLE_NAME"
"${SCP_CMD[@]}" -P "$REMOTE_PORT" \
-o "ProxyCommand=$PROXY_COMMAND" \
-o PreferredAuthentications=password \
-o PubkeyAuthentication=no \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
"$LOCAL_BUNDLE_TARBALL" \
"${REMOTE_USER}@${REMOTE_HOST}:~/$REMOTE_DIR/$TMP_BUNDLE_NAME"
echo "==> Installing binary and resources for ${REMOTE_USER}"
# Args: <remote dir> <tarball name> <binary name in tarball> <installed name>.
# The tarball ships the unversioned binary beside its resources/ tree; the
# installed binary carries the version suffix the Integration channel
# launches. The resources tree lands at `bundled_resources`, the global
# version-independent location the daemon reads (must match
# BUNDLED_RESOURCES_DIR_NAME in crates/remote_server/src/setup.rs).
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" \
"bash -s -- '$REMOTE_DIR' '$TMP_BUNDLE_NAME' '$BUNDLE_BINARY_NAME' '$BINARY_NAME'" <<'REMOTE_SCRIPT'
set -euo pipefail
cd "$HOME/$1"
tar -xzf "$2"
rm -f "$2"
rm -rf bundled_resources
mv resources bundled_resources
chmod 755 "$3"
mv -f "$3" "$4"
"./$4" --version
REMOTE_SCRIPT
done
echo ""
echo "==> Done! Binary deployed to ${REMOTE_HOST}:~/$REMOTE_DIR/$BINARY_NAME for users: ${REMOTE_USERS[*]}"
echo " Bundled resources: ~/$REMOTE_DIR/bundled_resources"