powershellでoneget &...
Post on 15-Jan-2015
1.117 Views
Preview:
DESCRIPTION
TRANSCRIPT
PowerShell で One-Get & Chocolateyパッケージを作るときに気を付ける 10 のこと第 3 回 PowerShell 勉強会 2014/07/12@oota_ken
アジェンダ OneGet と Chocolatey とは? Chocolatey のパッケージの作り方 Chocolatey パッケージを作るときの 10 の地雷
OneGet と Chocolatey とは? OneGet Windows Management Framework 5.0( 現在は Preview) から追加される Microsoft 謹製のパッケージマネー
ジャー apt-get や yum, Homebrew のようなもの Store アプリではなく、既存のネイティブアプリが対象 但し、ソースからではなく、バイナリでインストール、アンインストール プラグインを追加することで複数のリポジトリをサポート 但し、現状は後述の Chocolatey のリポジトリのみ Chocolatey OneGet 以前に有志により開発されたオープンなパッケージマネージャー インストール済みのものをインストールしないなど「冪等性」については、 Chocolatey が担保してくれます 開発者登録すれば自由にパッケージをアップできます 故に、品質やサポートが玉石混淆です とはいえ、ブラウザからコマンド、開発ツールまで一通り揃っています c inst chrome firefox jdk8 git poshgit gradle intellijidea-community jenkins vim nodejs ruby
OneGet と Chocolatey のインストール OneGet Windows Management Framework 5.0 Preview May 2014 http://www.microsoft.com/en-us/download/details.aspx?id=42936 コントロール パネル \ すべてのコントロール パネル項目 \ 言語 "English" にしないとインストールがこけます Chocolatey Windows PowerShell – 管理者として実行 Set-ExecutionPolicy Unrestricted iex ((new-object
net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
Chocolatey パッケージの作り方
Chocolatey アカウントの作成 アカウント情報の登録 https://chocolatey.org/account/Register
API キーの取得 https://chocolatey.org/account
API キーの登録 nuget.exe setApiKey 上記 URL から取得した API キー -Source
http://chocolatey.org/
ひな形の取得とコピー cinst warmup git nuget.commandline
cd %ChocolateyInstall%
git clone [[https://github.com/chocolatey/chocolateytemplates.git]]
cd chocolateytemplates\\\_templates
warmup addTemplateFolder chocolatey "%CD%\chocolatey"
warmup chocolatey jdk8
最低限記述が必要なファイル インストールのみ パッケージ名 .nuspec tools/chocolateyInstall.ps1
アンインストールもサポート 上記に加えて、 tools/chocolateyUninstall.ps1
パッケージ定義<?xml version="1.0"?><package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>jdk8</id> <title>Java SE 8u5 </title> <version>8.0.5</version> <authors>Sun Microsystems/Oracle Corporation</authors> <owners>oota_ken</owners> <summary>The Java Development Kit (JDK) version 8.0.5</summary> <description>The Java Development Kit (JDK) version 8.0.5</description> <projectUrl>http://www.oracle.com/technetwork/java/javase/downloads/index.html</projectUrl> <tags>java jdk</tags> <licenseUrl>http://www.oracle.com/technetwork/java/javase/terms/license/index.html</licenseUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <iconUrl>https://raw.githubusercontent.com/carolynvs/chocolatey-packages/master/Java.JDK/java-logo.jpg</iconUrl> </metadata> <files> <file src="tools\**" target="tools" /> </files></package>
依存関係の定義*.nuspec に下記のように依存関係を定義すると、 apt や brew のように最初のパッケージを指定してあげるだけで、芋づる式にパッケージがインストールされます但し、バージョン番号とか細かい制御はできないようです <dependencies> <dependency id='gradle' /> <dependency id='maven' /> <dependency id='ant' /> </dependencies>
tools/chocolateyInstall.ps1 サイレントインストール対応のアプリケーションだと実質 1 行で済みます 例えば、 JetBrains IntelliJ IDEA - Community Edition $name = "intellijidea-community" $url = "http://download.jetbrains.com/idea/ideaIC-13.1.2.exe" $kind = "EXE" $silent = "/S" Install-ChocolateyPackage $name $kind $silent $url
tools/chocolateyUninstall.ps1 現状の殆どのパッケージでは実装されていません 理由 https://github.com/chocolatey/chocolatey/wiki/CommandsUninstall There are no functions defined in the chocolatey powershell module that would help
with uninstall Chocolatey 側ではアンインストールには最小限のコマンドレット or 関数しか用意されてい
ません パッケージ毎に個別に実装する必要があります jdk8 例 ( 抜粋 ) $jdk = "/qn /x {64A3A4F4-B792-11D6-A78A-00B0D0" + $uninstall_id + "0}" Start-ChocolateyProcessAsAdmin $jdk 'msiexec' $java_bin = get-java-bin Uninstall-ChocolateyPath $java_bin 'Machine'
パッケージ化と検証、発行 パッケージ化 cpack
ローカルインストールで検証 cinst jdk8 -source '%cd%'
( アンインストールをサポートしている場合 ) ローカルアンインストールで検証
cuninst jdk8
パッケージを発行する cpush jdk8.1.8.0.05.nupkg
Chocolatey パッケージを作るときの 10の地雷
*.nuspec での ID とバージョン番号 <id>jdk8</id>
<title>Java SE 8u5 </title>
<version>8.0.5</version>
PowerShell ではありませんが・・・ id 基本的に自由につけられます が、同じようなものが乱立しており、
もめてます java.jdk, jdk7, jdk, jdk8
version JDK, JRE 内で統一の動きがあります パッケージ自体のマイナーバージョ
ンアップに統一見解がないです 8.0.501 とか?
直ダウンロードインストールが簡単にできない場合 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$client = New-Object Net.WebClient
$client.Headers.Add('Cookie', 'gpw_e24=http://www.oracle.com; oraclelicense=accept-securebackup-cookie')
$client.DownloadFile($url, $output_filename)
提供元の Web サイトを解析して、認証やクッキーの設定をした上で、ローカルにダウンロードする必要があります
提供元の Web サイトの仕様変更があっても、文句は言えず、仕様変更に追従する必要があります
ライセンス上 OK なのか怪しいところもあります
副作用のある関数やコマンドレットを呼び出している場合 >function add($a, $b) { return $a + $b; }
> function call_add { add 1 2; add 2 3; return 6 }
C:\Users\KenichiroOta> call_add
3
5
6
嵌まった場所 $dummy =
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$client = New-Object Net.WebClient 以下略
PowerShell では、 return 文以外でも、値はすべて関数の結果として返されます
結果ではなく副作用の動作を期待して、関数やコマンドレットを呼んでいる場合に忘れがちです
対応 メソッド:呼び出し [void] で打ち消します コマンドレット: $dummy とかに代入します 嵌まった場所 [System.Net.ServicePointManager]::ServerCerti
ficateValidationCallback = { $true } 実はこの代入文の戻り値はコールバックのスクリプ
トブロックですので下記のような修正が必要です $dummy =
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
アンインストールサポートの欠如 $use64bit = use64bit
if ($use64bit) { $jdk = "/qn /x {64A3A4F4-B792-11D6-A78A-
00B0D0" + $uninstall_id + "0}" $jre = "/qn /x {26A24AE4-039D-4CA4-87B4-
2F864" + $uninstall_id + "FF}"
} else { $jdk = "/qn /x {32A3A4F4-B792-11D6-A78A-
00B0D0" + $uninstall_id + "0}" $jre = "/qn /x {26A24AE4-039D-4CA4-87B4-
2F832" + $uninstall_id + "FF}"
}
Start-ChocolateyProcessAsAdmin $jdk 'msiexec'
Start-ChocolateyProcessAsAdmin $jre 'msiexec'
アンインストールに関するヘルパーが殆どありません
https://github.com/chocolatey/chocolatey/wiki/CommandsUninstall
サポートしている Helper Uninstall-ChocolateyPackage UnInstall-ChocolateyZipPackage
サイレントアンインストールはソフトウェアによってバラバラです
殆どのパッケージでアンインストールをサポートしていません
→上記よりアンインストールの実装のノウハウが不足しています
環境変数の取り扱い Install-ChocolateyPath $java_bin 'Machine'
内部実装 [Environment]::SetEnvironmentVariabl
e('Path', $actualPath, $pathType)
Install-ChocolateyEnvironmentVariable 'JAVA_HOME' $java_home 'Machine'
$env:Path = $actualPath
環境変数の変更が反映されてない ??
cinst でインストールして、環境変数を書き換えたのに、元のシェル ( コマンドプロンプト、 PowerShell) 上では環境変数の変更が反映されていません
cinst は新たに PowerShell を起動して、その中で SetEnvironmentVariable しています
従って、親のシェルには反映されません 親のシェルはそのシェルの起動時に環境変数を親プ
ロセスからコピーするため、 cinst 後、再度GetEnvironmentVraible しても、更新後の環境変数の値が取得できません
→現実にはレアケースですが、同じシェルのまま、 cinst, cuninst すると環境変数の残骸が残るという面倒なことが起きます
分かりにくいので次ページの図で
環境変数の取り扱いステップ Windows本体
cinstを起動したシェル
cinst内部のPowerShell
cuninst内部のPowerShell
cinst後起動したシェル
cinst 前
cinst 後 key=value key=value
シェルもう一つ起動 key=value key=value
cuninst を起動 key=value
ない!! (cinst を起動したシェルを引き継ぐ ) key=value
cunsint 後 key=value (残骸として残る )
※このシェルでcuninst を起動すれば問題ない
※このシェルでcuninst を起動すれば問題ない
x64, x86 の判断 function use64bit() {
$is64bitOS = (Get-WmiObject –Class Win32_ComputerSystem).SystemType -match ‘(x64)’
return $is64bitOS
}
if ($use64bit) { $jdk = "/qn /x {64A3A4F4-B792-11D6-
A78A-00B0D0" + $uninstall_id + "0}" $jre = "/qn /x {26A24AE4-039D-4CA4-
87B4-2F864" + $uninstall_id + "FF}"
} else { # 略 }
アプリケーションが x64版、 x86版の方を用意している場合、オプションインストールのサポートを含めると、最悪以下の組合せ毎にロジックを書く必要があります
x64 OS に x86 アプリケーションを入れた先と x86 OS に x86アプリケーションを入れた先が異なるのがロジックミスをしやすく要注意です
OS アプリケーション 標準インストール先x64 x64 C:\Program Files
x64 x86 C:\Program Files (x86)
x86 x86 C:\Program Files
OneGet でのテスト Chocolatey cinst jdk8 -source '%cd%'
OneGet cpush jdk8.1.8.0.05.nupkg Install-Package jdk8 Uninstall-Package jdk8
OneGet ではローカルインストール検証のサポートは現状ありません
Chocolatey でローカル検証した後、本番アップして検証する綱渡りです
後述しますが、 OneGet では各コマンドはネイティブ実装 (DLL) されています
Chocolatey のパッケージ・プロバイダーもDLL で実装されており、 PowerShell で実装されているオリジナルの Chocolatey の挙動と微妙に異なるところがあり、検証は必須です
OneGet で正常に動作しないと、その間の本番パッケージは OneGet でインストールできない状態になるので注意が必要です
正式版の OneGet の改善を望みます
x64, x86 * Chocolatey, OneGetのテスト Chocolatey * x64, x86 cinst jdk8 –source '%cd%' cunint jdk8
OneGet cpush jdk8.1.8.0.05.nupkg Install-Package jdk8 Uninstall-Package jdk8
下記の組合せテストが必要ですOS Chocolat
eyOneGet
アプリ
x64 Chocolatey
x64
x86
OneGet x64
x86
x86 Chocolatey
x86
OneGet x86
開発効率のための管理者として実行 function Start-ChocolateyProcessAsAdmin {
# 略 $psi = new-object
System.Diagnostics.ProcessStartInfo; $psi.FileName = $exeToRun;
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,0)){
$psi.Verb = "runas"; } # 略}
Start-ChocolateyProcessAsAdmin
内部で runas しています Start-ChocolateyProcessAsAdmin を
呼び出している functionごとに、以下のダイアログがでます
ユーザーアカウント制御 次のプログラムにこのコンピュータへの変
更を許可しますか? →ダイアログボックスを手動で "OK" す
る必要があり、開発効率が悪いです →親プロセスの PowerShell を「管理者
として実行する」で起動して回避します →これで効率化すると次の地雷が・・・
最終実行は通常実行 function Start-ChocolateyProcessAsAdmin {
param(
[string] $statements,
[string] $exeToRun = 'powershell',
[switch] $minimized,
[switch] $noSleep,
$validExitCodes = @(0)
) # 略 if ($minimized) { $psi.WindowStyle =
[System.Diagnostics.ProcessWindowStyle]::Minimized;
} # 略}
Start-ChocolateyProcessAsAdmin not 「管理者として実行」 かつ $minimized = $true で呼び出さないと 呼び出す度にサブウィンドウが開きます 難解も開くのがウザいので間違って閉じてしまう可能性が
あります というか、じぶんでやってしまいました そうすると、サブプロセスがエラー Exit でインストールが
失敗します ユーザーがやってしまいがちです 対処方法 $minimized = $true で呼びます ・・・が、 function Install-ChocolateyPath { # 略 Start-ChocolateyProcessAsAdmin "$psArgs" # 略 Chocolatey の関数自体が minimzed = $true してません
まとめ OneGet & Chocolatey ネイティブアプリの一括インストールは劇的に楽になりました ただし、アンインストールのサポートが殆ど無いです OneGet の今後の整備に期待します OneGet & Chocolatey のパッケージ作り OS x アプリ x (OneGet | Chocolatey) の組合せテストが大変です もうちょっと、アンインストール系を始め API が充実して欲しいです とはいえ、色々整備されると嬉しいのでみんな作ってみましょう (震え声 )
top related