fix: improve wechat collector deploy visibility
This commit is contained in:
@@ -107,6 +107,11 @@ personalWechatIngress:
|
||||
context: src/components/platform-infra/personal-wechat-collector
|
||||
dockerfile: src/components/platform-infra/personal-wechat-collector/Dockerfile
|
||||
wcferryVersion: 39.5.2.0
|
||||
pip:
|
||||
indexUrl: http://mirrors.aliyun.com/pypi/simple/
|
||||
trustedHost: mirrors.aliyun.com
|
||||
timeoutSeconds: 120
|
||||
retries: 8
|
||||
wcfHost: 172.26.16.1
|
||||
commandPort: 10086
|
||||
messagePort: 10087
|
||||
|
||||
@@ -97,7 +97,15 @@ interface WechatArchiveConfig {
|
||||
createNamespace: boolean;
|
||||
workload: { kind: string; name: string; serviceAccountName: string; replicas: number; containerName: string };
|
||||
storage: { kind: string; name: string; mountPath: string; size: string; create: boolean };
|
||||
image: { repository: string; tag: string; pullPolicy: string; context: string; dockerfile: string; wcferryVersion: string };
|
||||
image: {
|
||||
repository: string;
|
||||
tag: string;
|
||||
pullPolicy: string;
|
||||
context: string;
|
||||
dockerfile: string;
|
||||
wcferryVersion: string;
|
||||
pip: { indexUrl: string; trustedHost: string; timeoutSeconds: number; retries: number };
|
||||
};
|
||||
wcfHost: string;
|
||||
commandPort: number;
|
||||
messagePort: number;
|
||||
@@ -819,11 +827,17 @@ function windowsScriptSyncAndStartPrepareScript(_archive: WechatArchiveConfig):
|
||||
$StateRoot = ${psSingleQuote(stateRoot)}
|
||||
New-Item -ItemType Directory -Force $StateRoot | Out-Null
|
||||
if (Test-Path ${psSingleQuote(resultFile)}) { Remove-Item -Force ${psSingleQuote(resultFile)} }
|
||||
$proc = Start-Process -FilePath "powershell.exe" -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File",${psSingleQuote(prepare)}) -WindowStyle Hidden -PassThru -RedirectStandardOutput ${psSingleQuote(stdout)} -RedirectStandardError ${psSingleQuote(stderr)}
|
||||
$Wrapper = Join-Path $StateRoot "prepare-runner.cmd"
|
||||
@"
|
||||
@echo off
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${prepare}" > "${stdout}" 2> "${stderr}"
|
||||
"@ | Set-Content -Encoding ASCII $Wrapper
|
||||
$cmd = '/c start "" /min "' + $Wrapper + '"'
|
||||
$proc = Start-Process -FilePath "cmd.exe" -ArgumentList $cmd -WindowStyle Hidden -PassThru
|
||||
[pscustomobject]@{
|
||||
ok = $true
|
||||
started = $true
|
||||
pid = $proc.Id
|
||||
launcherPid = $proc.Id
|
||||
opsRoot = $OpsRoot
|
||||
stdout = ${psSingleQuote(stdout)}
|
||||
stderr = ${psSingleQuote(stderr)}
|
||||
@@ -1027,7 +1041,13 @@ import json, sys, time
|
||||
payload = {"ok": False, "status": "running", "startedAt": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "image": "${image}", "logs": {"build": sys.argv[2], "push": sys.argv[3]}}
|
||||
open(sys.argv[1], "w", encoding="utf-8").write(json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
PY
|
||||
docker build --build-arg WCFERRY_VERSION=${shQuote(ingress.collector.image.wcferryVersion)} -t ${shQuote(image)} "$job_dir" >"$build_log" 2>&1
|
||||
docker build \\
|
||||
--build-arg WCFERRY_VERSION=${shQuote(ingress.collector.image.wcferryVersion)} \\
|
||||
--build-arg PIP_INDEX_URL=${shQuote(ingress.collector.image.pip.indexUrl)} \\
|
||||
--build-arg PIP_TRUSTED_HOST=${shQuote(ingress.collector.image.pip.trustedHost)} \\
|
||||
--build-arg PIP_TIMEOUT_SECONDS=${shQuote(String(ingress.collector.image.pip.timeoutSeconds))} \\
|
||||
--build-arg PIP_RETRIES=${shQuote(String(ingress.collector.image.pip.retries))} \\
|
||||
-t ${shQuote(image)} "$job_dir" >"$build_log" 2>&1
|
||||
build_rc=$?
|
||||
if [ "$build_rc" -eq 0 ]; then
|
||||
docker push ${shQuote(image)} >"$push_log" 2>&1
|
||||
@@ -1399,6 +1419,7 @@ function parsePersonalWechatIngress(raw: Record<string, unknown>): WechatArchive
|
||||
const workload = recordField(collector, "workload", `${configLabel}.personalWechatIngress.collector`);
|
||||
const storage = recordField(collector, "storage", `${configLabel}.personalWechatIngress.collector`);
|
||||
const image = recordField(collector, "image", `${configLabel}.personalWechatIngress.collector`);
|
||||
const pip = recordField(image, "pip", `${configLabel}.personalWechatIngress.collector.image`);
|
||||
const readOnly = recordField(collector, "readOnly", `${configLabel}.personalWechatIngress.collector`);
|
||||
const poc = recordField(raw, "poc", `${configLabel}.personalWechatIngress`);
|
||||
return {
|
||||
@@ -1460,6 +1481,12 @@ function parsePersonalWechatIngress(raw: Record<string, unknown>): WechatArchive
|
||||
context: stringField(image, "context", `${configLabel}.personalWechatIngress.collector.image`),
|
||||
dockerfile: stringField(image, "dockerfile", `${configLabel}.personalWechatIngress.collector.image`),
|
||||
wcferryVersion: stringField(image, "wcferryVersion", `${configLabel}.personalWechatIngress.collector.image`),
|
||||
pip: {
|
||||
indexUrl: stringField(pip, "indexUrl", `${configLabel}.personalWechatIngress.collector.image.pip`),
|
||||
trustedHost: stringField(pip, "trustedHost", `${configLabel}.personalWechatIngress.collector.image.pip`),
|
||||
timeoutSeconds: numberField(pip, "timeoutSeconds", `${configLabel}.personalWechatIngress.collector.image.pip`),
|
||||
retries: numberField(pip, "retries", `${configLabel}.personalWechatIngress.collector.image.pip`),
|
||||
},
|
||||
},
|
||||
wcfHost: stringField(collector, "wcfHost", `${configLabel}.personalWechatIngress.collector`),
|
||||
commandPort: numberField(collector, "commandPort", `${configLabel}.personalWechatIngress.collector`),
|
||||
@@ -1574,6 +1601,12 @@ function personalWechatIngressSummary(config: WechatArchiveConfig["personalWecha
|
||||
context: config.collector.image.context,
|
||||
dockerfile: config.collector.image.dockerfile,
|
||||
wcferryVersion: config.collector.image.wcferryVersion,
|
||||
pip: {
|
||||
indexUrl: config.collector.image.pip.indexUrl,
|
||||
trustedHost: config.collector.image.pip.trustedHost,
|
||||
timeoutSeconds: config.collector.image.pip.timeoutSeconds,
|
||||
retries: config.collector.image.pip.retries,
|
||||
},
|
||||
},
|
||||
wcfHost: config.collector.wcfHost,
|
||||
commandPort: config.collector.commandPort,
|
||||
|
||||
@@ -6,18 +6,44 @@ $WcfRoot = Join-Path $Root "wcf\v39.5.2"
|
||||
$StateRoot = Join-Path $Root "wcf-state"
|
||||
$DownloadRoot = Join-Path $Root "downloads"
|
||||
$PrepareResult = Join-Path $StateRoot "prepare-result.json"
|
||||
$ProgressLog = Join-Path $StateRoot "prepare-progress.log"
|
||||
$Python = "C:\ProgramData\miniconda3\python.exe"
|
||||
$PipIndex = "http://mirrors.aliyun.com/pypi/simple/"
|
||||
$ReleaseBase = "https://github.com/lich0821/WeChatFerry/releases/download/v39.5.2"
|
||||
|
||||
New-Item -ItemType Directory -Force $WechatRoot,$WcfRoot,$StateRoot,$DownloadRoot | Out-Null
|
||||
$StartedAt = (Get-Date).ToUniversalTime().ToString("o")
|
||||
|
||||
function Write-PrepareProgress {
|
||||
param([string]$Message)
|
||||
Add-Content -Encoding utf8 -Path $ProgressLog -Value "$((Get-Date).ToUniversalTime().ToString("o")) $Message"
|
||||
}
|
||||
|
||||
trap {
|
||||
$message = $_.Exception.Message
|
||||
Write-PrepareProgress "error $message"
|
||||
$failed = [ordered]@{
|
||||
ok = $false
|
||||
startedAt = $StartedAt
|
||||
finishedAt = (Get-Date).ToUniversalTime().ToString("o")
|
||||
root = $Root
|
||||
stateRoot = $StateRoot
|
||||
python = $Python
|
||||
error = $message
|
||||
valuesPrinted = $false
|
||||
}
|
||||
$failed | ConvertTo-Json -Depth 6 | Set-Content -Encoding utf8 $PrepareResult
|
||||
exit 1
|
||||
}
|
||||
|
||||
function Download-IfMissing {
|
||||
param([string]$Url, [string]$Path)
|
||||
if (Test-Path $Path) { return }
|
||||
Write-PrepareProgress "download-start $Url"
|
||||
$tmp = "$Path.part"
|
||||
Invoke-WebRequest -Uri $Url -OutFile $tmp -UseBasicParsing
|
||||
Move-Item -Force $tmp $Path
|
||||
Write-PrepareProgress "download-done $Path"
|
||||
}
|
||||
|
||||
function Find-WeChatExe {
|
||||
@@ -32,7 +58,7 @@ function Find-WeChatExe {
|
||||
return $null
|
||||
}
|
||||
|
||||
$startedAt = (Get-Date).ToUniversalTime().ToString("o")
|
||||
Write-PrepareProgress "prepare-start"
|
||||
$installer = Join-Path $DownloadRoot "WeChatSetup-3.9.12.51.exe"
|
||||
Download-IfMissing "$ReleaseBase/WeChatSetup-3.9.12.51.exe" $installer
|
||||
Download-IfMissing "$ReleaseBase/sdk.dll" (Join-Path $WcfRoot "sdk.dll")
|
||||
@@ -45,8 +71,10 @@ if (!(Test-Path $Python)) {
|
||||
|
||||
$pipOut = Join-Path $StateRoot "prepare-pip.stdout.log"
|
||||
$pipErr = Join-Path $StateRoot "prepare-pip.stderr.log"
|
||||
Write-PrepareProgress "pip-install-start"
|
||||
& $Python -m pip install --trusted-host mirrors.aliyun.com --index-url $PipIndex "wcferry==39.5.2.0" > $pipOut 2> $pipErr
|
||||
if ($LASTEXITCODE -ne 0) { throw "pip install wcferry failed" }
|
||||
Write-PrepareProgress "pip-install-done"
|
||||
|
||||
Copy-Item -Force "$PSScriptRoot\wcf_host.py" (Join-Path $WcfRoot "wcf_host.py")
|
||||
|
||||
@@ -70,8 +98,10 @@ $installStderr = Join-Path $StateRoot "prepare-wechat-installer.stderr.log"
|
||||
if (-not $wechatExe) {
|
||||
$installAttempted = $true
|
||||
$args = @("/S", "/D=$WechatRoot")
|
||||
Write-PrepareProgress "wechat-install-start $installer"
|
||||
$proc = Start-Process -FilePath $installer -ArgumentList $args -Wait -PassThru -RedirectStandardOutput $installStdout -RedirectStandardError $installStderr -WindowStyle Hidden
|
||||
$installExitCode = $proc.ExitCode
|
||||
Write-PrepareProgress "wechat-install-exit $installExitCode"
|
||||
Start-Sleep -Seconds 5
|
||||
$wechatExe = Find-WeChatExe
|
||||
}
|
||||
@@ -93,7 +123,7 @@ $pyProbe = $pyProbeJson | ConvertFrom-Json
|
||||
|
||||
$summary = [ordered]@{
|
||||
ok = [bool]($pyProbe.ok -and $wechatExe)
|
||||
startedAt = $startedAt
|
||||
startedAt = $StartedAt
|
||||
finishedAt = (Get-Date).ToUniversalTime().ToString("o")
|
||||
root = $Root
|
||||
wechatInstaller = $installer
|
||||
@@ -111,5 +141,6 @@ $summary = [ordered]@{
|
||||
wcferryVersion = $pyProbe.wcferryVersion
|
||||
next = if ($wechatExe) { "Run start.ps1 and scan the WeChat login QR." } else { "WeChat silent install did not produce WeChat.exe; run the installer UI from the interactive Windows session, then re-run prepare.ps1." }
|
||||
}
|
||||
Write-PrepareProgress "prepare-done ok=$($summary.ok)"
|
||||
$summary | ConvertTo-Json -Depth 6 | Set-Content -Encoding utf8 $PrepareResult
|
||||
$summary | ConvertTo-Json -Depth 6
|
||||
|
||||
@@ -5,6 +5,9 @@ $StateRoot = Join-Path $Root "wcf-state"
|
||||
$PidFile = Join-Path $StateRoot "wcf-host.pid"
|
||||
$StatusFile = Join-Path $StateRoot "status.json"
|
||||
$PrepareResultFile = Join-Path $StateRoot "prepare-result.json"
|
||||
$PrepareStdout = Join-Path $StateRoot "prepare.stdout.log"
|
||||
$PrepareStderr = Join-Path $StateRoot "prepare.stderr.log"
|
||||
$PrepareProgress = Join-Path $StateRoot "prepare-progress.log"
|
||||
$Stdout = Join-Path $StateRoot "wcf-host.stdout.log"
|
||||
$Stderr = Join-Path $StateRoot "wcf-host.stderr.log"
|
||||
function Read-JsonFile {
|
||||
@@ -31,12 +34,25 @@ if (Test-Path $PidFile) {
|
||||
}
|
||||
$status = Read-JsonFile $StatusFile
|
||||
$prepare = Read-JsonFile $PrepareResultFile
|
||||
$prepareProc = Get-Process -Name powershell -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Path -like "*powershell*" -or $_.ProcessName -like "*powershell*" } |
|
||||
Sort-Object StartTime -Descending |
|
||||
Select-Object -First 5 Id,ProcessName,StartTime
|
||||
[pscustomobject]@{
|
||||
ok = $true
|
||||
pid = $pidValue
|
||||
running = $running
|
||||
prepared = if ($prepare) { [bool]$prepare.ok } else { $false }
|
||||
prepare = $prepare
|
||||
prepareRuntime = [ordered]@{
|
||||
candidateProcesses = $prepareProc
|
||||
stdout = $PrepareStdout
|
||||
stderr = $PrepareStderr
|
||||
progress = $PrepareProgress
|
||||
stdoutTail = Tail-Text $PrepareStdout
|
||||
stderrTail = Tail-Text $PrepareStderr
|
||||
progressTail = Tail-Text $PrepareProgress
|
||||
}
|
||||
status = $status
|
||||
ports = Get-NetTCPConnection -LocalPort 10086,10087 -ErrorAction SilentlyContinue | Select-Object LocalAddress,LocalPort,State,OwningProcess
|
||||
logs = [ordered]@{
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
FROM python:3.12-alpine
|
||||
|
||||
ARG WCFERRY_VERSION=39.5.2.0
|
||||
ARG PIP_INDEX_URL=http://mirrors.aliyun.com/pypi/simple/
|
||||
ARG PIP_TRUSTED_HOST=mirrors.aliyun.com
|
||||
ARG PIP_TIMEOUT_SECONDS=120
|
||||
ARG PIP_RETRIES=8
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& python -m pip install --no-cache-dir --trusted-host mirrors.aliyun.com \
|
||||
--index-url http://mirrors.aliyun.com/pypi/simple/ \
|
||||
&& python -m pip install --no-cache-dir \
|
||||
--trusted-host "${PIP_TRUSTED_HOST}" \
|
||||
--index-url "${PIP_INDEX_URL}" \
|
||||
--timeout "${PIP_TIMEOUT_SECONDS}" \
|
||||
--retries "${PIP_RETRIES}" \
|
||||
"wcferry==${WCFERRY_VERSION}" \
|
||||
&& python - <<'PY'
|
||||
import importlib.metadata
|
||||
|
||||
Reference in New Issue
Block a user