feat(release): add Alibaba Cloud OSS distribution (#166)
This commit is contained in:
1 parent
24cea8c511
commit
2e8389f438
13 files changed
+1199
-57
No files matched your search
@@ -1,33 +1,161 @@
|
||||
# https://penguin.ooo/install.ps1 - PenguinHarness installer entry point for Windows.
|
||||
#
|
||||
# GitHub Pages cannot serve HTTP redirects, so this thin forwarder IS the
|
||||
# stable install URL: it fetches the real installer attached to the latest
|
||||
# GitHub release and runs it, forwarding every argument it was given. Usage:
|
||||
# stable install URL. It selects an immutable OSS release when that mirror is
|
||||
# available, otherwise it falls back to the matching GitHub Release, then runs
|
||||
# the real installer while forwarding every argument it was given. Usage:
|
||||
#
|
||||
# irm https://penguin.ooo/install.ps1 | iex
|
||||
# & ([scriptblock]::Create((irm https://penguin.ooo/install.ps1))) -Version v0.2.0
|
||||
#
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
try {
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
||||
} catch {
|
||||
# .NET builds where the enum is immutable already default to TLS 1.2+.
|
||||
}
|
||||
# Download fully first, then run: executing a piped stream directly would run a
|
||||
# truncated download line by line, and the real installer moves the old
|
||||
# bin/lib/web/node aside before moving the new ones in - a cut connection
|
||||
# mid-way must never leave a half-executed installer. The installer runs as an
|
||||
# in-memory script block (not a script file): script files are subject to the
|
||||
# execution policy, which is Restricted by default on client Windows - while the
|
||||
# user has already consented to remote code by piping this forwarder into iex.
|
||||
# Neither this forwarder nor the installer calls `exit`, which in iex/script-block
|
||||
# context would terminate the user's whole PowerShell session.
|
||||
$Tmp = Join-Path ([IO.Path]::GetTempPath()) "penguin-install-$PID.ps1"
|
||||
try {
|
||||
Invoke-WebRequest -Uri "https://github.com/Prism-Shadow/penguin-harness/releases/latest/download/install.ps1" -OutFile $Tmp -UseBasicParsing
|
||||
$Installer = [scriptblock]::Create((Get-Content -Path $Tmp -Raw))
|
||||
& $Installer @args
|
||||
} finally {
|
||||
Remove-Item -Force $Tmp -ErrorAction SilentlyContinue
|
||||
}
|
||||
& {
|
||||
$ForwardedArgs = @($args)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
$OssOrigin = "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com"
|
||||
$OssReleaseRoot = "$OssOrigin/releases"
|
||||
$GitHubReleaseRoot = "https://github.com/Prism-Shadow/penguin-harness/releases/download"
|
||||
$GitHubLatestBase = "https://github.com/Prism-Shadow/penguin-harness/releases/latest/download"
|
||||
|
||||
function Fail([string]$Message) {
|
||||
throw "error: $Message"
|
||||
}
|
||||
|
||||
function Test-HttpsUrl([string]$Value) {
|
||||
try { $Uri = [Uri]$Value } catch { return $false }
|
||||
return $Uri.IsAbsoluteUri -and $Uri.Scheme -eq "https"
|
||||
}
|
||||
|
||||
function Test-ReleaseTag([string]$Value) {
|
||||
return $Value -match '^v[0-9A-Za-z][0-9A-Za-z._-]*$'
|
||||
}
|
||||
|
||||
function Try-DownloadFile([string]$Uri, [string]$OutFile, [int]$TimeoutSec) {
|
||||
try {
|
||||
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -TimeoutSec $TimeoutSec
|
||||
return $true
|
||||
} catch {
|
||||
Remove-Item -LiteralPath $OutFile -Force -ErrorAction SilentlyContinue
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
||||
} catch {
|
||||
# .NET builds where the enum is immutable already default to TLS 1.2+.
|
||||
}
|
||||
|
||||
$SourceMode = if ($env:PENGUIN_DOWNLOAD_SOURCE) { $env:PENGUIN_DOWNLOAD_SOURCE.ToLowerInvariant() } else { "auto" }
|
||||
if ($SourceMode -notin @("auto", "oss", "github")) {
|
||||
Fail "PENGUIN_DOWNLOAD_SOURCE must be auto, oss, or github"
|
||||
}
|
||||
|
||||
$RequestedVersion = if ($env:PENGUIN_VERSION) { $env:PENGUIN_VERSION } else { "" }
|
||||
for ($i = 0; $i -lt $ForwardedArgs.Count; $i++) {
|
||||
if ([string]$ForwardedArgs[$i] -ieq "-Version" -and $i + 1 -lt $ForwardedArgs.Count) {
|
||||
$RequestedVersion = [string]$ForwardedArgs[$i + 1]
|
||||
$i++
|
||||
}
|
||||
}
|
||||
if ($RequestedVersion -and -not (Test-ReleaseTag $RequestedVersion)) {
|
||||
Fail "invalid release version: $RequestedVersion"
|
||||
}
|
||||
|
||||
# Download fully first, then run: executing a piped stream directly would run a
|
||||
# truncated download line by line, and the real installer moves the old
|
||||
# bin/lib/web/node aside before moving the new ones in - a cut connection
|
||||
# mid-way must never leave a half-executed installer. The installer runs as an
|
||||
# in-memory script block (not a script file): script files are subject to the
|
||||
# execution policy, which is Restricted by default on client Windows - while the
|
||||
# user has already consented to remote code by piping this forwarder into iex.
|
||||
# Neither this forwarder nor the installer calls `exit`, which in iex/script-block
|
||||
# context would terminate the user's whole PowerShell session.
|
||||
$TmpDir = Join-Path ([IO.Path]::GetTempPath()) "penguin-forwarder-$PID"
|
||||
$InstallerPath = Join-Path $TmpDir "install.ps1"
|
||||
$ManifestPath = Join-Path $TmpDir "latest.json"
|
||||
$SelectedBase = ""
|
||||
$FallbackBase = ""
|
||||
$OriginalBase = [Environment]::GetEnvironmentVariable("PENGUIN_DOWNLOAD_BASE_URL", "Process")
|
||||
$OriginalFallback = [Environment]::GetEnvironmentVariable("PENGUIN_DOWNLOAD_FALLBACK_BASE_URL", "Process")
|
||||
|
||||
try {
|
||||
if (Test-Path -LiteralPath $TmpDir) {
|
||||
Remove-Item -LiteralPath $TmpDir -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $TmpDir | Out-Null
|
||||
|
||||
if ($OriginalBase) {
|
||||
$SelectedBase = $OriginalBase.TrimEnd('/')
|
||||
$FallbackBase = if ($OriginalFallback) { $OriginalFallback.TrimEnd('/') } else { "" }
|
||||
if (-not (Test-HttpsUrl $SelectedBase)) { Fail "PENGUIN_DOWNLOAD_BASE_URL must be an absolute HTTPS URL" }
|
||||
if ($FallbackBase -and -not (Test-HttpsUrl $FallbackBase)) {
|
||||
Fail "PENGUIN_DOWNLOAD_FALLBACK_BASE_URL must be an absolute HTTPS URL"
|
||||
}
|
||||
if (-not (Try-DownloadFile "$SelectedBase/install.ps1" $InstallerPath 30)) {
|
||||
Fail "could not download the installer from the configured mirror."
|
||||
}
|
||||
} elseif ($SourceMode -eq "github") {
|
||||
$SelectedBase = if ($RequestedVersion) { "$GitHubReleaseRoot/$RequestedVersion" } else { $GitHubLatestBase }
|
||||
if (-not (Try-DownloadFile "$SelectedBase/install.ps1" $InstallerPath 30)) {
|
||||
Fail "could not download the installer from GitHub. Check your network, then retry."
|
||||
}
|
||||
} else {
|
||||
$OssTag = $RequestedVersion
|
||||
$OssBase = if ($OssTag) { "$OssReleaseRoot/$OssTag" } else { "" }
|
||||
|
||||
if (-not $OssTag -and (Try-DownloadFile "$OssOrigin/latest.json" $ManifestPath 8)) {
|
||||
try {
|
||||
$Manifest = [IO.File]::ReadAllText($ManifestPath, [Text.UTF8Encoding]::new($false)) | ConvertFrom-Json
|
||||
$CandidateTag = [string]$Manifest.tag
|
||||
$CandidateBase = ([string]$Manifest.releaseBaseUrl).TrimEnd('/')
|
||||
if ([int]$Manifest.schemaVersion -eq 1 -and
|
||||
(Test-ReleaseTag $CandidateTag) -and
|
||||
$CandidateBase -eq "$OssReleaseRoot/$CandidateTag") {
|
||||
$OssTag = $CandidateTag
|
||||
$OssBase = $CandidateBase
|
||||
}
|
||||
} catch {
|
||||
$OssTag = ""
|
||||
$OssBase = ""
|
||||
}
|
||||
}
|
||||
|
||||
if ($OssBase -and (Try-DownloadFile "$OssBase/install.ps1" $InstallerPath 30)) {
|
||||
$SelectedBase = $OssBase
|
||||
if ($SourceMode -eq "auto") {
|
||||
$FallbackBase = "$GitHubReleaseRoot/$OssTag"
|
||||
}
|
||||
} elseif ($SourceMode -eq "oss") {
|
||||
Fail "the OSS mirror is unavailable or its release metadata is invalid."
|
||||
} else {
|
||||
$SelectedBase = if ($OssTag) { "$GitHubReleaseRoot/$OssTag" } else { $GitHubLatestBase }
|
||||
if (-not (Try-DownloadFile "$SelectedBase/install.ps1" $InstallerPath 30)) {
|
||||
Fail "could not download the installer from GitHub. Check your network, then retry."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$env:PENGUIN_DOWNLOAD_BASE_URL = $SelectedBase
|
||||
if ($FallbackBase) {
|
||||
$env:PENGUIN_DOWNLOAD_FALLBACK_BASE_URL = $FallbackBase
|
||||
} else {
|
||||
Remove-Item Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL -ErrorAction SilentlyContinue
|
||||
}
|
||||
$InstallerText = [IO.File]::ReadAllText($InstallerPath, [Text.UTF8Encoding]::new($false))
|
||||
$Installer = [scriptblock]::Create($InstallerText)
|
||||
& $Installer @ForwardedArgs
|
||||
} finally {
|
||||
if ($null -eq $OriginalBase) {
|
||||
Remove-Item Env:\PENGUIN_DOWNLOAD_BASE_URL -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$env:PENGUIN_DOWNLOAD_BASE_URL = $OriginalBase
|
||||
}
|
||||
if ($null -eq $OriginalFallback) {
|
||||
Remove-Item Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$env:PENGUIN_DOWNLOAD_FALLBACK_BASE_URL = $OriginalFallback
|
||||
}
|
||||
Remove-Item -LiteralPath $TmpDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
} @args
|
||||
Reference in new issue
Block a user