mirror of https://github.com/ospab/ostp.git
refactor: professionalize all scripts and CI workflow
build.ps1: - Added mandatory cargo check pre-flight that blocks releases on errors - Added --Check flag for check-only mode (no build, no release) - Reverts version bump if check fails - Professionalized all output (removed informal language) - Cleaner output structure with consistent [ok], [warn], [error] tags install.ps1 / install.sh: - Professionalized all prompts and messages - Removed informal phrasing - Consistent formatting test_linux.sh: - Updated all log string matchers to match professionalized output: 'Connection established' (was 'Bridge connection established') 'Starting server' (was 'Starting in SERVER mode') 'Starting client' (was 'Starting in CLIENT mode') RTT regex updated for new format release.yml: - Added cargo check pre-flight step before native compilation
This commit is contained in:
parent
aa9a93fcbf
commit
e36d743ad5
|
|
@ -137,6 +137,13 @@ jobs:
|
|||
if: ${{ matrix.os == 'ubuntu-latest' && !matrix.use_cross }}
|
||||
run: sudo apt-get update && sudo apt-get install -y musl-tools
|
||||
|
||||
- name: Pre-flight compilation check
|
||||
if: ${{ !matrix.use_cross }}
|
||||
shell: bash
|
||||
run: |
|
||||
cargo check --target ${{ matrix.target }} --bin ostp 2>&1
|
||||
echo "Pre-flight check passed."
|
||||
|
||||
- name: Execute Standard Native Compilation (Windows)
|
||||
if: ${{ !matrix.use_cross && matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -745,7 +745,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
|||
|
||||
[[package]]
|
||||
name = "ostp"
|
||||
version = "0.1.60"
|
||||
version = "0.1.61"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
|
@ -762,7 +762,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-client"
|
||||
version = "0.1.60"
|
||||
version = "0.1.61"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -780,7 +780,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-core"
|
||||
version = "0.1.60"
|
||||
version = "0.1.61"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
|
@ -813,7 +813,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-server"
|
||||
version = "0.1.60"
|
||||
version = "0.1.61"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -828,7 +828,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-tun-helper"
|
||||
version = "0.1.60"
|
||||
version = "0.1.61"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
# OSTP High-Performance Cross-Platform Build & Release Pipeline
|
||||
# OSTP Build & Release Pipeline
|
||||
# Usage:
|
||||
# .\scripts\build.ps1 Build locally + trigger CI/CD
|
||||
# .\scripts\build.ps1 -TriggerOnly Skip local builds, trigger CI/CD only
|
||||
# .\scripts\build.ps1 -Check Run cargo check only (no build, no release)
|
||||
|
||||
param(
|
||||
[switch]$Flatten, # Consolidate raw uncompressed binaries with arch suffixes under dist/release/
|
||||
[switch]$TriggerOnly # Bypasses all local builds to instantly execute global cloud CI/CD tag injection
|
||||
[switch]$Flatten,
|
||||
[switch]$TriggerOnly,
|
||||
[switch]$Check
|
||||
)
|
||||
|
||||
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
||||
Push-Location $ProjectRoot
|
||||
|
||||
Write-Output "Synchronizing latest workspace source code from origin master..."
|
||||
# Leverage autostash and rebase to pull cleanly even with uncommitted local edits
|
||||
# --- Sync ---
|
||||
Write-Output "Synchronizing with origin master..."
|
||||
& git pull origin master --rebase --autostash | Out-Null
|
||||
|
||||
Write-Output "Starting Universal OSTP Build & Release Pipeline in $ProjectRoot"
|
||||
|
||||
# Unblock binaries by terminating any existing active instances
|
||||
Stop-Process -Name ostp -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
# 1. Read and automatically bump version inside Cargo.toml PRIOR to compilation
|
||||
# --- Version bump ---
|
||||
$CargoToml = Join-Path $ProjectRoot "Cargo.toml"
|
||||
$Version = "0.1.0"
|
||||
if (Test-Path $CargoToml) {
|
||||
|
|
@ -30,35 +31,68 @@ if (Test-Path $CargoToml) {
|
|||
$NewVersionStr = 'version = "' + $Version + '"'
|
||||
$NewContent = $Content -replace 'version\s*=\s*"\d+\.\d+\.\d+"', $NewVersionStr
|
||||
[System.IO.File]::WriteAllText($CargoToml, $NewContent)
|
||||
Write-Output "[OK] Bounded workspace package to target release version: v$Version"
|
||||
Write-Output "[ok] Version: v$Version"
|
||||
}
|
||||
}
|
||||
|
||||
# --- Pre-flight: cargo check ---
|
||||
Write-Output ""
|
||||
Write-Output "Running pre-flight cargo check..."
|
||||
$checkOutput = & cargo check 2>&1 | Out-String
|
||||
$checkErrors = $checkOutput | Select-String "^error\[" -CaseSensitive
|
||||
|
||||
if ($checkErrors) {
|
||||
Write-Output ""
|
||||
Write-Output "[error] Compilation check failed. Fix errors before releasing:"
|
||||
Write-Output $checkOutput
|
||||
# Revert version bump
|
||||
[System.IO.File]::WriteAllText($CargoToml, $Content)
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Show warnings if any
|
||||
$checkWarnings = $checkOutput | Select-String "^warning:" -CaseSensitive
|
||||
if ($checkWarnings) {
|
||||
Write-Output "[warn] Compiler warnings detected (non-blocking):"
|
||||
$checkWarnings | ForEach-Object { Write-Output " $_" }
|
||||
} else {
|
||||
Write-Output "[ok] No errors or warnings."
|
||||
}
|
||||
|
||||
if ($Check) {
|
||||
Write-Output ""
|
||||
Write-Output "Check-only mode. Exiting without build or release."
|
||||
# Revert version bump
|
||||
[System.IO.File]::WriteAllText($CargoToml, $Content)
|
||||
Pop-Location
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
Write-Output "Starting build pipeline for v$Version"
|
||||
|
||||
# Kill existing instances
|
||||
Stop-Process -Name ostp -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
$DistDir = Join-Path $ProjectRoot "dist"
|
||||
$StagingDir = Join-Path $DistDir "staging"
|
||||
|
||||
# Wipe legacy artifacts to prepare a clean clean slate
|
||||
if (Test-Path $DistDir) { Remove-Item -Path $DistDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
New-Item -ItemType Directory -Force -Path $DistDir | Out-Null
|
||||
|
||||
# Collection for dynamically mapping successful build archives
|
||||
$ReleaseArchives = @()
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# CONDITIONAL BUILD SUITE execution
|
||||
# ---------------------------------------------------------------------
|
||||
# --- Conditional local build ---
|
||||
if (-not $TriggerOnly) {
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# PHASE 1: WINDOWS COMPILATION MATRIX (Native Host)
|
||||
# ---------------------------------------------------------------------
|
||||
# Phase 1: Windows
|
||||
$WindowsTargets = @(
|
||||
@{ Target = "x86_64-pc-windows-msvc"; Arch = "x64"; BinaryName = "ostp.exe" }
|
||||
)
|
||||
|
||||
Write-Output "========================================================="
|
||||
Write-Output " PHASE 1: Compiling Windows Architectures"
|
||||
Write-Output "========================================================="
|
||||
Write-Output ""
|
||||
Write-Output "--- Phase 1: Windows compilation ---"
|
||||
$TempWinTargetDir = Join-Path $env:TEMP "ostp_target_win"
|
||||
|
||||
foreach ($item in $WindowsTargets) {
|
||||
|
|
@ -66,9 +100,7 @@ foreach ($item in $WindowsTargets) {
|
|||
$arch = $item.Arch
|
||||
$bin = $item.BinaryName
|
||||
|
||||
Write-Output "--> Compiling target: Windows $arch [$target]..."
|
||||
|
||||
# Attempt setup of the rust toolchain for this architecture
|
||||
Write-Output " Compiling: Windows $arch ($target)"
|
||||
& rustup target add $target 2>&1 | Out-Null
|
||||
|
||||
$env:CARGO_TARGET_DIR = $TempWinTargetDir
|
||||
|
|
@ -80,40 +112,32 @@ foreach ($item in $WindowsTargets) {
|
|||
$archiveName = "ostp-v$Version-windows-$arch.zip"
|
||||
$targetStaging = Join-Path $StagingDir "windows-$arch"
|
||||
New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null
|
||||
|
||||
# Stage and package binary natively
|
||||
Copy-Item -Path $compiledBin -Destination $targetStaging -Force
|
||||
|
||||
$archivePath = Join-Path $DistDir $archiveName
|
||||
Compress-Archive -Path "$targetStaging\*" -DestinationPath $archivePath -Force
|
||||
|
||||
$ReleaseArchives += $archivePath
|
||||
Write-Output "[OK] SUCCESSFULLY PACKAGED: $archiveName"
|
||||
Write-Output " [ok] $archiveName"
|
||||
|
||||
if ($Flatten) {
|
||||
$RawReleaseDir = Join-Path $DistDir "release"
|
||||
New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null
|
||||
$FlatName = "ostp-windows-$arch.exe"
|
||||
Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force
|
||||
Write-Output " -> Flat copied: dist/release/$FlatName"
|
||||
Write-Output " [ok] Flat: dist/release/$FlatName"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Output "[WARN] FAILED compiling Windows $arch ($target). Missing local platform C++ toolchain components."
|
||||
Write-Output " [warn] Failed: Windows $arch ($target)"
|
||||
}
|
||||
}
|
||||
# Restore environment variables
|
||||
Remove-Item Env:\CARGO_TARGET_DIR -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# PHASE 2: LINUX CROSS-COMPILATION MATRIX (via WSL + rust-lld)
|
||||
# ---------------------------------------------------------------------
|
||||
Write-Output "`n========================================================="
|
||||
Write-Output " PHASE 2: Compiling Linux Architectures via WSL"
|
||||
Write-Output "========================================================="
|
||||
# Phase 2: Linux via WSL
|
||||
Write-Output ""
|
||||
Write-Output "--- Phase 2: Linux compilation via WSL ---"
|
||||
|
||||
if (Get-Command wsl -ErrorAction SilentlyContinue) {
|
||||
# Anchor output cache on Windows disk to survive WSL instance cycling
|
||||
$LinuxBuildDir = Join-Path $ProjectRoot "target_linux"
|
||||
New-Item -ItemType Directory -Force -Path $LinuxBuildDir | Out-Null
|
||||
$LinuxBuildUnix = $LinuxBuildDir.Replace("\", "/")
|
||||
|
|
@ -127,15 +151,11 @@ if (Get-Command wsl -ErrorAction SilentlyContinue) {
|
|||
$target = $item.Target
|
||||
$arch = $item.Arch
|
||||
$bin = $item.BinaryName
|
||||
|
||||
$osPrefix = "linux"
|
||||
if ($target -match "freebsd") { $osPrefix = "freebsd" }
|
||||
|
||||
Write-Output "--> Compiling target: $osPrefix $arch [$target] via rust-lld..."
|
||||
|
||||
Write-Output " Compiling: $osPrefix $arch ($target)"
|
||||
& wsl rustup target add $target 2>&1 | Out-Null
|
||||
|
||||
# Invoke Cargo cross-compiling via toolless rust-lld LLVM backend for Musl targets!
|
||||
& wsl env RUSTFLAGS="-C linker=rust-lld" CARGO_TARGET_DIR=$WslBuildDir cargo build --release --target $target --bin ostp
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
|
|
@ -144,81 +164,72 @@ if (Get-Command wsl -ErrorAction SilentlyContinue) {
|
|||
$archiveName = "ostp-v$Version-$osPrefix-$arch.tar.gz"
|
||||
$targetStaging = Join-Path $StagingDir "$osPrefix-$arch"
|
||||
New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null
|
||||
|
||||
Copy-Item -Path $compiledBin -Destination $targetStaging -Force
|
||||
|
||||
# Translate staging paths to Linux formats for WSL tar archiving
|
||||
$wslStagingDir = & wsl wslpath -u ($targetStaging.Replace("\", "/"))
|
||||
$wslArchiveFile = & wsl wslpath -u ((Join-Path $DistDir $archiveName).Replace("\", "/"))
|
||||
|
||||
# Generate clean compressed tarball natively via WSL tar engine
|
||||
& wsl tar -czf $wslArchiveFile -C $wslStagingDir $bin
|
||||
|
||||
$ReleaseArchives += Join-Path $DistDir $archiveName
|
||||
Write-Output "[OK] SUCCESSFULLY PACKAGED: $archiveName"
|
||||
Write-Output " [ok] $archiveName"
|
||||
|
||||
if ($Flatten) {
|
||||
$RawReleaseDir = Join-Path $DistDir "release"
|
||||
New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null
|
||||
$FlatName = "ostp-$osPrefix-$arch"
|
||||
Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force
|
||||
Write-Output " -> Flat copied: dist/release/$FlatName"
|
||||
Write-Output " [ok] Flat: dist/release/$FlatName"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Output "[WARN] FAILED compiling Linux $arch ($target)."
|
||||
Write-Output " [warn] Failed: $osPrefix $arch ($target)"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Output "[WARN] WSL utility not discovered on host. Skipping Linux binary compilations."
|
||||
Write-Output " [skip] WSL not available."
|
||||
}
|
||||
|
||||
# Dissolve staging buffer directory
|
||||
# Cleanup staging
|
||||
if (Test-Path $StagingDir) { Remove-Item -Path $StagingDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
|
||||
Write-Output "`n========================================================="
|
||||
Write-Output " RELEASE ARTIFACTS SUMMARY"
|
||||
Write-Output "========================================================="
|
||||
Write-Output ""
|
||||
Write-Output "--- Build summary ---"
|
||||
if ($ReleaseArchives.Count -gt 0) {
|
||||
$ReleaseArchives | ForEach-Object { Write-Output " [+] $_" }
|
||||
$ReleaseArchives | ForEach-Object { Write-Output " $_" }
|
||||
} else {
|
||||
Write-Output "[ERROR] CRITICAL: No architectures compiled successfully."
|
||||
Write-Output "[error] No architectures compiled successfully."
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Output "`n--> [TRIGGER ONLY MODE] Bypassing all local compilations as requested."
|
||||
Write-Output ""
|
||||
Write-Output "[info] Trigger-only mode. Skipping local compilation."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# PHASE 3: TRIGGER GLOBAL CI/CD RELEASE PIPELINE (Via Git Tag)
|
||||
# ---------------------------------------------------------------------
|
||||
Write-Output "`n========================================================="
|
||||
Write-Output " PHASE 3: Launching Unified Global Cloud Release"
|
||||
Write-Output "========================================================="
|
||||
# --- Phase 3: CI/CD release trigger ---
|
||||
Write-Output ""
|
||||
Write-Output "--- Phase 3: CI/CD release ---"
|
||||
|
||||
Write-Output "Synchronizing workspace version metadata to origin master..."
|
||||
# Commit current Cargo.toml bump to establish version lineage
|
||||
& git add Cargo.toml
|
||||
Write-Output "Pushing version metadata..."
|
||||
& git add Cargo.toml Cargo.lock
|
||||
& git commit -m "CI/CD: release version v$Version" --allow-empty | Out-Null
|
||||
& git push origin master | Out-Null
|
||||
|
||||
Write-Output "Generating release tracking tag: v$Version"
|
||||
# Purge local tracking tag if pre-existing to guarantee clean sync
|
||||
Write-Output "Creating release tag: v$Version"
|
||||
& git tag -d "v$Version" 2>&1 | Out-Null
|
||||
& git tag "v$Version"
|
||||
|
||||
Write-Output "Deploying trigger tag to GitHub..."
|
||||
# Pushing the tag forces GitHub Actions to instantly spin up the cloud builders
|
||||
Write-Output "Pushing tag to GitHub..."
|
||||
& git push origin "v$Version" --force
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "`n[OK] EXCELLENT! Release trigger successfully synchronized with Cloud runners!"
|
||||
Write-Output "[INFO] GitHub Actions is now compiling all 13 architectures in parallel."
|
||||
Write-Output "[INFO] Live monitoring link: https://github.com/ospab/ostp/actions"
|
||||
Write-Output ""
|
||||
Write-Output "[ok] Release v$Version triggered on GitHub Actions."
|
||||
Write-Output " Monitor: https://github.com/ospab/ostp/actions"
|
||||
} else {
|
||||
Write-Output "`n[ERROR] Failed to deliver release tag to remote origin."
|
||||
Write-Output ""
|
||||
Write-Output "[error] Failed to push release tag."
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
|
|
|
|||
|
|
@ -1,27 +1,22 @@
|
|||
$ErrorActionPreference = "Stop"
|
||||
$repo = "ospab/ostp"
|
||||
|
||||
# 1. Smart & Aggressive Installation Path Resolution
|
||||
$InstallDir = "C:\opt\ostp" # Standard default fallback
|
||||
# 1. Install path resolution
|
||||
$InstallDir = "C:\opt\ostp"
|
||||
|
||||
if (Test-Path "config.json") {
|
||||
# Config is in active current directory
|
||||
$InstallDir = (Get-Item .).FullName
|
||||
} elseif (Test-Path "ostp.exe") {
|
||||
# Binary is in active current directory
|
||||
$InstallDir = (Get-Item .).FullName
|
||||
} elseif ($cmd = Get-Command "ostp" -ErrorAction SilentlyContinue) {
|
||||
# Binary is registered in system PATH
|
||||
$InstallDir = Split-Path $cmd.Path
|
||||
} else {
|
||||
# Aggressive search in current directory tree (excluding compiler target and Git directories)
|
||||
$found = Get-ChildItem -Filter "ostp.exe" -Recurse -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notlike "*\target\*" -and $_.FullName -notlike "*\.git\*" } |
|
||||
Select-Object -First 1
|
||||
if ($found) {
|
||||
$InstallDir = Split-Path $found.FullName
|
||||
} else {
|
||||
# Scan parent directory as fallback
|
||||
$parentFound = Get-ChildItem -Path .. -Filter "ostp.exe" -File -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($parentFound) {
|
||||
$InstallDir = Split-Path $parentFound.FullName
|
||||
|
|
@ -30,18 +25,18 @@ if (Test-Path "config.json") {
|
|||
}
|
||||
|
||||
Write-Host "========================================================"
|
||||
Write-Host " Installing Ospab Stealth Transport Protocol (OSTP)"
|
||||
Write-Host " OSTP Installer"
|
||||
Write-Host "========================================================"
|
||||
Write-Host "Target deployment location: $InstallDir"
|
||||
Write-Host "Install directory: $InstallDir"
|
||||
|
||||
# 2. Check Write Access & Elevation Status
|
||||
# 2. Access check
|
||||
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
|
||||
if (-not (Test-Path $InstallDir)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $InstallDir -ErrorAction Stop | Out-Null
|
||||
} catch {
|
||||
Write-Error "Access Denied: Cannot create target directory '$InstallDir'. Run as Administrator."
|
||||
Write-Error "Cannot create '$InstallDir'. Run as Administrator."
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
|
|
@ -50,27 +45,26 @@ if (-not (Test-Path $InstallDir)) {
|
|||
"test" | Set-Content $testFile -ErrorAction Stop
|
||||
Remove-Item $testFile -Force
|
||||
} catch {
|
||||
Write-Error "Access Denied: Directory '$InstallDir' is read-only. Run as Administrator to update."
|
||||
Write-Error "Directory '$InstallDir' is read-only. Run as Administrator."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Detect Architecture
|
||||
# 3. Architecture detection
|
||||
$arch = "amd64"
|
||||
if ([System.Environment]::Is64BitOperatingSystem -and ($Env:PROCESSOR_ARCHITECTURE -eq "ARM64" -or $Env:PROCESSOR_ARCHITEW6432 -eq "ARM64")) {
|
||||
$arch = "arm64"
|
||||
}
|
||||
|
||||
# 4. Fetch Stable Version Asset (with -UseBasicParsing to prevent Internet Explorer hangs)
|
||||
Write-Host "Fetching latest stable version from the repository..."
|
||||
# 4. Fetch latest release
|
||||
Write-Host "Fetching latest release..."
|
||||
try {
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
# Explicitly set -UseBasicParsing to guarantee execution doesn't hang on headless servers
|
||||
$api = Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases/latest" -UseBasicParsing
|
||||
$tag = $api.tag_name
|
||||
} catch {
|
||||
Write-Host "[Notice] Failed to retrieve tag automatically."
|
||||
$tag = Read-Host "Enter release version tag manually (e.g., v0.1.23)"
|
||||
Write-Host "[notice] Could not determine latest release automatically."
|
||||
$tag = Read-Host "Enter release tag (e.g. v0.1.60)"
|
||||
if (-not $tag) { exit 1 }
|
||||
}
|
||||
|
||||
|
|
@ -79,29 +73,26 @@ $url = "https://github.com/$repo/releases/download/$tag/$archive"
|
|||
$zipPath = Join-Path $env:TEMP "ostp_temp_$($PID).zip"
|
||||
$extractPath = Join-Path $env:TEMP "ostp_extract_$($PID)"
|
||||
|
||||
Write-Host "Downloading asset windows-${arch}: $url ..."
|
||||
# Explicitly set -UseBasicParsing to prevent any engine initialization stalls
|
||||
Write-Host "Downloading: $archive ($tag)"
|
||||
Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing
|
||||
|
||||
if (-not (Test-Path $zipPath)) {
|
||||
Write-Error "Failed to download zip package."
|
||||
Write-Error "Download failed."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Overwrite and clear file locks
|
||||
if (Test-Path $extractPath) { Remove-Item $extractPath -Recurse -Force }
|
||||
Expand-Archive -Path $zipPath -DestinationPath $extractPath -Force
|
||||
|
||||
$extractedFiles = Get-ChildItem -Path $extractPath -File -Recurse
|
||||
if ($extractedFiles.Count -gt 0) {
|
||||
Write-Host "Stopping any active instances of ostp to unlock binary targets..."
|
||||
Write-Host "Stopping active instances..."
|
||||
Stop-Process -Name "ostp", "tun2socks" -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
foreach ($file in $extractedFiles) {
|
||||
$destPath = Join-Path $InstallDir $file.Name
|
||||
if (Test-Path $destPath) {
|
||||
# Rename the existing executable out of the way to bypass file locks
|
||||
$oldPath = $destPath + ".old_$PID"
|
||||
Rename-Item -Path $destPath -NewName $oldPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
|
@ -109,36 +100,32 @@ if ($extractedFiles.Count -gt 0) {
|
|||
(Get-Item $destPath).LastWriteTime = [DateTime]::Now
|
||||
}
|
||||
|
||||
# Try to clean up any leftover old files
|
||||
Get-ChildItem -Path $InstallDir -Filter "*.old_*" | Remove-Item -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "Executables and dependencies successfully deployed to $InstallDir."
|
||||
Write-Host "Files deployed to $InstallDir."
|
||||
} else {
|
||||
Write-Error "No files found in archive package."
|
||||
Write-Error "Archive is empty."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Remove-Item $zipPath -Force
|
||||
Remove-Item $extractPath -Recurse -Force
|
||||
|
||||
# 5. Smart Auto-Updater Mode
|
||||
# 5. Update detection
|
||||
$configPath = Join-Path $InstallDir "config.json"
|
||||
if (Test-Path $configPath) {
|
||||
Write-Host "--------------------------------------------------------"
|
||||
Write-Host "[Update] Existing configuration detected at $configPath."
|
||||
Write-Host "[Update] Binary successfully hot-swapped to version $tag."
|
||||
Write-Host "Existing configuration found. Binary updated to $tag."
|
||||
Write-Host "--------------------------------------------------------"
|
||||
Write-Host "Update completed successfully!"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 6. Interactive Setup
|
||||
# 6. Interactive setup
|
||||
Write-Host "--------------------------------------------------------"
|
||||
Write-Host "Select configuration mode:"
|
||||
Write-Host "1) Configure Server"
|
||||
Write-Host "2) Configure Client"
|
||||
Write-Host "Select mode:"
|
||||
Write-Host " 1) Server"
|
||||
Write-Host " 2) Client"
|
||||
Write-Host "--------------------------------------------------------"
|
||||
$mode = Read-Host "Enter choice [1-2]"
|
||||
$mode = Read-Host "Choice [1-2]"
|
||||
|
||||
Push-Location $InstallDir
|
||||
|
||||
|
|
@ -147,64 +134,64 @@ if ($mode -eq "1") {
|
|||
& .\ostp.exe --init server --config config.json
|
||||
|
||||
$config = Get-Content "config.json" -Raw | ConvertFrom-Json
|
||||
$listen = Read-Host "Enter IP and port to accept incoming traffic [default: 0.0.0.0:50000]"
|
||||
$listen = Read-Host "Listen address [default: 0.0.0.0:50000]"
|
||||
if ($listen) { $config.listen = $listen }
|
||||
|
||||
$keyCount = Read-Host "How many access keys to generate? [default: 1]"
|
||||
$keyCount = Read-Host "Number of access keys [default: 1]"
|
||||
if (-not $keyCount) { $keyCount = 1 }
|
||||
|
||||
if ([int]$keyCount -gt 1) {
|
||||
Write-Host "Generating additional security keys..."
|
||||
Write-Host "Generating $keyCount access keys..."
|
||||
$keys = & .\ostp.exe -g -c $keyCount
|
||||
$config.access_keys = $keys -split "`r`n" | Where-Object { $_ -ne "" }
|
||||
}
|
||||
|
||||
$config | ConvertTo-Json -Depth 10 | Set-Content "config.json"
|
||||
Write-Host "Server configuration completed. Config written to $(Join-Path $InstallDir 'config.json')"
|
||||
Write-Host "Server configuration saved: $(Join-Path $InstallDir 'config.json')"
|
||||
|
||||
} elseif ($mode -eq "2") {
|
||||
Write-Host "Initializing client configuration..."
|
||||
& .\ostp.exe --init client --config config.json
|
||||
|
||||
$config = Get-Content "config.json" -Raw | ConvertFrom-Json
|
||||
$server = Read-Host "Enter remote server address (IP:PORT)"
|
||||
$server = Read-Host "Server address (host:port)"
|
||||
if ($server) { $config.server = $server }
|
||||
|
||||
$key = Read-Host "Enter access key (leave blank to generate automatically)"
|
||||
$key = Read-Host "Access key (blank to generate)"
|
||||
if (-not $key) {
|
||||
$key = & .\ostp.exe -g
|
||||
Write-Host "Automatically generated client access key: $key"
|
||||
Write-Host "Generated key: $key"
|
||||
}
|
||||
$config.access_key = $key.Trim()
|
||||
|
||||
$socks = Read-Host "Enter SOCKS5 listening address [default: 127.0.0.1:1088]"
|
||||
$socks = Read-Host "Local proxy address [default: 127.0.0.1:1088]"
|
||||
if ($socks) { $config.socks5_bind = $socks }
|
||||
|
||||
$config | ConvertTo-Json -Depth 10 | Set-Content "config.json"
|
||||
Write-Host "Client configuration completed. Config written to $(Join-Path $InstallDir 'config.json')"
|
||||
Write-Host "Client configuration saved: $(Join-Path $InstallDir 'config.json')"
|
||||
} else {
|
||||
Write-Error "Invalid configuration choice."
|
||||
Write-Error "Invalid selection."
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
|
||||
# 7. Environment PATH Registration
|
||||
# 7. PATH registration
|
||||
Write-Host "--------------------------------------------------------"
|
||||
Write-Host "Registering binary route in Environment PATH..."
|
||||
Write-Host "Registering in system PATH..."
|
||||
$targetScope = if ($isAdmin) { [EnvironmentVariableTarget]::Machine } else { [EnvironmentVariableTarget]::User }
|
||||
$sysPath = [Environment]::GetEnvironmentVariable("Path", $targetScope)
|
||||
if ($sysPath -notlike "*$InstallDir*") {
|
||||
$newPath = "$sysPath;$InstallDir"
|
||||
[Environment]::SetEnvironmentVariable("Path", $newPath, $targetScope)
|
||||
Write-Host "Environment PATH updated successfully ($($targetScope.ToString()) scope)."
|
||||
Write-Host "PATH updated ($($targetScope.ToString()) scope)."
|
||||
} else {
|
||||
Write-Host "$InstallDir is already registered in PATH."
|
||||
Write-Host "$InstallDir already in PATH."
|
||||
}
|
||||
|
||||
Write-Host "--------------------------------------------------------"
|
||||
Write-Host "Deployment completed successfully!"
|
||||
Write-Host "Binary can be executed globally by typing: ostp"
|
||||
Write-Host "Config location: $(Join-Path $InstallDir 'config.json')"
|
||||
Write-Host "Installation complete."
|
||||
Write-Host " Binary: ostp"
|
||||
Write-Host " Config: $(Join-Path $InstallDir 'config.json')"
|
||||
Write-Host "--------------------------------------------------------"
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Official repository settings
|
||||
GITHUB_REPO="ospab/ostp"
|
||||
INSTALL_DIR="/opt/ostp"
|
||||
|
||||
echo "========================================================"
|
||||
echo " Installing Ospab Stealth Transport Protocol (OSTP)"
|
||||
echo " OSTP Installer"
|
||||
echo "========================================================"
|
||||
|
||||
# Verify superuser privileges
|
||||
# Verify root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "[Error] This script must be run with root privileges (sudo)."
|
||||
echo "[error] Root privileges required. Run with sudo."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create target directory
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# System Architecture Detection
|
||||
# ---------------------------------------------------------
|
||||
# Architecture detection
|
||||
ARCH=$(uname -m)
|
||||
case "$ARCH" in
|
||||
x86_64) ARCH="amd64" ;;
|
||||
|
|
@ -28,18 +24,18 @@ case "$ARCH" in
|
|||
i386|i686) ARCH="386" ;;
|
||||
armv7l) ARCH="armv7" ;;
|
||||
*)
|
||||
echo "[Warning] Unknown architecture $ARCH, falling back to amd64."
|
||||
echo "[warn] Unknown architecture $ARCH, defaulting to amd64."
|
||||
ARCH="amd64"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Fetch execution binary
|
||||
echo "Fetching the latest stable version from the repository..."
|
||||
# Fetch latest release
|
||||
echo "Fetching latest release..."
|
||||
LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
|
||||
if [ -z "$LATEST_RELEASE" ] || [[ "$LATEST_RELEASE" == *"null"* ]]; then
|
||||
echo "[Notice] Failed to automatically retrieve release tag for ${GITHUB_REPO}."
|
||||
echo "Enter a direct URL to the compiled .tar.gz archive"
|
||||
echo "[notice] Could not determine latest release automatically."
|
||||
echo "Enter a direct URL to the .tar.gz archive,"
|
||||
echo "or press Enter if the binary is already in $INSTALL_DIR/ostp."
|
||||
read -p "URL: " DIRECT_URL
|
||||
if [ -n "$DIRECT_URL" ]; then
|
||||
|
|
@ -51,18 +47,18 @@ if [ -z "$LATEST_RELEASE" ] || [[ "$LATEST_RELEASE" == *"null"* ]]; then
|
|||
else
|
||||
ARCHIVE_NAME="ostp-linux-${ARCH}.tar.gz"
|
||||
DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_RELEASE}/${ARCHIVE_NAME}"
|
||||
echo "Downloading archive for linux-$ARCH: $DOWNLOAD_URL ..."
|
||||
echo "Downloading: $ARCHIVE_NAME ($LATEST_RELEASE)"
|
||||
|
||||
TEMP_TAR="/tmp/ostp_temp.tar.gz"
|
||||
# Fetch archive with basic error handling
|
||||
HTTP_CODE=$(curl -sL -w "%{http_code}" "$DOWNLOAD_URL" -o "$TEMP_TAR")
|
||||
|
||||
if [ "$HTTP_CODE" -eq 200 ]; then
|
||||
tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp
|
||||
rm -f "$TEMP_TAR"
|
||||
else
|
||||
echo "[Error] Failed to download the file (HTTP status $HTTP_CODE)."
|
||||
echo "Verify that the version $LATEST_RELEASE is published and fully compiled on GitHub."
|
||||
echo "[error] Download failed (HTTP $HTTP_CODE)."
|
||||
echo "Verify that $LATEST_RELEASE is published at:"
|
||||
echo " https://github.com/$GITHUB_REPO/releases"
|
||||
rm -f "$TEMP_TAR"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -70,40 +66,37 @@ fi
|
|||
|
||||
if [ -f "$INSTALL_DIR/ostp" ]; then
|
||||
chmod +x "$INSTALL_DIR/ostp"
|
||||
echo "Executable configured successfully at $INSTALL_DIR/ostp."
|
||||
echo "Binary installed: $INSTALL_DIR/ostp"
|
||||
else
|
||||
echo "[Error] Binary file not found in $INSTALL_DIR/ostp. Aborting setup."
|
||||
echo "[error] Binary not found at $INSTALL_DIR/ostp."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Automatic Update Detection (Preserves Settings)
|
||||
# ---------------------------------------------------------
|
||||
# Update detection
|
||||
if [ -f "$INSTALL_DIR/config.json" ]; then
|
||||
echo "--------------------------------------------------------"
|
||||
echo "[Update] Existing configuration detected at $INSTALL_DIR/config.json."
|
||||
echo "[Update] Binary successfully updated to version ${LATEST_RELEASE:-latest}."
|
||||
echo "Existing configuration found. Binary updated to ${LATEST_RELEASE:-latest}."
|
||||
|
||||
if systemctl is-active --quiet ostp.service 2>/dev/null; then
|
||||
echo "[Update] Restarting service ostp to apply the new version..."
|
||||
echo "Restarting ostp service..."
|
||||
systemctl restart ostp.service
|
||||
echo "[Update] Service ostp restarted successfully."
|
||||
else
|
||||
echo "[Update] Service ostp is registered but not currently running."
|
||||
echo "Start the service manually to apply changes: systemctl start ostp"
|
||||
echo "Service restarted."
|
||||
elif systemctl is-enabled --quiet ostp.service 2>/dev/null; then
|
||||
echo "Service registered but not running."
|
||||
echo "Start manually: systemctl start ostp"
|
||||
fi
|
||||
echo "--------------------------------------------------------"
|
||||
echo "Update completed successfully!"
|
||||
echo "Update complete."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Interactive Setup Menu
|
||||
# Interactive setup
|
||||
echo "--------------------------------------------------------"
|
||||
echo "Select configuration mode:"
|
||||
echo "1) Configure Server"
|
||||
echo "2) Configure Client"
|
||||
echo "Select mode:"
|
||||
echo " 1) Server"
|
||||
echo " 2) Client"
|
||||
echo "--------------------------------------------------------"
|
||||
read -p "Enter choice [1-2]: " NODE_MODE
|
||||
read -p "Choice [1-2]: " NODE_MODE
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
|
|
@ -111,56 +104,55 @@ if [ "$NODE_MODE" == "1" ]; then
|
|||
echo "Initializing server configuration..."
|
||||
./ostp --init server --config config.json
|
||||
|
||||
read -p "Enter IP and port to accept incoming traffic [default: 0.0.0.0:50000]: " LISTEN_ADDR
|
||||
read -p "Listen address [default: 0.0.0.0:50000]: " LISTEN_ADDR
|
||||
if [ -n "$LISTEN_ADDR" ]; then
|
||||
sed -i "s/\"listen\": \"0.0.0.0:50000\"/\"listen\": \"$LISTEN_ADDR\"/g" config.json
|
||||
sed -i "s/\"listen\": \".*\"/\"listen\": \"$LISTEN_ADDR\"/g" config.json
|
||||
fi
|
||||
|
||||
read -p "How many access keys to generate? [default: 1]: " KEYS_COUNT
|
||||
read -p "Number of access keys [default: 1]: " KEYS_COUNT
|
||||
KEYS_COUNT=${KEYS_COUNT:-1}
|
||||
|
||||
if [ "$KEYS_COUNT" -gt 1 ]; then
|
||||
echo "Generating additional security keys..."
|
||||
echo "Generating $KEYS_COUNT access keys..."
|
||||
NEW_KEYS=$(./ostp -g -c "$KEYS_COUNT" | sed 's/^/ "/;s/$/",/' | sed '$ s/,$//')
|
||||
sed -i '/"access_keys": \[/,/\]/c\ "access_keys": [\n'"$NEW_KEYS"'\n ],' config.json
|
||||
echo "Successfully generated and wrote $KEYS_COUNT keys."
|
||||
sed -i '/\"access_keys\": \[/,/\]/c\ "access_keys": [\n'"$NEW_KEYS"'\n ],' config.json
|
||||
fi
|
||||
echo "Server configuration completed. Config file: $INSTALL_DIR/config.json"
|
||||
echo "Server configuration saved: $INSTALL_DIR/config.json"
|
||||
|
||||
elif [ "$NODE_MODE" == "2" ]; then
|
||||
echo "Initializing client configuration..."
|
||||
./ostp --init client --config config.json
|
||||
|
||||
read -p "Enter remote server address (IP:PORT): " REMOTE_SERVER
|
||||
read -p "Server address (host:port): " REMOTE_SERVER
|
||||
if [ -n "$REMOTE_SERVER" ]; then
|
||||
sed -i "s/\"server\": \"127.0.0.1:50000\"/\"server\": \"$REMOTE_SERVER\"/g" config.json
|
||||
else
|
||||
echo "[Warning] No remote address provided, keeping default (127.0.0.1:50000)."
|
||||
echo "[warn] No server address provided. Using default (127.0.0.1:50000)."
|
||||
fi
|
||||
|
||||
read -p "Enter access key (leave blank to generate automatically via ostp -g): " ACCESS_KEY
|
||||
read -p "Access key (blank to generate): " ACCESS_KEY
|
||||
if [ -z "$ACCESS_KEY" ]; then
|
||||
ACCESS_KEY=$(./ostp -g)
|
||||
echo "Automatically generated client key: $ACCESS_KEY"
|
||||
echo "Generated key: $ACCESS_KEY"
|
||||
fi
|
||||
sed -i "s/\"access_key\": \"[^\"]*\"/\"access_key\": \"$ACCESS_KEY\"/g" config.json
|
||||
|
||||
read -p "Enter local SOCKS5 listening address [default: 127.0.0.1:1088]: " SOCKS_BIND
|
||||
read -p "Local proxy address [default: 127.0.0.1:1088]: " SOCKS_BIND
|
||||
if [ -n "$SOCKS_BIND" ]; then
|
||||
sed -i "s/\"socks5_bind\": \"127.0.0.1:1088\"/\"socks5_bind\": \"$SOCKS_BIND\"/g" config.json
|
||||
fi
|
||||
echo "Client configuration completed. Config file: $INSTALL_DIR/config.json"
|
||||
echo "Client configuration saved: $INSTALL_DIR/config.json"
|
||||
|
||||
else
|
||||
echo "[Error] Invalid selection choice."
|
||||
echo "[error] Invalid selection."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Register Systemd daemon
|
||||
echo "Registering system service..."
|
||||
# Register systemd service
|
||||
echo "Registering systemd service..."
|
||||
cat <<EOF > /etc/systemd/system/ostp.service
|
||||
[Unit]
|
||||
Description=Ospab Stealth Transport Protocol Service
|
||||
Description=OSTP Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
|
|
@ -180,8 +172,7 @@ systemctl daemon-reload
|
|||
systemctl enable ostp.service >/dev/null 2>&1
|
||||
|
||||
echo "--------------------------------------------------------"
|
||||
echo "Installation completed successfully."
|
||||
echo "Configuration file saved at $INSTALL_DIR/config.json"
|
||||
echo "Service 'ostp' has been registered but not started."
|
||||
echo "Start the service manually using: systemctl start ostp"
|
||||
echo "Installation complete."
|
||||
echo " Config: $INSTALL_DIR/config.json"
|
||||
echo " Start: systemctl start ostp"
|
||||
echo "--------------------------------------------------------"
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ if [ ! -z "$EXT_SERVER" ]; then
|
|||
echo -e "2. Awaiting Cryptographic Handshake (Noise_NNpsk0)..."
|
||||
HANDSHAKE_OK=0
|
||||
for i in {1..10}; do
|
||||
if grep -q "Bridge connection established" cli.log; then
|
||||
if grep -q "Connection established" cli.log; then
|
||||
HANDSHAKE_OK=1
|
||||
break
|
||||
fi
|
||||
|
|
@ -91,8 +91,8 @@ if [ ! -z "$EXT_SERVER" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
RTT=$(grep "rtt_ms=" cli.log | tail -n 1 | awk -F'rtt_ms=' '{print $2}' | awk '{print $1}')
|
||||
echo -e "${GREEN}✓ Handshake Successful!${NC} Estimated Tunnel RTT: \033[0;33m${RTT}ms${NC}\n"
|
||||
RTT=$(grep "rtt=" cli.log | tail -n 1 | sed -E 's/.*rtt=([0-9.]+)ms.*/\1/')
|
||||
echo -e "${GREEN}Handshake successful.${NC} RTT: ${RTT}ms\n"
|
||||
|
||||
echo -e "3. Executing End-to-End HTTP Proxy Ping..."
|
||||
PING_OUTPUT=$(curl -s -o /dev/null -w "DNS: %{time_namelookup}s | Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s" -x socks5h://127.0.0.1:$SOCKS_PORT -I $HTTP_TEST_URL)
|
||||
|
|
@ -224,8 +224,8 @@ else
|
|||
fi
|
||||
|
||||
# Validate log patterns
|
||||
grep -q "Starting in SERVER mode" server_run.log
|
||||
print_result "server dynamic mode logging" $? "Expected starting sequence omitted in log"
|
||||
grep -q "Starting server" server_run.log
|
||||
print_result "server startup log" $? "Expected startup log missing"
|
||||
|
||||
# Clean up server
|
||||
kill $SRV_PID 2>/dev/null
|
||||
|
|
@ -255,8 +255,8 @@ else
|
|||
fi
|
||||
|
||||
# Verify local proxy init logging
|
||||
grep -q "Starting in CLIENT mode" client_run.log
|
||||
print_result "client local proxy pipeline logging" $? "Starting logs missing"
|
||||
grep -q "Starting client" client_run.log
|
||||
print_result "client startup log" $? "Expected startup log missing"
|
||||
|
||||
# Verify network bindings (checking if SOCKS5 port opened)
|
||||
# Try both ss and netstat, or fallback to /proc parsing
|
||||
|
|
@ -317,8 +317,8 @@ CLI_CONN_PID=$!
|
|||
sleep 3
|
||||
|
||||
# 4. Validate active handshake in client logs
|
||||
grep -q "Bridge connection established" client_conn.log
|
||||
print_result "client-server secure handshake completion" $? "Handshake signatures missing in log. Log output: $(cat client_conn.log)"
|
||||
grep -q "Connection established" client_conn.log
|
||||
print_result "client-server secure handshake" $? "Handshake failed. Log: $(cat client_conn.log)"
|
||||
|
||||
# 5. Teardown integration run
|
||||
kill $CLI_CONN_PID 2>/dev/null
|
||||
|
|
@ -391,7 +391,7 @@ SEC_UNAUTH_PID=$!
|
|||
sleep 3
|
||||
|
||||
# Verify client remained unauthorized
|
||||
grep -q "Bridge connection established" client_unauth.log
|
||||
grep -q "Connection established" client_unauth.log
|
||||
HAS_ESTABLISHED=$?
|
||||
|
||||
if [ $HAS_ESTABLISHED -ne 0 ]; then
|
||||
|
|
|
|||
Loading…
Reference in New Issue