cringe
Some checks are pending
CI / agent (push) Waiting to run
CI / backend (push) Waiting to run
CI / frontend (push) Waiting to run
CI / containers (push) Waiting to run

This commit is contained in:
2026-09-20 11:03:09 +03:00
parent c4dc19cd41
commit cf1c31eb2a
6 changed files with 194 additions and 28 deletions

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@ control-plane/frontend/*.tsbuildinfo
control-plane/backend/backend
control-plane/secrets/*
!control-plane/secrets/.gitkeep
build/

View File

@@ -19,13 +19,31 @@ releases root. Set `VPS_AGENT_MINISIGN_PUBLIC_KEY` to require verification of
`SHA256SUMS.minisig`; checksums are always mandatory. Supported artifact names
are `vps-agent-linux-amd64` and `vps-agent-linux-arm64`.
Maintainers can create that release layout from two cross-compiled binaries:
Each architecture can be built and packaged independently on its matching Linux
builder. An amd64-only release does not require an arm64 binary:
```bash
./package-agent-release.sh path/to/x86_64/vps-agent path/to/aarch64/vps-agent dist
./scripts/build-agent-native.sh dist
```
This produces both canonical names and `SHA256SUMS`; when
The script detects the current Linux host architecture, builds the release
binary, and packages only that architecture. To package an existing binary:
```bash
./package-agent-release.sh --output dist --amd64 path/to/x86_64/vps-agent
```
Use `--arm64 path/to/aarch64/vps-agent` on a separate arm64 Linux builder. Both
options may also be passed in one invocation after the artifacts have been copied
to the same machine. The script regenerates `SHA256SUMS` for every canonical
artifact already present in the output directory and supports both Linux
`sha256sum` and macOS `shasum -a 256`.
Native macOS builds produce Mach-O binaries and cannot be published as Linux
agent artifacts. macOS may be used to combine and sign Linux binaries that were
built independently on matching Linux hosts.
Packaging produces the selected canonical names and `SHA256SUMS`; when
`VPS_AGENT_MINISIGN_SECRET_KEY` is set it also creates `SHA256SUMS.minisig`.
Install checks root, Linux/systemd and architecture, creates the locked service

View File

@@ -22,13 +22,42 @@
- `vps-agent-linux-amd64`
- `vps-agent-linux-arm64`
Сопровождающие проект разработчики могут сформировать необходимую структуру релиза из двух заранее скомпилированных бинарных файлов:
Каждую архитектуру можно собрать и упаковать независимо на соответствующей Linux-машине. Для релиза только под amd64 второй бинарный файл не нужен:
```bash
./package-agent-release.sh path/to/x86_64/vps-agent path/to/aarch64/vps-agent dist
./scripts/build-agent-native.sh dist
```
Этот скрипт создаёт файлы с каноническими именами, а также `SHA256SUMS`. Если задана переменная `VPS_AGENT_MINISIGN_SECRET_KEY`, дополнительно создаётся файл подписи `SHA256SUMS.minisig`.
Скрипт определит архитектуру текущего Linux-хоста, выполнит release-сборку и создаст только соответствующий артефакт. Например, на Linux x86_64 будут созданы `dist/vps-agent-linux-amd64` и `dist/SHA256SUMS`.
Если бинарный файл уже собран, можно запустить только упаковку:
```bash
./package-agent-release.sh \
--output dist \
--amd64 path/to/x86_64/vps-agent
```
На отдельном Linux arm64 builder используется независимый запуск:
```bash
./package-agent-release.sh \
--output dist \
--arm64 path/to/aarch64/vps-agent
```
Если оба Linux-бинарника уже скопированы на одну машину, их можно упаковать одним запуском:
```bash
./package-agent-release.sh \
--output dist \
--amd64 path/to/x86_64/vps-agent \
--arm64 path/to/aarch64/vps-agent
```
Скрипт создаёт файлы с каноническими именами и пересобирает `SHA256SUMS` для всех артефактов, находящихся в выходном каталоге. На Linux используется `sha256sum`, а на macOS — `shasum -a 256`. Если задана переменная `VPS_AGENT_MINISIGN_SECRET_KEY`, дополнительно создаётся файл подписи `SHA256SUMS.minisig`.
Нативная сборка на macOS создаёт Mach-O и для Linux-релиза не подходит. На macOS можно объединять и подписывать уже собранные Linux-артефакты, но сами `linux/amd64` и `linux/arm64` бинарники собираются независимо на Linux-хостах соответствующей архитектуры.
Во время установки скрипт:

39
scripts/build-agent-native.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly REPOSITORY_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
readonly OUTPUT_DIRECTORY="${1:-$REPOSITORY_ROOT/dist}"
[[ "$(uname -s)" == Linux ]] || {
printf 'error: the agent must be built on Linux; macOS produces a Mach-O binary, not a Linux ELF binary\n' >&2
exit 1
}
case "$(uname -m)" in
x86_64|amd64)
RELEASE_ARCHITECTURE="amd64"
;;
aarch64|arm64)
RELEASE_ARCHITECTURE="arm64"
;;
*)
printf 'error: unsupported build architecture: %s\n' "$(uname -m)" >&2
exit 1
;;
esac
command -v cargo >/dev/null || { printf 'error: cargo is required\n' >&2; exit 1; }
cargo build \
--manifest-path "$REPOSITORY_ROOT/agent/Cargo.toml" \
--release \
--locked
"$SCRIPT_DIR/package-agent-release.sh" \
--output "$OUTPUT_DIRECTORY" \
"--$RELEASE_ARCHITECTURE" "$REPOSITORY_ROOT/agent/target/release/vps-agent"
printf 'release artifact prepared in %s for linux/%s\n' \
"$OUTPUT_DIRECTORY" "$RELEASE_ARCHITECTURE"

View File

@@ -2,34 +2,113 @@
set -Eeuo pipefail
IFS=$'\n\t'
if [[ $# -ne 3 ]]; then
printf 'Usage: %s X86_64_BINARY AARCH64_BINARY OUTPUT_DIRECTORY\n' "$0" >&2
exit 2
fi
usage() {
printf '%s\n' \
"Usage:" \
" $0 --output DIRECTORY --amd64 BINARY" \
" $0 --output DIRECTORY --arm64 BINARY" \
" $0 --output DIRECTORY --amd64 BINARY --arm64 BINARY" \
"" \
"The legacy form is still supported:" \
" $0 X86_64_BINARY AARCH64_BINARY OUTPUT_DIRECTORY" >&2
}
AMD64_BINARY=""
ARM64_BINARY=""
OUTPUT_DIRECTORY=""
# Preserve the original interface for existing release jobs while allowing each
# architecture to be packaged independently on its native Linux builder.
if [[ $# -eq 3 && "$1" != --* ]]; then
AMD64_BINARY="$1"
ARM64_BINARY="$2"
OUTPUT_DIRECTORY="$3"
else
while [[ $# -gt 0 ]]; do
case "$1" in
--amd64)
[[ $# -ge 2 ]] || { usage; exit 2; }
AMD64_BINARY="$2"
shift 2
;;
--arm64)
[[ $# -ge 2 ]] || { usage; exit 2; }
ARM64_BINARY="$2"
shift 2
;;
--output)
[[ $# -ge 2 ]] || { usage; exit 2; }
OUTPUT_DIRECTORY="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
printf 'unknown argument: %s\n' "$1" >&2
usage
exit 2
;;
esac
done
fi
[[ -x "$AMD64_BINARY" ]] || { printf 'amd64 binary is not executable\n' >&2; exit 1; }
[[ -x "$ARM64_BINARY" ]] || { printf 'arm64 binary is not executable\n' >&2; exit 1; }
command -v sha256sum >/dev/null || { printf 'sha256sum is required\n' >&2; exit 1; }
[[ -n "$OUTPUT_DIRECTORY" ]] || { printf 'output directory is required\n' >&2; usage; exit 2; }
[[ -n "$AMD64_BINARY" || -n "$ARM64_BINARY" ]] || {
printf 'at least one architecture binary is required\n' >&2
usage
exit 2
}
command -v file >/dev/null || { printf 'file is required\n' >&2; exit 1; }
AMD64_DESCRIPTION="$(file -b "$AMD64_BINARY")"
ARM64_DESCRIPTION="$(file -b "$ARM64_BINARY")"
[[ "$AMD64_DESCRIPTION" == *ELF* && "$AMD64_DESCRIPTION" == *x86-64* ]] || {
printf 'amd64 artifact is not an x86-64 Linux ELF binary\n' >&2; exit 1;
validate_and_install() {
local architecture="$1"
local source="$2"
local destination="$3"
local description
[[ -x "$source" ]] || { printf '%s binary is not executable\n' "$architecture" >&2; exit 1; }
description="$(file -b "$source")"
case "$architecture" in
amd64)
[[ "$description" == *ELF* && "$description" == *x86-64* ]] || {
printf 'amd64 artifact is not an x86-64 Linux ELF binary\n' >&2
exit 1
}
[[ "$ARM64_DESCRIPTION" == *ELF* && ("$ARM64_DESCRIPTION" == *aarch64* || "$ARM64_DESCRIPTION" == *ARM64*) ]] || {
printf 'arm64 artifact is not an aarch64 Linux ELF binary\n' >&2; exit 1;
;;
arm64)
[[ "$description" == *ELF* && ("$description" == *aarch64* || "$description" == *ARM64*) ]] || {
printf 'arm64 artifact is not an aarch64 Linux ELF binary\n' >&2
exit 1
}
;;
esac
install -m 0755 "$source" "$destination"
}
install -d -m 0755 "$OUTPUT_DIRECTORY"
install -m 0755 "$AMD64_BINARY" "$OUTPUT_DIRECTORY/vps-agent-linux-amd64"
install -m 0755 "$ARM64_BINARY" "$OUTPUT_DIRECTORY/vps-agent-linux-arm64"
if [[ -n "$AMD64_BINARY" ]]; then
validate_and_install amd64 "$AMD64_BINARY" "$OUTPUT_DIRECTORY/vps-agent-linux-amd64"
fi
if [[ -n "$ARM64_BINARY" ]]; then
validate_and_install arm64 "$ARM64_BINARY" "$OUTPUT_DIRECTORY/vps-agent-linux-arm64"
fi
CHECKSUM_FILES=()
[[ -f "$OUTPUT_DIRECTORY/vps-agent-linux-amd64" ]] && CHECKSUM_FILES+=(vps-agent-linux-amd64)
[[ -f "$OUTPUT_DIRECTORY/vps-agent-linux-arm64" ]] && CHECKSUM_FILES+=(vps-agent-linux-arm64)
(
cd "$OUTPUT_DIRECTORY"
sha256sum vps-agent-linux-amd64 vps-agent-linux-arm64 > SHA256SUMS
if command -v sha256sum >/dev/null; then
sha256sum "${CHECKSUM_FILES[@]}" > SHA256SUMS
elif command -v shasum >/dev/null; then
shasum -a 256 "${CHECKSUM_FILES[@]}" > SHA256SUMS
else
printf 'sha256sum or shasum is required\n' >&2
exit 1
fi
if [[ -n "${VPS_AGENT_MINISIGN_SECRET_KEY:-}" ]]; then
command -v minisign >/dev/null || { printf 'minisign is required for signing\n' >&2; exit 1; }
minisign -Sm SHA256SUMS -s "$VPS_AGENT_MINISIGN_SECRET_KEY"

View File

@@ -9,7 +9,7 @@ readonly CONFIG_DIR="/etc/vps-agent"
readonly CREDENTIAL_DIR="${CONFIG_DIR}/credentials"
readonly STATE_DIR="/var/lib/vps-agent"
readonly UNIT="/etc/systemd/system/vps-agent.service"
readonly DEFAULT_RELEASES="https://github.com/vps-control/vps-control/releases"
readonly DEFAULT_RELEASES="https://gitea.hyperdog.dev/dizyaka/vps-control/releases"
VERSION="latest"
RELEASES_URL="${VPS_AGENT_RELEASES_URL:-$DEFAULT_RELEASES}"