fixed new target

This commit is contained in:
2026-07-28 21:29:02 +03:00
parent e7996a15ed
commit f16a365b4d
20 changed files with 2856 additions and 119 deletions
+151
View File
@@ -0,0 +1,151 @@
# collect-debs-ssh.ps1 — как collect-debs.ps1, но по SSH (для устройства БЕЗ adbd).
# Windows-хост, без WSL: SSH/SCP делаются через plink.exe / pscp.exe (PuTTY tools).
#
# Шаг 1 — снять список установленных пакетов с устройства:
# powershell -ExecutionPolicy Bypass -File collect-debs-ssh.ps1 -Step target
# -> new-installed.txt
#
# Шаг 2 — сравнить с тем, что вам давали (файл target-installed.txt из старого workflow):
# powershell -ExecutionPolicy Bypass -File collect-debs-ssh.ps1 -Step diff
#
# Шаг 3 (опционально, как -Step fetch у adb-версии) — добрать недостающие .deb:
# powershell -ExecutionPolicy Bypass -File collect-debs-ssh.ps1 -Step fetch
# нужен рядом packages.list и collect-on-device.sh (тот же файл, без изменений).
#
# Параметры подключения (по умолчанию — как вы просили):
# -HostAddr 192.168.1.52 -User linaro -Pass linaro
#
# plink.exe / pscp.exe берутся из .\bin\ рядом со скриптом (как у вас adb.exe),
# иначе — из PATH. Если ни там ни там нет — скачайте с https://www.putty.org
#
# ВАЖНО про первое подключение: plink на первый коннект спросит про host key
# ("host key is not cached... store key?"). В batch-режиме он на это ответит
# отказом и упадёт. Поэтому один раз ПЕРЕД первым запуском примите ключ вручную:
# .\bin\plink.exe -ssh linaro@192.168.1.52
# (введите "y" на вопрос про ключ, затем можно Ctrl+C — ключ сохранится в реестр)
param(
[Parameter(Mandatory = $true)][ValidateSet('target', 'diff', 'fetch')][string]$Step,
[string]$HostAddr = '192.168.1.52',
[string]$User = 'linaro',
[string]$Pass = 'linaro',
[string]$SudoPass,
[string]$OldFile, # для -Step diff, по умолчанию target-installed.txt
[string]$NewFile, # для -Step diff, по умолчанию new-installed.txt
[string]$Plink,
[string]$Pscp
)
$ErrorActionPreference = 'Continue'
$Here = Split-Path -Parent $MyInvocation.MyCommand.Path
if (-not $SudoPass) { $SudoPass = $Pass }
function Log($m) { Write-Host "[collect] $m" -ForegroundColor Green }
function Warn($m) { Write-Host "[warn] $m" -ForegroundColor Yellow }
function Die($m) { Write-Host "[error] $m" -ForegroundColor Red; exit 1 }
# plink/pscp по умолчанию берём из .\bin\ рядом со скриптом, иначе из PATH
if (-not $Plink) {
$cand = Join-Path $Here 'bin\plink.exe'
$Plink = if (Test-Path $cand) { $cand } else { 'plink' }
}
if (-not $Pscp) {
$cand = Join-Path $Here 'bin\pscp.exe'
$Pscp = if (Test-Path $cand) { $cand } else { 'pscp' }
}
foreach ($exe in @($Plink, $Pscp)) {
if (-not (Get-Command $exe -ErrorAction SilentlyContinue)) {
Die "не найден '$exe'. Положите plink.exe/pscp.exe в .\bin\ или в PATH (https://www.putty.org)"
}
}
function Write-Lf($path, [string[]]$lines) {
$text = ($lines -join "`n") + "`n"
[System.IO.File]::WriteAllText($path, $text, (New-Object System.Text.UTF8Encoding($false)))
}
function Invoke-Remote([string]$cmd) {
# plink в batch-режиме: без интерактивных вопросов (host key должен быть уже принят заранее)
$out = & $Plink -ssh -batch -pw $Pass "$User@$HostAddr" $cmd 2>&1 | Out-String
return $out
}
function Push-File([string]$local, [string]$remote) {
& $Pscp -batch -pw $Pass $local "$User@${HostAddr}:$remote" 2>&1 | Out-Null
}
function Pull-Path([string]$remote, [string]$localDir) {
& $Pscp -batch -pw $Pass -r "$User@${HostAddr}:$remote" $localDir 2>&1 | Out-Null
}
# ---------------------------------------------------------------------------
if ($Step -eq 'target') {
Log "подключаюсь к $User@$HostAddr, снимаю список установленных пакетов..."
$raw = Invoke-Remote 'dpkg-query -W | cut -f1'
$pkgs = $raw -replace "`r", '' -split "`n" | Where-Object { $_ -ne '' } | Sort-Object -Unique
if ($pkgs.Count -eq 0) { Die "не получил список пакетов (проверьте SSH-доступ / что это Debian-rootfs). Вывод:`n$raw" }
$out = Join-Path $Here 'new-installed.txt'
Write-Lf $out $pkgs
Log "сохранено $($pkgs.Count) пакетов -> $out"
Log "теперь сравните: -Step diff"
exit 0
}
# ---------------------------------------------------------------------------
if ($Step -eq 'diff') {
$old = if ($OldFile) { $OldFile } else { Join-Path $Here 'target-installed.txt' }
$new = if ($NewFile) { $NewFile } else { Join-Path $Here 'new-installed.txt' }
foreach ($f in @($old, $new)) { if (-not (Test-Path $f)) { Die "нет файла: $f" } }
$oldSet = Get-Content $old | Where-Object { $_ -ne '' } | Sort-Object -Unique
$newSet = Get-Content $new | Where-Object { $_ -ne '' } | Sort-Object -Unique
$onlyOld = $oldSet | Where-Object { $newSet -notcontains $_ }
$onlyNew = $newSet | Where-Object { $oldSet -notcontains $_ }
Write-Host "=== Есть только на СТАРОМ устройстве (в новом отсутствует), $($onlyOld.Count) шт ===" -ForegroundColor Cyan
$onlyOld | ForEach-Object { Write-Host $_ }
Write-Host ""
Write-Host "=== Есть только на НОВОМ устройстве (на старом не было), $($onlyNew.Count) шт ===" -ForegroundColor Cyan
$onlyNew | ForEach-Object { Write-Host $_ }
if ($onlyOld.Count -eq 0 -and $onlyNew.Count -eq 0) { Log "списки пакетов идентичны." }
else { Warn "списки различаются (см. выше)." }
exit 0
}
# ---------------------------------------------------------------------------
# Step 'fetch'
$pkgsList = Join-Path $Here 'packages.list'
$helper = Join-Path $Here 'collect-on-device.sh'
$tgt = Join-Path $Here 'target-installed.txt'
foreach ($f in @($pkgsList, $helper)) { if (-not (Test-Path $f)) { Die "нет файла: $f" } }
Log "проверяю доступ по SSH..."
$idOut = (Invoke-Remote 'id -u').Trim()
if (-not $idOut) { Die "не удалось подключиться к $User@$HostAddr (проверьте host key: см. комментарий в начале файла)" }
$sudo = if ($idOut -eq '0') { '' } else { Warn "$User не root — иду через sudo"; 'sudo -S' }
Log "заливаю списки и хелпер на устройство..."
Invoke-Remote 'rm -rf /tmp/btcollect && mkdir -p /tmp/btcollect' | Out-Null
Push-File $pkgsList '/tmp/btcollect/packages.list'
Push-File $helper '/tmp/btcollect/collect-on-device.sh'
if (Test-Path $tgt) { Push-File $tgt '/tmp/btcollect/target-installed.txt' }
else { Warn "нет target-installed.txt — сначала лучше прогнать -Step target" }
# на случай CRLF после Windows
Invoke-Remote "sed -i 's/\r`$//' /tmp/btcollect/* 2>/dev/null; true" | Out-Null
Log "качаю зависимости на устройстве (нужен интернет на нём)..."
$cmd = if ($sudo -ne '') {
"echo '$SudoPass' | $sudo bash /tmp/btcollect/collect-on-device.sh"
} else {
"bash /tmp/btcollect/collect-on-device.sh"
}
$output = Invoke-Remote $cmd
Write-Host $output
if ($output -notmatch 'COLLECT-OK') { Die "сбор пакетов не дошёл до COLLECT-OK" }
Log "забираю .deb на хост..."
$debs = Join-Path $Here 'debs'
if (Test-Path $debs) { Remove-Item -Recurse -Force $debs }
Pull-Path '/tmp/btdebs' $Here
Rename-Item (Join-Path $Here 'btdebs') $debs
$n = (Get-ChildItem $debs -Filter *.deb).Count
Log "готово: $n .deb в $debs"