Switch mac client install to tarball download
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 15s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-07-15 12:13:12 +03:00
parent 7b94f2dee4
commit b4adcce26a
7 changed files with 111 additions and 19 deletions

View File

@@ -14,8 +14,8 @@ Harbor помогает пользоваться одной VPN-подписко
## Что понадобится ## Что понадобится
- ссылка на подписку от VPN-провайдера; - ссылка на подписку от VPN-провайдера;
- Git;
- Docker с командой `docker compose`; - Docker с командой `docker compose`;
- для ручной установки Gateway — Git;
- для Gateway — Linux-машина в одной локальной сети с устройствами; - для Gateway — Linux-машина в одной локальной сети с устройствами;
- для Connect — Mac с запущенным Docker Desktop. - для Connect — Mac с запущенным Docker Desktop.
@@ -78,14 +78,12 @@ http://АДРЕС-GATEWAY:3456
### 1. Запустите Docker Desktop ### 1. Запустите Docker Desktop
Установщик проверит наличие Git, Docker, Docker Compose и `curl`. Если Docker Desktop не запущен, установка остановится с понятным сообщением. Установщик проверит наличие Docker, Docker Compose, `curl` и `tar`. Если Docker Desktop не запущен, установка остановится с понятным сообщением.
### 2. Скачайте проект и запустите установщик ### 2. Запустите установщик
```bash ```bash
git clone https://git.dokops.ru/dokril/vpn-proxy.git curl -fsSL https://git.dokops.ru/dokril/vpn-proxy/raw/branch/master/install.sh | sh
cd vpn-proxy
./scripts/install-macos-client.sh
``` ```
Установщик: Установщик:
@@ -114,9 +112,10 @@ cd vpn-proxy
Передайте нужные значения при повторном запуске установщика: Передайте нужные значения при повторном запуске установщика:
```bash ```bash
curl -fsSL https://git.dokops.ru/dokril/vpn-proxy/raw/branch/master/install.sh | \
VPN_PROXY_CLIENT_PORT=9080 \ VPN_PROXY_CLIENT_PORT=9080 \
VPN_PROXY_CLIENT_UI_PORT=3457 \ VPN_PROXY_CLIENT_UI_PORT=3457 \
./scripts/install-macos-client.sh sh
``` ```
Допустимы порты от `1024` до `65535`. Установщик не позволит выбрать занятый порт или один порт одновременно для интерфейса и прокси. Допустимы порты от `1024` до `65535`. Установщик не позволит выбрать занятый порт или один порт одновременно для интерфейса и прокси.
@@ -212,11 +211,10 @@ docker compose -f docker-compose.gateway.yml up -d --build
### Connect ### Connect
Повторно запустите установщик. Он обновит рабочую копию, снова спросит порт прокси и пересоберёт Connect: Повторно запустите однострочный установщик. Он обновит рабочую копию, снова спросит порт прокси и пересоберёт Connect:
```bash ```bash
cd ~/.vpn-proxy-client curl -fsSL https://git.dokops.ru/dokril/vpn-proxy/raw/branch/master/install.sh | sh
./scripts/install-macos-client.sh
``` ```
Если раньше использовался нестандартный порт, укажите его снова через `VPN_PROXY_CLIENT_PORT`. Если раньше использовался нестандартный порт, укажите его снова через `VPN_PROXY_CLIENT_PORT`.

27
install.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -eu
need() {
command -v "$1" >/dev/null 2>&1 || {
printf '[harbor-connect] error: %s is required\n' "$1" >&2
exit 1
}
}
need curl
need tar
[ -x /bin/bash ] || { printf '[harbor-connect] error: /bin/bash is required\n' >&2; exit 1; }
branch="${VPN_PROXY_BRANCH:-master}"
archive_url="${VPN_PROXY_ARCHIVE_URL:-https://git.dokops.ru/dokril/vpn-proxy/archive/${branch}.tar.gz}"
tmp="$(mktemp -d "${TMPDIR:-/tmp}/harbor-connect.XXXXXX")"
trap 'rm -rf "$tmp"' 0 1 2 3 15
mkdir -p "$tmp/source"
curl -fsSL "$archive_url" | tar -xzf - -C "$tmp/source" --strip-components=1
[ -f "$tmp/source/scripts/install-macos-client.sh" ] || {
printf '[harbor-connect] error: installer is missing from archive\n' >&2
exit 1
}
VPN_PROXY_SOURCE_DIR="$tmp/source" /bin/bash "$tmp/source/scripts/install-macos-client.sh"

View File

@@ -34,7 +34,7 @@ export function affectedComponents(files) {
else if (/^(src\/web\/|public\/|index\.html$|vite\.config\.js$)/.test(file)) { else if (/^(src\/web\/|public\/|index\.html$|vite\.config\.js$)/.test(file)) {
add('macClient', 'gatewayClient'); add('macClient', 'gatewayClient');
} else if (/^src\/server\//.test(file)) add('macClient', 'gatewayBackend'); } else if (/^src\/server\//.test(file)) add('macClient', 'gatewayBackend');
else if (/^(Dockerfile\.client|docker-compose\.client(\.local)?\.yml|entrypoint\.client\.sh|scripts\/(install-macos-client|harbor-network-monitor)\.sh)$/.test(file)) { else if (/^(install\.sh|Dockerfile\.client|docker-compose\.client(\.local)?\.yml|entrypoint\.client\.sh|scripts\/(install-macos-client|harbor-network-monitor)\.sh)$/.test(file)) {
add('macClient'); add('macClient');
} else if (/^(Dockerfile|Dockerfile\.runtime-base|docker-compose\.gateway\.yml|entrypoint\.sh|scripts\/(deploy-gateway|build-runtime-base|build-on-107-deploy-111)\.sh)$/.test(file)) { } else if (/^(Dockerfile|Dockerfile\.runtime-base|docker-compose\.gateway\.yml|entrypoint\.sh|scripts\/(deploy-gateway|build-runtime-base|build-on-107-deploy-111)\.sh)$/.test(file)) {
add('gatewayBackend'); add('gatewayBackend');

View File

@@ -2,8 +2,9 @@
set -euo pipefail set -euo pipefail
INSTALL_DIR="${VPN_PROXY_INSTALL_DIR:-$HOME/.vpn-proxy-client}" INSTALL_DIR="${VPN_PROXY_INSTALL_DIR:-$HOME/.vpn-proxy-client}"
REPO_URL="${VPN_PROXY_REPO_URL:-https://git.dokops.ru/dokril/vpn-proxy.git}"
BRANCH="${VPN_PROXY_BRANCH:-master}" BRANCH="${VPN_PROXY_BRANCH:-master}"
ARCHIVE_URL="${VPN_PROXY_ARCHIVE_URL:-https://git.dokops.ru/dokril/vpn-proxy/archive/${BRANCH}.tar.gz}"
SOURCE_DIR="${VPN_PROXY_SOURCE_DIR:-}"
COMPOSE_FILE="docker-compose.client.yml" COMPOSE_FILE="docker-compose.client.yml"
DEFAULT_PROXY_PORT="8082" DEFAULT_PROXY_PORT="8082"
REQUESTED_PROXY_PORT="${VPN_PROXY_CLIENT_PORT:-}" REQUESTED_PROXY_PORT="${VPN_PROXY_CLIENT_PORT:-}"
@@ -254,26 +255,49 @@ get_env_value() {
' .env ' .env
} }
copy_source() {
local source_dir="$1"
[ -f "$source_dir/docker-compose.client.yml" ] || die "invalid Harbor source archive"
log "installing files to $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
cp -R "$source_dir/." "$INSTALL_DIR/"
}
download_source() {
local tmp_dir
tmp_dir="$(mktemp -d)"
mkdir -p "$tmp_dir/source"
log "downloading $ARCHIVE_URL"
if ! curl -fsSL "$ARCHIVE_URL" | tar -xzf - -C "$tmp_dir/source" --strip-components=1; then
rm -rf "$tmp_dir"
die "failed to download Harbor source"
fi
copy_source "$tmp_dir/source"
rm -rf "$tmp_dir"
}
if [[ "$(uname -s)" != "Darwin" ]]; then if [[ "$(uname -s)" != "Darwin" ]]; then
die "this installer is intended for macOS" die "this installer is intended for macOS"
fi fi
need git
need docker need docker
need curl need curl
need tar
docker compose version >/dev/null 2>&1 || die "Docker Compose plugin is required" docker compose version >/dev/null 2>&1 || die "Docker Compose plugin is required"
docker info >/dev/null 2>&1 || die "Docker Desktop is not running" docker info >/dev/null 2>&1 || die "Docker Desktop is not running"
if [[ -d "$INSTALL_DIR/.git" ]]; then if [[ -n "$SOURCE_DIR" ]]; then
copy_source "$SOURCE_DIR"
elif [[ -d "$INSTALL_DIR/.git" ]]; then
need git
log "updating $INSTALL_DIR" log "updating $INSTALL_DIR"
git -C "$INSTALL_DIR" fetch origin "$BRANCH" git -C "$INSTALL_DIR" fetch origin "$BRANCH"
git -C "$INSTALL_DIR" checkout "$BRANCH" git -C "$INSTALL_DIR" checkout "$BRANCH"
git -C "$INSTALL_DIR" pull --ff-only origin "$BRANCH" git -C "$INSTALL_DIR" pull --ff-only origin "$BRANCH"
else else
log "cloning $REPO_URL#$BRANCH to $INSTALL_DIR"
mkdir -p "$(dirname "$INSTALL_DIR")" mkdir -p "$(dirname "$INSTALL_DIR")"
git clone --branch "$BRANCH" "$REPO_URL" "$INSTALL_DIR" download_source
fi fi
cd "$INSTALL_DIR" cd "$INSTALL_DIR"

View File

@@ -1,5 +1,5 @@
export const HARBOR_VERSIONS = Object.freeze({ export const HARBOR_VERSIONS = Object.freeze({
macClient: '0.8.9', macClient: '0.8.10',
gatewayClient: '0.8.9', gatewayClient: '0.8.9',
gatewayBackend: '0.8.0', gatewayBackend: '0.8.0',
}); });

View File

@@ -0,0 +1,42 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
const root = path.resolve(import.meta.dirname, '..');
test('one-line installer extracts the archive and hands it to the macOS installer', () => {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'harbor-install-'));
try {
const source = path.join(tmp, 'fixture', 'harbor-net');
fs.mkdirSync(path.join(source, 'scripts'), { recursive: true });
fs.writeFileSync(path.join(source, 'marker'), 'ok');
fs.writeFileSync(path.join(source, 'scripts', 'install-macos-client.sh'), [
'#!/bin/bash',
'set -eu',
'test "$(cat "$VPN_PROXY_SOURCE_DIR/marker")" = ok',
'printf bootstrap-ok',
].join('\n'));
const archive = path.join(tmp, 'source.tar.gz');
execFileSync('tar', ['-czf', archive, '-C', path.dirname(source), path.basename(source)]);
const bin = path.join(tmp, 'bin');
fs.mkdirSync(bin);
fs.writeFileSync(path.join(bin, 'curl'), '#!/bin/sh\ncat "$FIXTURE_ARCHIVE"\n', { mode: 0o755 });
const output = execFileSync('sh', [path.join(root, 'install.sh')], {
encoding: 'utf8',
env: {
...process.env,
FIXTURE_ARCHIVE: archive,
PATH: `${bin}:/usr/bin:/bin`,
VPN_PROXY_ARCHIVE_URL: 'https://example.invalid/source.tar.gz',
},
});
assert.equal(output, 'bootstrap-ok');
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});

View File

@@ -13,6 +13,7 @@ test('version paths map to the components actually shipped by this repository',
assert.deepEqual(affectedComponents(['src/web/App.jsx']), ['macClient', 'gatewayClient']); assert.deepEqual(affectedComponents(['src/web/App.jsx']), ['macClient', 'gatewayClient']);
assert.deepEqual(affectedComponents(['src/server/index.js']), ['macClient', 'gatewayBackend']); assert.deepEqual(affectedComponents(['src/server/index.js']), ['macClient', 'gatewayBackend']);
assert.deepEqual(affectedComponents(['docker-compose.client.local.yml']), ['macClient']); assert.deepEqual(affectedComponents(['docker-compose.client.local.yml']), ['macClient']);
assert.deepEqual(affectedComponents(['install.sh']), ['macClient']);
assert.deepEqual(affectedComponents(['package-lock.json']), [ assert.deepEqual(affectedComponents(['package-lock.json']), [
'macClient', 'macClient',
'gatewayClient', 'gatewayClient',