Chocolatey. Створення власного пакету та локальний репозиторій.

chocolatey logo
Оновлення 01/03/2021
Ком’юніті репозиторій Chocolatey містить фактично все що треба, але в той же час для деякого чисто корпоративного чи рідкісного софту треба писати самому. В нульовому наближенні це робиться якось так…

  • Інсталимо якщо ще не встановлений Chocolatey та необхідні додаткові пакети.
powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin

тут звертаємо увагу на .\chocolatey\bin бо положення може відрізнятися від версії до версії.

cinst warmup
cinst git
cinst nuget.commandline
  • Йдемо в папку з chocolate і створюємо папку packages де будуть зібрані пакети
  • Генеруємо шаблон(на прикладі Total Commander)
choco new totalcmd
cd totalcmd
  • Правимо файли totalcmd.nuspec - описовий файл в корені та файл конфігурації chocolateyinstall.ps1
  • Очищаємо файл конфігурації від всього закоментованого
$f='C:\ProgramData\chocolatey\packages\totalcmd\tools\chocolateyinstall.ps1'
gc $f | ? {$_ -notmatch "^\s*#"} | % {$_ -replace '(^.*?)\s*?[^``]#.*','$1'} | Out-File $f+".~" -en utf8; mv -fo $f+".~" $f
  • Генеруємо контрольну суму для установочного файлу.
Get-FileHash tcmd951x32_64.exe | Format-List
  • Генеруємо пакет для Chocolatey.
choco pack
  • Перевірити наявність пакету можна так:
choco list -s C:\ProgramData\chocolatey\packages
  • Тепер його можна встановлювати указавши джерело пакетів, без указання джерела його шукатиме на офіційному репозиторії.
choco install totalcmd -s C:\ProgramData\chocolatey\packages -y

Зразки файлів конфігурації totalcmd.nuspec

 <?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
  <metadata>
    <id>totalcmd</id>
    <version>9.51</version>
    <title>totalcmd (Install)</title>
    <authors>nyurch</authors>
    <projectUrl>https://www.ghisler.com/</projectUrl>
    <tags>totalcmd file manager</tags>
    <summary>file manager</summary>
    <description>file manager</description>
  </metadata>
  <files>
    <file src="tools\**" target="tools" />
  </files>
</package>

та chocolateyinstall.ps1

$ErrorActionPreference = 'Stop';
$toolsDir   = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$url        = 'C:\Users\zf\Downloads\tcmd951x32_64.exe'
файл chocolateyinstall.ps1
$packageArgs = @{
  packageName   = $env:ChocolateyPackageName
  unzipLocation = $toolsDir
  fileType      = 'EXE'
  url           = $url

  softwareName  = 'totalcmd*'

  checksum      = '2D2115049AEA04C0AF4090571F212AC553811338FA6C9EAEBFF88D6B61D35448'
  checksumType  = 'sha256'

  silentArgs    = "/AHMD`"$($env:TEMP)\$($packageName).$($env:chocolateyPackageVersion).MsiInstall.log`""
  validExitCodes= @(0, 3010, 1641)
}

Install-ChocolateyPackage @packageArgs

Тепер до основного, все це добре але хотілося б мати локальний сервер який би дзеркалив репозиторій ком’юніті плюс містив софт якого там нема. Це вирішується або покупкою корпоративних версій Chocolatey PRO чи Chocolatey Business(C4B) у яких для команди choco доступний ключ download. А можна як завжди ліпити з глини і палок, що як мінімум цікавіше :) Для цього є проект ChocolateStore. В результаті можна закачати з репозиторію потрібні програми, додати свої, надати доступ до локального репозиторію в мережі і вказувати що програми ставимо з нього

choco install totalcmd -s \\127.0.0.1\packages -y

Тепер можна добавити глини і палок щоб пакети у локальному репозиторії обновлялися наприклад раз у тиждень і маємо досить непогане рішення. Ну і можна додати свистєлок і пердєлок зліпивши наприклад на zenity графічний інтерфейс щоб ставити не весь софт, а натикати галочок напроти потрібного і поставити тільки обране.

Ще пара костилів до шоколаду.

На віддаленому ПК включити PowerShell remoting

Enable-PSRemoting -Force

Установка chocolatey на віддалений ПК(задати значення remotePC)

$Credential = Get-Credential
Invoke-Command -ComputerName remotePC -Credential $Credential -ScriptBlock {
    Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
    choco feature enable -n allowGlobalConfirmation
}

І далі

$Credential = Get-Credential
Invoke-Command -ComputerName remotePC -Credential $Credential -ScriptBlock {
    choco install program1
    choco install program2
    choco install program3
}

Хоча краще звичайно не придумувати велосипед і використовувати Ansible, мануал по якому все ще в драфті.