mirror of
https://github.com/saltstack/salt-bootstrap.git
synced 2025-04-16 09:40:21 +00:00
Fix script to support installing RC on Windows
This commit is contained in:
parent
e05d70558f
commit
a0c99153f9
1 changed files with 206 additions and 141 deletions
|
@ -5,23 +5,18 @@
|
|||
.DESCRIPTION
|
||||
The script will download the official Salt package from SaltProject. It will
|
||||
install a specific package version and accept parameters for the master and
|
||||
minion ids. Finally, it can stop and set the Windows service to "manual" for
|
||||
minion IDs. Finally, it can stop and set the Windows service to "manual" for
|
||||
local testing.
|
||||
|
||||
.EXAMPLE
|
||||
./bootstrap-salt.ps1
|
||||
Runs without any parameters. Uses all the default values/settings.
|
||||
Runs without any parameters. Uses all the default values/settings. Will
|
||||
install the latest version of Salt
|
||||
|
||||
.EXAMPLE
|
||||
./bootstrap-salt.ps1 -version 2017.7.0
|
||||
./bootstrap-salt.ps1 -version 3006.7
|
||||
Specifies a particular version of the installer.
|
||||
|
||||
.EXAMPLE
|
||||
./bootstrap-salt.ps1 -pythonVersion 3
|
||||
Specifies the Python version of the installer. Can be "2" or "3". Defaults
|
||||
to "2". Python 3 installers are only available for Salt 2017.7.0 and newer.
|
||||
Starting with Python 3002 only Python 3 installers are available.
|
||||
|
||||
.EXAMPLE
|
||||
./bootstrap-salt.ps1 -runservice false
|
||||
Specifies the salt-minion service to stop and be set to manual. Useful for
|
||||
|
@ -33,33 +28,9 @@
|
|||
installer values of host name for the minion id and "salt" for the master.
|
||||
|
||||
.EXAMPLE
|
||||
./bootstrap-salt.ps1 -minion minion-box -master master-box -version 2017.7.0 -runservice false
|
||||
./bootstrap-salt.ps1 -minion minion-box -master master-box -version 3006.7 -runservice false
|
||||
Specifies all the optional parameters in no particular order.
|
||||
|
||||
.PARAMETER version
|
||||
The version of the Salt minion to install. Default is "latest" which will
|
||||
install the latest version of Salt minion available.
|
||||
|
||||
.PARAMETER pythonVersion
|
||||
The version of Python the installer should use. Specify either "2" or "3".
|
||||
Beginning with Salt 2017.7.0, Salt will run on either Python 2 or Python 3.
|
||||
The default is Python 2 if not specified. This parameter only works for Salt
|
||||
|
||||
.PARAMETER runservice
|
||||
Boolean flag to start or stop the minion service. True will start the minion
|
||||
service. False will stop the minion service and set it to "manual". The
|
||||
installer starts it by default.
|
||||
|
||||
.PARAMETER minion
|
||||
Name of the minion being installed on this host. Installer defaults to the
|
||||
host name.
|
||||
|
||||
.PARAMETER master
|
||||
Name or IP of the master server. Installer defaults to "salt".
|
||||
|
||||
.PARAMETER repourl
|
||||
URL to the windows packages. Default is "https://repo.saltproject.io/windows"
|
||||
|
||||
.NOTES
|
||||
All of the parameters are optional. The default should be the latest
|
||||
version. The architecture is dynamically determined by the script.
|
||||
|
@ -68,7 +39,7 @@
|
|||
Salt Bootstrap GitHub Project (script home) - https://github.com/saltstack/salt-bootstrap
|
||||
Original Vagrant Provisioner Project - https://github.com/saltstack/salty-vagrant
|
||||
Vagrant Project (utilizes this script) - https://github.com/mitchellh/vagrant
|
||||
Salt Download Location - https://repo.saltproject.io/windows/
|
||||
Salt Download Location - https://repo.saltproject.io/salt/py3/windows
|
||||
#>
|
||||
|
||||
#===============================================================================
|
||||
|
@ -77,43 +48,62 @@
|
|||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
# Doesn't support versions prior to "YYYY.M.R-B"
|
||||
# Supports new version and latest
|
||||
# Option 1 means case insensitive
|
||||
[ValidatePattern('^(\d{4}(\.\d{1,2}){0,2}(\-\d{1})?)|(latest)$', Options=1)]
|
||||
[Alias("v")]
|
||||
# The version of the Salt minion to install. Default is "latest" which will
|
||||
# install the latest version of Salt minion available. Doesn't support
|
||||
# versions prior to "YYYY.M.R-B"
|
||||
[String]$Version = "latest",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
# Python 3 support was added in 2017. Python 2 support was dropped in
|
||||
# version 3001. This parameter is ignored for all versions before 2017 and
|
||||
# after 3000.
|
||||
[ValidateSet("2","3")]
|
||||
[Alias("p")]
|
||||
[String]$PythonVersion = "3",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
[ValidateSet("true","false")]
|
||||
[Alias("s")]
|
||||
# Boolean flag to start or stop the minion service. True will start the
|
||||
# minion service. False will stop the minion service and set it to "manual".
|
||||
# The installer starts it by default.
|
||||
[String]$RunService = "true",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
[Alias("m")]
|
||||
# Name of the minion being installed on this host. Installer defaults to the
|
||||
# host name.
|
||||
[String]$Minion = "not-specified",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
[Alias("a")]
|
||||
#Name or IP of the master server. Installer defaults to "salt".
|
||||
[String]$Master = "not-specified",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
[Alias("r")]
|
||||
# URL to the windows packages. Will look for a file named repo.json at the
|
||||
# root of the URL. This file is used to determine the name and location of
|
||||
# the installer in the repo. If repo.json is not found, it will look for the
|
||||
# file under the minor directory.
|
||||
# Default is "https://repo.saltproject.io/salt/py3/windows"
|
||||
[String]$RepoUrl = "https://repo.saltproject.io/salt/py3/windows",
|
||||
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
||||
[Alias("c")]
|
||||
[Switch]$ConfigureOnly
|
||||
# Vagrant only
|
||||
# Vagrant files are placed in "C:\tmp". Copies Salt config files from
|
||||
# Vagrant (C:\tmp) to Salt config locations and exits. Does not run the
|
||||
# installer
|
||||
[Switch]$ConfigureOnly,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("h")]
|
||||
# Displays help for this script.
|
||||
[Switch] $Help
|
||||
)
|
||||
|
||||
# We'll check for help first because it really has no requirements
|
||||
if ($help) {
|
||||
# Get the full script name
|
||||
$this_script = & {$myInvocation.ScriptName}
|
||||
Get-Help $this_script -Detailed
|
||||
exit 0
|
||||
}
|
||||
|
||||
#===============================================================================
|
||||
# Script Preferences
|
||||
|
@ -301,27 +291,11 @@ if (!(Get-IsAdministrator)) {
|
|||
$defaultUrl = "https://repo.saltproject.io/salt/py3/windows"
|
||||
$oldRepoUrl = "https://repo.saltproject.io/windows"
|
||||
$majorVersion = Get-MajorVersion -Version $Version
|
||||
$customUrl = $true
|
||||
if ( $Version.ToLower() -ne "latest" ) {
|
||||
# A specific version has been passed
|
||||
# We only want to modify the URL if a custom URL was not passed
|
||||
$uri = [Uri]($RepoUrl)
|
||||
if ( $uri.AbsoluteUri -eq $defaultUrl ) {
|
||||
# No customURL passed, let's check for a pre 3006 version
|
||||
$customUrl = $false
|
||||
if ( $majorVersion -lt "3006" ) {
|
||||
# This is an older version, use the old URL
|
||||
$RepoUrl = $oldRepoUrl
|
||||
} else {
|
||||
# This is a new URL, and a version was passed, let's look in minor
|
||||
if ( $Version.ToLower() -ne $majorVersion.ToLower() ) {
|
||||
$RepoUrl = "$RepoUrl/minor"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( $RepoUrl -eq $defaultUrl ) {
|
||||
$customUrl = $false
|
||||
if ( [Uri]($RepoUrl).AbsoluteUri -eq $defaultUrl ) {
|
||||
# No customURL passed, let's check for a pre 3006 version
|
||||
if ($majorVersion -lt "3006") {
|
||||
# This is an older version, use the old URL
|
||||
$RepoUrl = $oldRepoUrl
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,9 +346,6 @@ $ConfDir = "$RootDir\conf"
|
|||
$PkiDir = "$ConfDir\pki\minion"
|
||||
Write-Verbose "ConfDir: $ConfDir"
|
||||
|
||||
# Create C:\tmp\
|
||||
New-Item C:\tmp\ -ItemType directory -Force | Out-Null
|
||||
|
||||
#===============================================================================
|
||||
# Copy Vagrant Files to their proper location.
|
||||
#===============================================================================
|
||||
|
@ -431,15 +402,52 @@ $saltFileName = ""
|
|||
$saltVersion = ""
|
||||
$saltSha512= ""
|
||||
$saltFileUrl = ""
|
||||
if ( ($customUrl) -or ($majorVersion -lt 3006) ) {
|
||||
$saltFileName = "Salt-Minion-$Version-Py3-$arch-Setup.exe"
|
||||
$saltVersion = $Version
|
||||
$saltFileUrl = "$RepoUrl/$saltFileName"
|
||||
} else {
|
||||
if ( $majorVersion -ge 3006 ) {
|
||||
$enc = [System.Text.Encoding]::UTF8
|
||||
# Look for a repo.json file
|
||||
try {
|
||||
$response = Invoke-WebRequest "$RepoUrl/repo.json" `
|
||||
-DisableKeepAlive `
|
||||
-UseBasicParsing `
|
||||
-Method Head
|
||||
if ( $response.StatusCode -eq "200" ) {
|
||||
# This URL contains a repo.json file, let's use it
|
||||
$use_repo_json = $true
|
||||
} else {
|
||||
#
|
||||
$use_repo_json = $false
|
||||
}
|
||||
} catch {
|
||||
$use_repo_json = $false
|
||||
}
|
||||
if ( $use_repo_json ) {
|
||||
# We will use the json file to get the name of the installer
|
||||
$enc = [System.Text.Encoding]::UTF8
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "$RepoUrl/repo.json" -UseBasicParsing
|
||||
if ($response.Content.GetType().Name -eq "Byte[]") {
|
||||
$psobj = $enc.GetString($response.Content) | ConvertFrom-Json
|
||||
} else {
|
||||
$psobj = $response.Content | ConvertFrom-Json
|
||||
}
|
||||
$hash = Convert-PSObjectToHashtable $psobj
|
||||
} catch {
|
||||
Write-Verbose "repo.json not found at: $RepoUrl"
|
||||
$hash = @{}
|
||||
}
|
||||
|
||||
$searchVersion = $Version.ToLower()
|
||||
if ( $hash.Contains($searchVersion)) {
|
||||
foreach ($item in $hash.($searchVersion).Keys) {
|
||||
if ( $item.EndsWith(".exe") ) {
|
||||
if ( $item.Contains($arch) ) {
|
||||
$saltFileName = $hash.($searchVersion).($item).name
|
||||
$saltVersion = $hash.($searchVersion).($item).version
|
||||
$saltSha512 = $hash.($searchVersion).($item).SHA512
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "$RepoUrl/repo.json" -UseBasicParsing
|
||||
$response = Invoke-WebRequest -Uri "$RepoUrl/minor/repo.json" -UseBasicParsing
|
||||
if ($response.Content.GetType().Name -eq "Byte[]") {
|
||||
$psobj = $enc.GetString($response.Content) | ConvertFrom-Json
|
||||
} else {
|
||||
|
@ -450,8 +458,6 @@ if ( ($customUrl) -or ($majorVersion -lt 3006) ) {
|
|||
Write-Verbose "repo.json not found at: $RepoUrl"
|
||||
$hash = @{}
|
||||
}
|
||||
|
||||
$searchVersion = $Version.ToLower()
|
||||
if ( $hash.Contains($searchVersion)) {
|
||||
foreach ($item in $hash.($searchVersion).Keys) {
|
||||
if ( $item.EndsWith(".exe") ) {
|
||||
|
@ -462,17 +468,29 @@ if ( ($customUrl) -or ($majorVersion -lt 3006) ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $saltFileName -and $saltVersion -and $saltSha512 ) {
|
||||
if ( $RepoUrl.Contains("minor") ) {
|
||||
$saltFileUrl = @($RepoUrl, $saltVersion, $saltFileName) -join "/"
|
||||
} else {
|
||||
$saltFileUrl = @($RepoUrl, "minor", $saltVersion, $saltFileName) -join "/"
|
||||
}
|
||||
} else {
|
||||
Write-Host "Version not found in $RepoUrl/repo.json"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
if ( $saltFileName -and $saltVersion -and $saltSha512 ) {
|
||||
if ( $RepoUrl.Contains("minor") ) {
|
||||
$saltFileUrl = @($RepoUrl, $saltVersion, $saltFileName) -join "/"
|
||||
} else {
|
||||
$saltFileUrl = @($RepoUrl, "minor", $saltVersion, $saltFileName) -join "/"
|
||||
}
|
||||
} else {
|
||||
Write-Host "Failed to get Name, Version, and Sha"
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
# We will guess the name of the installer
|
||||
$saltFileName = "Salt-Minion-$Version-Py3-$arch-Setup.exe"
|
||||
$saltVersion = $Version
|
||||
$saltFileUrl = "$RepoUrl/$saltFileName"
|
||||
}
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Download minion setup file
|
||||
#===============================================================================
|
||||
|
@ -481,10 +499,13 @@ Write-Host " Bootstrapping Salt Minion" -ForegroundColor Green
|
|||
Write-Host " - version: $Version"
|
||||
Write-Host " - file name: $saltFileName"
|
||||
Write-Host " - file url: $saltFileUrl"
|
||||
Write-Host " - master: $Master"
|
||||
Write-Host " - minion id: $Minion"
|
||||
Write-Host " - start service: $RunService"
|
||||
Write-Host "-------------------------------------------------------------------------------" -ForegroundColor Yellow
|
||||
Write-Host "Downloading Installer: " -NoNewline
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
$localFile = "C:\Windows\Temp\$saltFileName"
|
||||
$localFile = "$env:TEMP\$saltFileName"
|
||||
$webclient.DownloadFile($saltFileUrl, $localFile)
|
||||
|
||||
if ( Test-Path -Path $localFile ) {
|
||||
|
@ -514,72 +535,116 @@ if ( $saltSha512 ) {
|
|||
$parameters = ""
|
||||
if($Minion -ne "not-specified") {$parameters = "/minion-name=$Minion"}
|
||||
if($Master -ne "not-specified") {$parameters = "$parameters /master=$Master"}
|
||||
if($RunService -eq $false) {$parameters = "$parameters /start-service=0"}
|
||||
|
||||
#===============================================================================
|
||||
# Install minion silently
|
||||
#===============================================================================
|
||||
#Wait for process to exit before continuing.
|
||||
Write-Host "Installing Salt Minion: " -NoNewline
|
||||
Start-Process $localFile -ArgumentList "/S $parameters" -Wait -NoNewWindow -PassThru | Out-Null
|
||||
$process = Start-Process $localFile `
|
||||
-ArgumentList "/S /start-service=0 $parameters" `
|
||||
-NoNewWindow -PassThru
|
||||
|
||||
# Sometimes the installer hangs... we'll wait 60s and then kill it
|
||||
$process | Wait-Process -Timeout 60 -ErrorAction SilentlyContinue
|
||||
$process.Refresh()
|
||||
|
||||
if ( !$process.HasExited ) {
|
||||
Write-Host "Timedout" -ForegroundColor Yellow
|
||||
Write-Host "Killing hung installer: " -NoNewline
|
||||
$process | Stop-Process
|
||||
$process.Refresh()
|
||||
if ( $process.HasExited ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Checking installed service: " -NoNewline
|
||||
}
|
||||
|
||||
# Wait for salt-minion service to be registered to verify successful
|
||||
# installation
|
||||
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
||||
$tries = 0
|
||||
$max_tries = 5 # We'll try for 10 seconds
|
||||
while ( ! $service ) {
|
||||
# We'll keep trying to get a service object until we're successful, or we
|
||||
# reach max_tries
|
||||
if ( $tries -le $max_tries ) {
|
||||
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
$tries += 1
|
||||
} else {
|
||||
# If the salt-minion service is still not running, something
|
||||
# probably went wrong and user intervention is required - report
|
||||
# failure.
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
Write-Host "Timed out waiting for the salt-minion service to be installed"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
# If we get this far, the service was installed, we have a service object
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
|
||||
#===============================================================================
|
||||
# Configure the minion service
|
||||
#===============================================================================
|
||||
# Wait for salt-minion service to be registered before trying to start it
|
||||
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
||||
while (!$service) {
|
||||
Start-Sleep -s 2
|
||||
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ( $service ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
if($RunService) {
|
||||
# Start service
|
||||
if( $RunService ) {
|
||||
# Start the service
|
||||
Write-Host "Starting Service: " -NoNewline
|
||||
Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue
|
||||
|
||||
# Check if service is started, otherwise retry starting the
|
||||
# service 4 times.
|
||||
$try = 0
|
||||
while (($service.Status -ne "Running") -and ($try -ne 4)) {
|
||||
Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue
|
||||
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
||||
Start-Sleep -s 2
|
||||
$try += 1
|
||||
$tries = 0
|
||||
# We'll try for 2 minutes, sometimes the minion takes that long to start as
|
||||
# it compiles python code for the first time
|
||||
$max_tries = 60
|
||||
while ( $service.Status -ne "Running" ) {
|
||||
if ( $service.Status -eq "Stopped" ) {
|
||||
Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue
|
||||
}
|
||||
Start-Sleep -Seconds 2
|
||||
$service.Refresh()
|
||||
if ( $service.Status -eq "Running" ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
if ( $tries -le $max_tries ) {
|
||||
$tries += 1
|
||||
} else {
|
||||
# If the salt-minion service is still not running, something
|
||||
# probably went wrong and user intervention is required - report
|
||||
# failure.
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
Write-Host "Timed out waiting for the salt-minion service to start"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# If the salt-minion service is still not running, something probably
|
||||
# went wrong and user intervention is required - report failure.
|
||||
if ($service.Status -eq "Running") {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Host "Setting Service to 'Manual': " -NoNewline
|
||||
Set-Service "salt-minion" -StartupType "Manual"
|
||||
if ( (Get-Service "salt-minion").StartType -eq "Manual" ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
# Set the service to manual start
|
||||
$service.Refresh()
|
||||
if ( $service.StartType -ne "Manual" ) {
|
||||
Write-Host "Setting Service Start Type to 'Manual': " -NoNewline
|
||||
Set-Service "salt-minion" -StartupType "Manual"
|
||||
$service.Refresh()
|
||||
if ( $service.StartType -eq "Manual" ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Stopping Service: " -NoNewline
|
||||
Stop-Service "salt-minion"
|
||||
if ( (Get-Service "salt-minion").Status -eq "Stopped" ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
# The installer should have installed the service stopped, but we'll make
|
||||
# sure it is stopped here
|
||||
if ( $service.Status -ne "Stopped" ) {
|
||||
Write-Host "Stopping Service: " -NoNewline
|
||||
Stop-Service "salt-minion"
|
||||
$service.Refresh()
|
||||
if ( $service.Status -eq "Stopped" ) {
|
||||
Write-Host "Success" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue