Upload
-
View
436
Download
1
Tags:
Embed Size (px)
DESCRIPTION
10 Attentions when you make OneGet & Chocolatey packages using PowerShell
Citation preview
10 Attentions when you make OneGet & Chocolatey packages using PowerShell PowerShell study meeting vol.3 2014/07/12@oota_ken
Agenda What are OneGet and Chocolatey?
How to make Chocolatey packages
10 pitfalls when you make Chocolatey packages
What are OneGet and Chocolatey? OneGet Package manager of Windows since Windows Management Framework 5.0 Like apt-get, yum and Homebrew For native application, not for Store app not from source code, but from binary Support several repository adding plugin Current only Chocolatey repository
Chocolatey Voluntary package manager before OneGet Idempotency is ensured by Chocolatey Upload packages if you register as a developer Therefore, quality and support as chaos But, major applications are packaged c inst chrome firefox jdk8 git poshgit gradle intellijidea-community jenkins vim nodejs ruby
How to install OneGet and Chocolatey OneGet Windows Management Framework 5.0 Preview May 2014 http://www.microsoft.com/en-us/download/details.aspx?id=42936
Chocolatey Windows PowerShell – Run as administrator Set-ExecutionPolicy Unrestricted iex ((new-object
net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
How to create Chocolatey packages
Register Chocolatey account Register you https://chocolatey.org/account/Register
Get API https://chocolatey.org/account
Register API to NuGet nuget.exe setApiKey the_above_API_Key -Source
http://chocolatey.org/
Get and copy template 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
File that you must write For install packageName.nuspec tools/chocolateyInstall.ps1
For install and uninstall Add tools/chocolateyUninstall.ps1
Package definition<?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>
Definition of dependencyWrite the following description on *.nuspecChocolatey install dependency packages automatically
But, currently you can't specify version numbers <dependencies> <dependency id='gradle' /> <dependency id='maven' /> <dependency id='ant' /> </dependencies>
tools/chocolateyInstall.ps1 If application installers support silent install, you have only one line
For example, 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 Almost packages don't implement Reason https://github.com/chocolatey/chocolatey/wiki/CommandsUninstall There are no functions defined in the chocolatey Powershell module that would help
with uninstall Chocolatey support a few Cmdlets and functions for uninstall You must implement uninstall functions at each package Example of jdk8 (extracted) $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'
Package, evaluate and publish Package cpack
Evaluate install with the local package cinst jdk8 -source '%cd%'
(If you support uninstall), evaluate uninstall on local cuninst jdk8
Publish the pakcage cpush jdk8.1.8.0.05.nupkg
10 pitfalls when you create Chocolatey packages
ID and version number on *.nuspec <id>jdk8</id>
<title>Java SE 8u5 </title>
<version>8.0.5</version>
It is not PowerShell problem
id You can name freely But, users will confuse with similar
name packages java.jdk, jdk7, jdk, jdk8
version Free too Should unify for the same software
(for example, JDK or JRE) There are no collective views for
minor version up 8.0.501 for 8.0.5 minor version up?
When you can't direct install from network easily [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)
You must analyze the Web site of supplier, set certification and cookies and download the installer for local environment
You must track changes of suppliers' Web site
It is gray about license
When you call functions or Cmdlets with side effect >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
position that I fell into $dummy =
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$client = New-Object Net.WebClient etc…
PowerShell return all results of expressions with or without 'return' statements to callers
We tend to forget this behavior if you call functions or Cmdlets with expecting side effect and not are not interested in results
Answer Use [void] for methods Substitute dummy variables (ex. $dummy) for
Cmdlets
Position that I fell into [System.Net.ServicePointManager]::ServerCertificat
eValidationCallback = { $true } As result of the above statement (expression
exactly) is script block ( {$true} ), you must modify the following
$dummy = [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
No support for uninstall $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'
There are only a few helpers for uninstall
https://github.com/chocolatey/chocolatey/wiki/CommandsUninstall
helpers Uninstall-ChocolateyPackage UnInstall-ChocolateyZipPackage
Silent uninstalls are different at each software
Almost packages don't support uninstall
Therefore, there are no knowledge of uninstall
Environment variables Install-ChocolateyPath $java_bin 'Machine'
Internal implementation [Environment]::SetEnvironmentVariable('P
ath', $actualPath, $pathType)
Install-ChocolateyEnvironmentVariable 'JAVA_HOME' $java_home 'Machine'
$env:Path = $actualPath
Are changes of environment variables not reflected on the original PowerShell window?
After cinst changes environment variables, it seems the changes are not reflect on the original shell that you start cinst (cmd.exe, PowerShell)
"cinst" start new PowerShell internally and do "SetEnvironmentVariable"
Therefore, changes are not reflected on the original shell
As shell copy environment variables from the parent process on start up, you can only get the original environment variables by "GetEnvironmentVariable" after cinst
-> There are problems that environment variables are left if you run "cinst" and "cuninst" on the same shell
Figure on the next page
Environment variables
Step Windows kernelshell that start cinst
PowerShell in the cinst
PowerShell in the cuninst
new shell after running cinst
before cinst
afeter cinst key=value key=value
start new shell key=value key=value
run cuninst key=value
none!! (original environment variables) key=value
after cunsint key=value (left as gabage)
notesNo problems on this new shell
Judgment between x64 and 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 { # etc..
}
If the application support x64 and x86 version and your package want to support choices of x64 and x86, you must write the following pair logics.
Destination of x86 application on x64 OS are not same as destination of x86 application on x86 OS
It is easy to confuse
OS Application Default idestination
x64 x64 C:\Program Files
x64 x86 C:\Program Files (x86)
x86 x86 C:\Program Files
Test on OneGet Chocolatey cinst jdk8 -source '%cd%'
OneGet cpush jdk8.1.8.0.05.nupkg Install-Package jdk8 Uninstall-Package jdk8
OneGet doesn't support local install Therefore you must test by the public
package after testing on Chocolatey locally
OneGet implements Cmdlets as native DLL
As package providers of Chocolatey are implemented as DLL and not same as original Chocolatey Cmdlets that are implemented with PowerShell, you must test on each environment
If the package can't run on OneGet, users can't install the package by OneGet until you fix
Please OneGet support local install
Pair testing on 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
You must test in the following pairs
OS ChocolateyOneGet
Application
x64 Chocolatey
x64
x86
OneGet x64
x86
x86 Chocolatey
x86
OneGet x86
Run as Administrator for development improvement function Start-ChocolateyProcessAsAdmin {
# etc… $psi = new-object
System.Diagnostics.ProcessStartInfo; $psi.FileName = $exeToRun;
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,0)){
$psi.Verb = "runas"; } # etc…}
Start-ChocolateyProcessAsAdmin run "runas" internally The following dialog pop up at each
function calling Start-ChocolateyProcessAsAdmin
User Account Control Do you want to allow the following
program to make changes to this computer?
-> It is not effective to select "OK" on this dialog box each time
->Avoid this problem to start PowerShell to run cinst" and "cuninst" by "Run as Administrator"
->This leads another pitfall…
Run cinst by normal user finally function Start-ChocolateyProcessAsAdmin {
param(
[string] $statements,
[string] $exeToRun = 'powershell',
[switch] $minimized,
[switch] $noSleep,
$validExitCodes = @(0)
) # etc… if ($minimized) { $psi.WindowStyle =
[System.Diagnostics.ProcessWindowStyle]::Minimized;
} # etc…}
Start-ChocolateyProcessAsAdmin not "Run as Administrator" And Call without "$minimized = $true" Sub window opens each call Some users may close this sub window because it is
noisy I have experience to close this sub window Then, install failed because sub process exited with
error Some users sometimes this Solution Call with "$minimized = $true" But, function Install-ChocolateyPath { # etc… Start-ChocolateyProcessAsAdmin "$psArgs" # etc.. Functions of Chocolatey call without "minimized =
$true"
Conclusion OneGet & Chocolatey These package managers make easy to install native applications
at once silently But, there are only a few support for uninstall Expect for OneGet
Making packages for OneGet & Chocolatey Pair testing for OS x application x (OneGet | Chocolatey) are heavy It will be easy when they support more API (including uninstall
again) But, Let's create packages for happiness of Windows users and
developers