Skip to content

Commit

Permalink
Merge pull request #402 from mwallner/feature/ExitOnFirstError
Browse files Browse the repository at this point in the history
(GH-382) Add command line switch 'StopOnPackageFailure'
  • Loading branch information
pauby committed Feb 26, 2020
2 parents 411515e + dd75b9a commit 34fe98e
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 29 deletions.
19 changes: 14 additions & 5 deletions Boxstarter.Bootstrapper/Init-Settings.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
if(!$Global:Boxstarter) { $Global:Boxstarter = @{} }
if(!$Boxstarter.ContainsKey('Log')) {
$Boxstarter.Log="$(Get-BoxstarterTempDir)\boxstarter.log"
if (!$Global:Boxstarter) {
$Global:Boxstarter = @{ }
}
if (!$Boxstarter.ContainsKey('Log')) {
$Boxstarter.Log = "$(Get-BoxstarterTempDir)\boxstarter.log"
}
if (!$Boxstarter.ContainsKey('RebootOk')) {
$Boxstarter.RebootOk = $false
}
if (!$Boxstarter.ContainsKey('IsRebooting')) {
$Boxstarter.IsRebooting = $false
}
if (!$Boxstarter.ContainsKey('StopOnPackageFailure')) {
$Boxstarter.StopOnPackageFailure = $false
}
if(!$Boxstarter.ContainsKey('RebootOk')) { $Boxstarter.RebootOk=$false }
if(!$Boxstarter.ContainsKey('IsRebooting')) { $Boxstarter.IsRebooting=$false }
46 changes: 33 additions & 13 deletions Boxstarter.Bootstrapper/Invoke-Boxstarter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,31 @@ Invoke-Reboot
param(
[Parameter(Position=0,Mandatory=0)]
[ScriptBlock]$ScriptToCall,

[Parameter(Position=1,Mandatory=0)]
[System.Security.SecureString]$password,

[Parameter(Position=2,Mandatory=0)]
[switch]$RebootOk,

[Parameter(Position=3,Mandatory=0)]
[string]$encryptedPassword=$null,

[Parameter(Position=4,Mandatory=0)]
[switch]$KeepWindowOpen,

[Parameter(Position=5,Mandatory=0)]
[switch]$NoPassword,

[Parameter(Position=6,Mandatory=0)]
[switch]$DisableRestart
[switch]$DisableRestart,

[Parameter(Position=7,Mandatory=0)]
[switch]$StopOnPackageFailure
)
$BoxStarter.IsRebooting = $false
$scriptFile = "$(Get-BoxstarterTempDir)\boxstarter.script"
if(!(Test-Admin)) {
if (!(Test-Admin)) {
New-Item $scriptFile -type file -value $ScriptToCall.ToString() -force | Out-Null
Write-BoxstarterMessage "User is not running with administrative rights. Attempting to elevate..."
$unNormalized=(Get-Item "$($Boxstarter.Basedir)\Boxstarter.Bootstrapper\BoxStarter.Bootstrapper.psd1")
Expand All @@ -88,20 +97,31 @@ Invoke-Reboot
}
$session=$null
try{
if(!(Get-IsRemote)){ Write-BoxstarterLogo }
$session=Start-TimedSection "Installation session." -Verbose
if($RebootOk){$Boxstarter.RebootOk=$RebootOk}
if($DisableRestart){$Boxstarter.DisableRestart=$DisableRestart}
if($encryptedPassword){$password = ConvertTo-SecureString -string $encryptedPassword}
if(!$NoPassword){
if (!(Get-IsRemote)) {
Write-BoxstarterLogo
}
$session = Start-TimedSection "Installation session." -Verbose
if($RebootOk){
$Boxstarter.RebootOk = $RebootOk
}
if ($DisableRestart) {
$Boxstarter.DisableRestart = $DisableRestart
}
if ($StopOnPackageFailure) {
$Boxstarter.StopOnPackageFailure = $StopOnPackageFailure
}
if ($encryptedPassword) {
$password = ConvertTo-SecureString -string $encryptedPassword
}
if (!$NoPassword) {
Write-BoxstarterMessage "NoPassword is false checking autologin" -verbose
$boxstarter.NoPassword=$False
$script:BoxstarterPassword=InitAutologon $password
$boxstarter.NoPassword = $False
$script:BoxstarterPassword = InitAutologon $password
}
if($script:BoxstarterPassword -eq $null) {
$boxstarter.NoPassword=$True
if ($script:BoxstarterPassword -eq $null) {
$boxstarter.NoPassword = $True
}
Write-BoxstarterMessage "NoPassword is set to $($boxstarter.NoPassword) and RebootOk is set to $($Boxstarter.RebootOk) and the NoPassword parameter passed was $NoPassword" -verbose
Write-BoxstarterMessage "NoPassword is set to $($boxstarter.NoPassword) and RebootOk is set to $($Boxstarter.RebootOk) and the NoPassword parameter passed was $NoPassword and StopOnPackageFailure is set to $($Boxstarter.StopOnPackageFailure)" -verbose
$Boxstarter.ScriptToCall = Resolve-Script $ScriptToCall $scriptFile
Stop-UpdateServices
&([ScriptBlock]::Create($Boxstarter.ScriptToCall))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ BOXSTARTER VARIABLE SETTINGS
IsRebooting
Indicates if Boxstarter has intiated a reboot.

StopOnPackageFailure
Indicates if Boxstarter will stop any further execution after a Chocolatey package failed to install

Log
This points to the path of the Boxstarter log file. By default
this is $env:LocalAppData\Boxstarter\boxstarter.log. You may
Expand Down
29 changes: 29 additions & 0 deletions Boxstarter.Chocolatey/Chocolatey.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ Intercepts Chocolatey call to check for reboots
$packageNames = -split $packageNames
Write-BoxstarterMessage "Installing $($packageNames.Count) packages" -Verbose

$stopOnFirstError = (Get-PassedSwitch -SwitchName "StopOnPackageFailure" -OrigArgs $args) -Or $Boxstarter.StopOnPackageFailure
Write-BoxstarterMessage "Will stop on first package error: $stopOnFirstError" -Verbose

foreach($packageName in $packageNames){
$PSBoundParameters.packageNames = $packageName
if((Get-PassedArg @("source", "s") $args) -eq "WindowsFeatures"){
Expand Down Expand Up @@ -191,6 +194,12 @@ Intercepts Chocolatey call to check for reboots
$rebootable = $true
} else {
Write-BoxstarterMessage "Exit Code '$errorCode' is no reason to reboot" -Verbose
if ($stopOnFirstError) {
Write-BoxstarterMessage "Exiting because 'StopOnPackageFailure' is set."
Stop-Timedsection $session
Remove-ChocolateyPackageInProgress $packageName
exit 1
}
}
}
$idx += 1
Expand All @@ -204,6 +213,26 @@ Intercepts Chocolatey call to check for reboots
}
}

function Get-PassedSwitch {
<#
.SYNOPSIS
check if a parameter/switch is present in a list of arguments
(1-to many dashes followed by the parameter name)
#>
[CmdletBinding()]
param(
# the name of the argument switch to look for in $origArgs
[Parameter(Mandatory = $True)]
[string]$SwitchName,

# the full list of original parameters (probably $args)
[Parameter(Mandatory = $True)]
[string]$OrigArgs
)
return [bool]($OrigArgs | Where-Object { $_ -match "^-+$SwitchName$" })
}

function Get-PassedArg($argName, $origArgs) {
$candidateKeys = @()
$argName | % {
Expand Down
29 changes: 27 additions & 2 deletions Boxstarter.Chocolatey/Install-BoxstarterPackage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ directory but can be changed with Set-BoxstarterConfig.
This enables remote Chocolatey installs to use the same NugetSources
as the local Boxstarter install.
.PARAMETER StopOnPackageFailure
This will stop execution immediately after a Chocolatey package fails to
install.
.NOTES
If specifying only one package, Boxstarter calls Chocolatey with the
-force argument and deletes the previously installed package directory.
Expand Down Expand Up @@ -262,26 +266,39 @@ about_boxstarter_chocolatey
param(
[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="BoxstarterConnectionConfig")]
[BoxstarterConnectionConfig[]]$BoxstarterConnectionConfig,

[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="ComputerName")]
[string[]]$ComputerName,

[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="ConnectionUri")]
[Uri[]]$ConnectionUri,

[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="Session")]
[System.Management.Automation.Runspaces.PSSession[]]$Session,

[parameter(Mandatory=$true, Position=0, ParameterSetName="Package")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="ComputerName")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="ConnectionUri")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="Session")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="BoxstarterConnectionConfig")]
[string[]]$PackageName,

[Management.Automation.PsCredential]$Credential,

[switch]$Force,

[switch]$DisableReboots,

[parameter(ParameterSetName="Package")]
[switch]$KeepWindowOpen,

[string]$LocalRepo,

[switch]$DisableRestart,
[switch]$DelegateChocoSources

[switch]$DelegateChocoSources,

[switch]$StopOnPackageFailure
)
$CurrentVerbosity=$global:VerbosePreference
try {
Expand Down Expand Up @@ -519,12 +536,20 @@ function Install-BoxstarterPackageForSession($session, $PackageName, $DisableReb
function Invoke-Locally {
param(
[string[]]$PackageName,

[Management.Automation.PsCredential]$Credential,

[switch]$Force,

[switch]$DisableReboots,

[switch]$KeepWindowOpen,

[switch]$DisableRestart,
[string]$LocalRepo

[string]$LocalRepo,

[switch]$StopOnPackageFailure
)
if($PSBoundParameters.ContainsKey("Credential")){
if($Credential -ne $null) {
Expand Down
59 changes: 50 additions & 9 deletions Boxstarter.Chocolatey/Invoke-ChocolateyBoxstarter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,20 @@ Set-BoxstarterConfig
[CmdletBinding()]
param(
[string[]]$BootstrapPackage=$null,

[string]$LocalRepo,

[switch]$DisableReboots,

[System.Security.SecureString]$Password,

[switch]$KeepWindowOpen,

[switch]$NoPassword,
[switch]$DisableRestart

[switch]$DisableRestart,

[switch]$StopOnPackageFailure
)
try{
if($DisableReboots){
Expand All @@ -133,15 +141,48 @@ Set-BoxstarterConfig
else{
Write-BoxstarterMessage "Installing Chocolatey" -Color Cyan
}
$scriptArgs=@{}
if($bootstrapPackage){$scriptArgs.bootstrapPackage=$bootstrapPackage}
if($LocalRepo){$scriptArgs.Localrepo=$localRepo}
if($DisableReboots){$scriptArgs.DisableReboots = $DisableReboots}
$script=@"
Import-Module (Join-Path "$($Boxstarter.baseDir)" BoxStarter.Chocolatey\Boxstarter.Chocolatey.psd1) -global -DisableNameChecking;
Invoke-ChocolateyBoxstarter $(if($bootstrapPackage){"-bootstrapPackage '$($bootstrapPackage -join ''',''')'"}) $(if($LocalRepo){"-LocalRepo $localRepo"}) $(if($DisableReboots){"-DisableReboots"})
$scriptStringArgs = ""

# parameters for Invoke-ChocolateyBoxstarter
if ($bootstrapPackage) {
$scriptStringArgs += "-bootstrapPackage '$($bootstrapPackage -join ''',''')' "
}
if ($DisableReboots){
$scriptStringArgs += "-DisableReboots "
}
if ($LocalRepo) {
$scriptStringArgs += "-LocalRepo $localRepo "
}

$invokeBoxstarterArgs=@{}
# parameters for Invoke-ChocolateyBoxstarter AND Invoke-Boxstarter
if ($password) {
$invokeBoxstarterArgs.password = $password
}
if ($Boxstarter.RebootOk) {
$invokeBoxstarterArgs.RebootOk = $Boxstarter.RebootOk
}
# (skipping encryptedPassword)
if ($KeepWindowOpen) {
$invokeBoxstarterArgs.KeepWindowOpen = $KeepWindowOpen
}
if ($NoPassword) {
$invokeBoxstarterArgs.NoPassword = $NoPassword
}
if ($DisableRestart){
$invokeBoxstarterArgs.DisableRestart = $DisableRestart
$scriptStringArgs += "-DisableRestart "
}
if ($StopOnPackageFailure){
$invokeBoxstarterArgs.StopOnPackageFailure = $StopOnPackageFailure
$scriptStringArgs += "-StopOnPackageFailure "
}

$script = @"
Import-Module (Join-Path -Path "$($Boxstarter.baseDir)" -ChildPath BoxStarter.Chocolatey\Boxstarter.Chocolatey.psd1) -global -DisableNameChecking; Invoke-ChocolateyBoxstarter $scriptStringArgs
"@
Invoke-Boxstarter ([ScriptBlock]::Create($script)) -RebootOk:$Boxstarter.RebootOk -password $password -KeepWindowOpen:$KeepWindowOpen -NoPassword:$NoPassword -DisableRestart:$DisableRestart

Invoke-Boxstarter -ScriptToCall ([ScriptBlock]::Create($script)) @invokeBoxstarterArgs
return
}
if(${env:ProgramFiles(x86)} -ne $null){ $programFiles86 = ${env:ProgramFiles(x86)} } else { $programFiles86 = $env:ProgramFiles }
Expand Down

0 comments on commit 34fe98e

Please sign in to comment.