Files
greenhouse-openHAB/runtime/bin/update.ps1

880 lines
39 KiB
PowerShell

#Requires -Version 5.0
Set-StrictMode -Version Latest
<#
.SYNOPSIS
Updates openHAB to the latest version.
.DESCRIPTION
The Update-openHAB function performs the necessary tasks to update openHAB.
.PARAMETER OHDirectory
The directory where openHAB is installed (default: current directory).
.PARAMETER OHVersion
The version to upgrade to.
.PARAMETER Snapshot
DEPRECATED - Upgrade to a snapshot version ($true) or a release version ($false) (default: $false)
DEPRECATED - Please specify "-snapshot" in the OHVersion instead (ex: "2.4.0-SNAPSHOT")
.PARAMETER AutoConfirm
Automatically confirm update (used for headless mode)
.EXAMPLE
Update the openHAB distribution in the current directory to the current stable version
Update-openHAB
.EXAMPLE
Update the openHAB distribution in the C:\oh-snapshot directory to the next snapshot version
Update-openHAB -OHDirectory C:\oh-snapshot -OHVersion 2.3.0-SNAPSHOT
#>
Function Update-openHAB() {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $True)]
[string]$OHDirectory = ".",
[Parameter(ValueFromPipeline = $True)]
[string]$OHVersion,
[Parameter(ValueFromPipeline = $True)]
[boolean]$Snapshot = $false,
[Parameter(ValueFromPipeline = $True)]
[boolean]$AutoConfirm = $false,
[Parameter(ValueFromPipeline = $True)]
[boolean]$SkipNew = $false, # sssh - secret switch ;)
[Parameter(ValueFromPipeline = $True)]
[boolean]$KeepUpdateScript = $false # sssh - secret switch ;)
)
# Downloads the URL into a file showing a progress meter. Any error will be thrown to the caller
function DownloadFiles() {
param(
[Parameter(Mandatory = $True)]
[string] $URL,
[Parameter(Mandatory = $True)]
[string] $OutputFile
)
# Create the request
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
$uri = New-Object "System.Uri" "$URL"
$request = [System.Net.HttpWebRequest]::Create($uri)
$request.set_Timeout(15000)
#Get the response (along with the total size)
$response = $request.GetResponse()
$totalLength = [System.Math]::Floor($response.get_ContentLength()/1024)
try {
# Gets the response stream and setup the buffer
$responseStream = $response.GetResponseStream()
$targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $Outputfile, Create
$buffer = new-object byte[] 10KB
# Save console settings
$startTop = [System.Console]::CursorTop
$startVisibility = [System.Console]::CursorVisible
$startColor = [System.Console]::ForegroundColor
# Process each chunk into the output file (updating the progress meter along the way)
try {
[System.Console]::CursorVisible = $False
[System.Console]::ForegroundColor = "Blue"
$count = $responseStream.Read($buffer,0,$buffer.length)
$downloadedBytes = $count
while ($count -gt 0)
{
$bytes = [System.Math]::Floor($downloadedBytes/1024)
$perc = [System.Math]::Floor(($bytes / $totalLength) * 100)
[System.Console]::CursorLeft = 0
[System.Console]::CursorTop = $startTop
[System.Console]::Write("Downloaded {0}K of {1}K [{2}%]", $bytes, $totalLength, $perc)
$targetStream.Write($buffer, 0, $count)
$count = $responseStream.Read($buffer,0,$buffer.length)
$downloadedBytes = $downloadedBytes + $count
}
Write-Host "`nFinished Download"
} finally {
# Set the console settings back
[System.Console]::CursorVisible = $startVisibility
[System.Console]::ForegroundColor = $startColor
}
} finally {
# Cleanup resources
if ($targetStream) {
$targetStream.Flush()
$targetStream.Close()
$targetStream.Dispose()
}
if ($responseStream) {
$responseStream.Dispose()
}
}
}
# This function 'normalizes' the version number - creates left 0 padded segments "0000.0000.0000" that can be compared against
function NormalizeVersionNumber() {
param(
[Parameter(Mandatory = $True)]
[string] $VersionNumber
)
$parts = $VersionNumber.Split(".")
if ($parts.Length -eq 2) {
$parts += "0"
}
if ($parts.Length -ne 3) {
throw "$VersionNumber is not formatted correctly (d.d.d)"
}
$rc = "";
$parts | ForEach-Object {
$rc += $_.PadLeft(5 - $_.Length, '0')
$rc += "."
}
return $rc.Substring(0, $rc.Length - 1)
}
# This function will process a command from the upgrade.lst file (called from ProcessVersionChange)
function ProcessCommand() {
param(
[Parameter(Mandatory = $True)]
[string] $Line
)
# Use of global variables (not passed in)
$Line = $Line.Replace("`$OPENHAB_USERDATA", $OHUserData)
$Line = $Line.Replace("`$OPENHAB_CONF", $OHConf)
$Line = $Line.Replace("`$OPENHAB_HOME", $OHDirectory)
$Line = $Line.Replace("`$OPENHAB_RUNTIME", $OHRuntime)
# Split the line into it's distinct parts
$parts = $Line.Split(";")
# blank line - simply return
if ($parts.length -eq 0) {
return;
}
# If default - rename an item to "x.bak" (assumes a new version of this file will be added by the upgrade process)
if ($parts[0] -eq "DEFAULT") {
if ($parts.length -le 1) {
Write-Host -ForegroundColor Red "Badly formatted: $Line"
}
else {
try {
Rename-Item -Path $parts[1] "$parts[1].bak" -ErrorAction Stop
Write-Host -ForegroundColor Cyan "$($parts[1]) renamed to $($parts[1]).bak"
}
catch {
Write-Host -ForegroundColor Yellow "Could not rename $($parts[1]) to $($parts[1]).bak"
}
}
}
# Deletes an item
ElseIf ($parts[0] -eq "DELETEDIR" -or $parts[0] -eq "DELETE") {
if ($parts.length -le 1) {
Write-Host -ForegroundColor Red "Badly formatted: $Line"
}
else {
try {
if ($parts[0] -eq "DELETEDIR") {
DeleteIfExists $parts[1] $True
} else {
DeleteIfExists $parts[1]
}
Write-Host -ForegroundColor Cyan "Deleted $($parts[1])"
}
catch {
Write-Host -ForegroundColor Yellow "Could not delete $($parts[1])"
}
}
}
# Moves an item
ElseIf ($parts[0] -eq "MOVE") {
if ($parts.length -le 2) {
Write-Host -ForegroundColor Red "Badly formatted: $Line"
}
else {
try {
Move-Item -Path $parts[1] -Destination $parts[2] -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Moved $($parts[1]) to $($parts[2])"
}
catch {
Write-Host -ForegroundColor Yellow "Could not move $($parts[1]) to $($parts[2])"
}
}
}
# Shows a note (console message with a green label)
ElseIf ($parts[0] -eq "NOTE") {
if ($parts.length -le 1) {
Write-Host -ForegroundColor Red "Badly formatted: $Line"
}
else {
Write-Host -ForegroundColor Green "Note: " -NoNewLine
Write-Host $parts[1]
}
}
# Shows a note (console message with a red label)
ElseIf ($parts[0] -eq "ALERT") {
if ($parts.length -le 1) {
Write-Host -ForegroundColor Red "Badly formatted: $Line"
}
else {
Write-Host -ForegroundColor Red "Warning: " -NoNewLine
Write-Host $parts[1]
}
}
Else {
Write-Host -ForegroundColor Red "Unknown command: $Line"
}
}
# Processes the update.lst file for the specific section, and version (going from x.x.x to x.x.x).
# A boolean is returned indicating whether we found any commands or not
function ProcessVersionChange() {
param(
[Parameter(Mandatory = $True)]
[string] $FileName,
[Parameter(Mandatory = $True)]
[string] $Section,
[Parameter(Mandatory = $True)]
[string] $VersionMsg,
[Parameter(Mandatory = $True)]
[string] $OldVersion,
[Parameter(Mandatory = $True)]
[string] $NewVersion
)
# Flags used
$InSection = $false
$InNewVersion = $false
# Normalize our lower/upper versions
$NormalizedOldVersion = NormalizeVersionNumber $OldVersion
$NormalizedNewVersion = NormalizeVersionNumber $NewVersion
# FoundSomething is true if we did some action (and is returned to caller)
$FoundSomething = $False
# Loops through the content of the file...
Get-Content $FileName -ErrorAction Stop | ForEach-Object {
# Skip blank lines
if ($_ -ne "") {
# If it's OUR section - flip the switch
if ($_ -match "\[\[$Section\]\]") {
$InSection = $True
}
# If it's not OUR section - flip it false
ElseIf ($_ -match "\[\[.*\]\]") {
$InSection = $false
$InNewVersion = $false
}
# If its a version number section
ElseIf ($_ -match "\[\d\.*\d\.*\d\]") {
# Determine if we are in a section and the version number is greater than our lower bound but less than or equal to our upper bound
if ($InSection) {
$NormalizedSectionVersion = NormalizeVersionNumber $_.Substring(1, $_.length - 2)
$InNewVersion = ($NormalizedSectionVersion -gt $NormalizedOldVersion) -and ($NormalizedSectionVersion -le $NormalizedNewVersion)
if ($InNewVersion -and $InSection) {
# If so, show that we are processing this section
Write-Host ""
Write-Host -ForegroundColor Cyan "$VersionMsg $_ :"
}
}
}
else {
if ($InSection -and $InNewVersion) {
# Woohoo - found a command to process
$FoundSomething = $True
ProcessCommand $_
}
}
}
}
return $FoundSomething
}
# Force reimport of common functions (in case of upgrading the script)
Import-Module $PSScriptRoot\common.psm1 -Force
# Write out startup message
Write-Host ""
BoxMessage "openHAB 2.x.x update script" Magenta
Write-Host ""
# Check for admin (commented out - don't think we need it)
# CheckForAdmin
# Check for openhab running
CheckOpenHABRunning
# Check if service is installed, stop and delete it
Write-Host -ForegroundColor Cyan "Checking whether a service exists"
try {
$service = Get-Service 'openHAB%' -ErrorAction Ignore
if ($service) {
# Stop and delete the service
Write-Host -ForegroundColor Cyan "Stopping the service"
Stop-Service $service.Name -Force -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Deleting the service"
Remove-Service $service.Name -ErrorAction Stop
}
}
catch {
exit PrintAndReturn "Could not stop/delete the openHAB windows server - please do that manually and try again" $_
}
# Find the proper directory root directory
Write-Host -ForegroundColor Cyan "Checking the specified openHAB directory"
$OHDirectory = GetOpenHABRoot $OHDirectory
if ($OHDirectory -eq "") {
exit PrintAndReturn "Could not find the openHAB directory! Make sure you are in the openHAB directory or specify the -OHDirectory parameter!"
}
# Get the various 'other' directories
$OHConf = GetOpenHABDirectory "OPENHAB_CONF" "$OHDirectory\conf"
$OHUserData = GetOpenHABDirectory "OPENHAB_USERDATA" "$OHDirectory\userdata"
$OHRuntime = GetOpenHABDirectory "OPENHAB_RUNTIME" "$OHDirectory\runtime"
$OHAddons = GetOpenHABDirectory "OPENHAB_ADDONS" "$OHDirectory\addons"
# Validate that all the directories exist (and are directories)
if (-NOT (Test-Path -Path $OHConf -PathType Container)) {
exit PrintAndReturn "Configuration directory does not exist: $OHConf"
}
if (-NOT (Test-Path -Path $OHUserData -PathType Container)) {
exit PrintAndReturn "Userdata directory does not exist: $OHUserData"
}
if (-NOT (Test-Path -Path $OHRuntime -PathType Container)) {
exit PrintAndReturn "Runtime directory does not exist: $OHRuntime"
}
if (-NOT (Test-Path -Path $OHAddons -PathType Container)) {
exit PrintAndReturn "Addons directory does not exist: $OHAddons"
}
# Tell the user what we are processing
Write-Host -ForegroundColor Yellow "Using $OHConf as conf folder"
Write-Host -ForegroundColor Yellow "Using $OHUserData as userdata folder"
Write-Host -ForegroundColor Yellow "Using $OHRuntime as runtime folder"
Write-Host -ForegroundColor Yellow "Using $OHAddons as addons folder"
# Get current openHAB version
$CurrentVersion = GetOpenHABVersion $OHUserData
if ($CurrentVersion -eq "") {
exit PrintAndReturn "Can't get the current openhab version from $OHDirectory - exiting"
}
# Determine if it's a snapshot
$CurrentVersionSnapshot = $False;
if ($CurrentVersion.EndsWith("-SNAPSHOT", "CurrentCultureIgnoreCase")) {
$CurrentVersionSnapshot = $True;
$CurrentVersion = $CurrentVersion.Substring(0, $CurrentVersion.Length - "-SNAPSHOT".Length);
}
# Tell the user our current version
if ($CurrentVersionSnapshot) {
Write-Host -ForegroundColor Yellow "The current version is $CurrentVersion-SNAPSHOT"
} else {
Write-Host -ForegroundColor Yellow "The current version is $CurrentVersion"
}
# If the version was not specified,
# If the current version is snapshot - make OHVersion the same snapshot
# If the current version is stable - make OHVersion the next minor upgrade (current version 2.3.0 would make our OHversion 2.4.0)
# If the current version is milestone - make OHVersion the stable version (2.3.0.M6 becomes 2.3.0)
if (-Not $OHVersion) {
$parts = $CurrentVersion.Split(".")
if ($parts.Length -eq 3) {
if ($CurrentVersionSnapshot -eq $True) {
$OHVersion = $CurrentVersion + "-SNAPSHOT"
} else {
$OHVersion = $parts[0] + "." + ([int]$parts[1] + 1) + "." + $parts[2]
}
} elseif ($parts.Length -eq 4) {
$OHVersion = $parts[0] + "." + $parts[1] + "." + $parts[2]
}
else {
exit PrintAndReturn "The current version $CurrentVersion was not formatted correctly (d.d.d)"
}
}
# If snapshot was defined, add "-snapshot" to the OHVersion if not already present
if ($Snapshot -eq $true) {
BoxMessage "-SNAPSHOT is deprecated - please put '-snapshot' in OHVersion instead (ex: 2.4.0-snapshot)" Magenta
if (-Not $OHVersion.EndsWith("-SNAPSHOT", "CurrentCultureIgnoreCase")) {
$OHVersion = $OHVersion + "-SNAPSHOT"
}
}
# Split up the OHVersion to validate
$parts = $OHVersion.Split(".")
# If only "2.3" - make "2.3.0"
if ($parts.Length -eq 2) {
$parts += "0"
}
# Valid versions:
# Stable: "2.3.0"
# Snapshot: "2.3.0-SNAPSHOT"
# Milestone: "2.3.0.M6"
if (($parts.Length -lt 3) -or ($parts.Length -gt 4)) {
exit PrintAndReturn "The specified OH version $OHVersion was not formatted correctly (d.d.d[.d])"
}
$Snapshot = $False
$Milestone = ""
if ($parts[2].EndsWith("-SNAPSHOT", "CurrentCultureIgnoreCase")) {
$Snapshot = $True
$parts[2] = $parts[2].Substring(0, $parts[2].Length - "-SNAPSHOT".Length);
} elseif ($parts.Length -eq 4) {
$Milestone = $parts[3]
}
$OHVersion = $parts[0] + "." + $parts[1] + "." + $parts[2]
# Recreate the name - should be standardized now and is used for messages and downloads
if ($Snapshot -eq $True) {
$OHVersionName = "$OHVersion-SNAPSHOT"
} elseif ($Milestone -ne "") {
$OHVersionName = $OHVersion + "." + $Milestone
} else {
$OHVersionName = $OHVersion
}
# Get the current directory (so we can switch back to it at the end)
try {
$StartDir = Get-Location -ErrorAction Stop
}
catch {
exit PrintAndReturn "Can't retrieve the current location - exiting" $_
}
# Set the current directory to our OH root directory
Write-Host -ForegroundColor Cyan "Changing location to $OHDirectory"
try {
Set-Location -Path $OHDirectory
}
catch {
exit PrintAndReturn "Could not change location to $OHDirectory - exiting" $_
}
# Setup where our temporary locations will be
$TempDir = "$(GetOpenHABTempDirectory)"
$TempDistributionZip = "$TempDir\openhab-$OHVersion.zip";
$TempDistribution = "$TempDir\update"
# Create the proper download URLs
if ($Snapshot) {
$DownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab/target/openhab-$OHVersionName.zip"
$AddonsDownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab-addons/target/openhab-addons-$OHVersionName.kar"
$LegacyAddonsDownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab-addons-legacy/target/openhab-addons-legacy-$OHVersionName.kar"
}
elseif ($Milestone -ne "") {
$DownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab/$OHVersionName/openhab-$OHVersionName.zip"
$AddonsDownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab-addons/$OHVersionName/openhab-addons-$OHVersionName.kar"
$LegacyAddonsDownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab-addons-legacy/$OHVersionName/openhab-addons-legacy-$OHVersionName.kar"
}
else {
$DownloadLocation = "https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab%2F$OHVersion%2Fopenhab-$OHVersion.zip"
$AddonsDownloadLocation = "https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab-addons%2F$OHVersion%2Fopenhab-addons-$OHVersion.kar"
$LegacyAddonsDownloadLocation = "https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab-addons-legacy%2F$OHVersion%2Fopenhab-addons-legacy-$OHVersion.kar"
}
# If we are not in SkipNew (or SkipNew and the temporary distribution file/folders have not been created yet):
# 1. Delete and recreate the temporary distribution directory if it exists
# 2. Download the distribution to the temp directory
# 3. Expand the distribution to the temp directory
# 4. Copy the update.ps1/common.psm1 files to the temp distribution if KeepUpdateScript is true (dev purposes only)
if (($SkipNew -eq $False) -or
(($SkipNew -eq $True) -and -NOT
((Test-Path -Path $TempDistributionZip -PathType Leaf) -and (Test-Path -Path $TempDistribution -PathType Container))
)
) {
########### STEP 1 - Delete and recreate the temporary distribution directory if it exists
try {
DeleteIfExists $TempDir $True
}
catch {
# Do nothing here - probably a file lock issue
}
try {
Write-Host -ForegroundColor Cyan "Creating temporary update directory $TempDir"
CreateDirectory $TempDir
}
catch {
exit PrintAndReturn "Error creating temporary update directory $TempDir - exiting" $_
}
########### STEP 2 - download the distribution
try {
Write-Host -ForegroundColor Cyan "Downloading the openHAB $OHVersionName distribution to $TempDistributionZip"
DownloadFiles $DownloadLocation $TempDistributionZip
}
catch {
if ([int]$_.Exception.InnerException.Response.StatusCode -eq 404) {
exit PrintAndReturn "Download of $OHVersionName failed because it's not a valid version" $_
} else {
exit PrintAndReturn "Download of $DownloadLocation failed" $_
}
}
########### STEP 3 - Expand the archive
try {
Write-Host -ForegroundColor Cyan "Extracting the archive ($TempDistributionZip) to $TempDistribution"
Expand-Archive -Path $TempDistributionZip -DestinationPath $TempDistribution -Force -ErrorAction Stop
} catch {
exit PrintAndReturn "Unzipping of $TempDistributionZip to $TempDistribution failed." $_
}
########### STEP 4 - Copy the update/common over if we are keeping the update scripts
if ($KeepUpdateScript) {
try {
Write-Host -ForegroundColor Cyan "Keeping commons.psm1 and update.ps1 by copying to $TempDistribution\runtime\bin"
Copy-Item -Path "$OHRuntime\bin\common.psm1" -Destination "$TempDistribution\runtime\bin\common.psm1" -Force
Copy-Item -Path "$OHRuntime\bin\update.ps1" -Destination "$TempDistribution\runtime\bin\update.ps1" -Force
} catch {
Write-Error $_
Write-Host -ForegroundColor Magenta "Could not copy the common.psm1 and update.ps1 to $TempDistribution\runtime\bin"
# Don't bother with AutoConfirm here since this is special debugging logic to begin with
$confirmation = Read-Host "Okay to Continue? [y/N]"
if ($confirmation -ne 'y') {
exit PrintAndReturn "Cancelling update"
}
}
}
}
# If not SkipNew - check to see if the new distribution has an update.ps1 (which is likely)
# and then execute it (exiting with it's result)
if ($SkipNew -eq $False) {
$newUpdate = Join-Path $TempDistribution "\runtime\bin\update.ps1"
If (Test-Path $newUpdate) {
Write-Host ""
BoxMessage "New update.ps1 was found - executing it instead (found in $newUpdate)" Magenta
Write-Host ""
try {
# go back to our original directory so the new update script does it as well
Set-Location -Path $StartDir -ErrorAction Continue
. $newUpdate
exit Update-openHAB -OHDirectory $OHDirectory -OHVersion $OHVersionName -AutoConfirm $AutoConfirm -SkipNew $true -KeepUpdateScript $KeepUpdateScript
} catch {
exit PrintAndReturn "Execution of new update.ps1 failed - please execute it yourself (found in $newUpdate)" $_
}
}
}
# Do the following questions after the update.ps1 check to make sure this question isn't asked twice!
# Are we resinstalling the current version (as long as it's not a snapshot)
if ($OHVersion -eq $CurrentVersion -and $Snapshot -eq $False) {
if ($AutoConfirm) {
Write-Host -ForegroundColor Magenta "Current version is equal to specified version ($OHVersionName). ***REINSTALLING*** $OHVersionName instead (rather than upgrading)."
} else {
Write-Host -ForegroundColor Magenta "Current version is equal to specified version ($OHVersionName). If you continue, you will REINSTALL $OHVersionName rather than upgrade."
$confirmation = Read-Host "Okay to Continue? [y/N]"
if ($confirmation -ne 'y') {
exit PrintAndReturn "Cancelling update"
}
}
Write-Host -ForegroundColor Yellow "REINSTALLING" -NoNewline -BackgroundColor Blue
Write-Host -ForegroundColor Yellow " version $OHVersionName"
} else {
# Are we trying to downgrade the distribution (yikes!)
if ((NormalizeVersionNumber $OHVersion) -lt (NormalizeVersionNumber $CurrentVersion)) {
# Don't use autoconfirm on a downgrade warning
BoxMessage "You are attempting to downgrade from $CurrentVersion to $OHVersionName !!!" Red
Write-Host -ForegroundColor Magenta "This script is not meant to downgrade and the results will be unpredictable"
$confirmation = Read-Host "Okay to Continue? [y/N]"
if ($confirmation -ne 'y') {
exit PrintAndReturn "Cancelling update"
}
Write-Host -ForegroundColor Yellow "DOWNGRADING" -NoNewline -BackgroundColor Red
Write-Host -ForegroundColor Yellow " to version $OHVersionName"
} else {
Write-Host -ForegroundColor Yellow "Upgrading to version $OHVersionName"
}
}
# Crete the temporary backup locations to the current distribution
$TempBackupDir = "$TempDir\backup-$CurrentVersion"
$TempBackupDirHome = $TempBackupDir + "\home"
$TempBackupDirRuntime = $TempBackupDir + "\runtime"
$TempBackupDirUserData = $TempBackupDir + "\userdata"
$TempBackupDirConf = $TempBackupDir + "\conf"
# Backup the current distribution to those locations
Write-Host ""
Write-Host -ForegroundColor Cyan "Making a backup of your distribution to $TempBackupDir"
try {
Write-Host -ForegroundColor Cyan "Creating backup directories in $TempBackupDir"
DeleteIfExists $TempBackupDir $True
Write-Host -ForegroundColor Cyan "Copying directory conf, userdata and runtime to $TempBackupDirConf"
Copy-Item -Path $OHConf, $OHUserData, $OHRuntime -Destination $TempBackupDir -Recurse -Force -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Copying files from $OHDirectory to $TempBackupDirHome"
Get-ChildItem $OHDirectory -File -ErrorAction Stop | Copy-Item -Destination $TempBackupDirHome -Force -ErrorAction Stop
} catch {
exit PrintAndReturn "Could not backup existing distribution to $TempBackupDir" $_
}
# Alright - we are ready to being the update process. This will be wrapped in a
# try/catch/finally to restore our current distribution on error and to cleanup
# the temporary files when finished
try {
# If our update.lst exists, process the notes (ie MSG section) and the PRE section
$updateLst = Join-Path $TempDistribution "\runtime\bin\update.lst"
if (Test-Path $updateLst) {
Write-Host ""
Write-Host -ForegroundColor Cyan "The script will attempt to update openHAB to version $OHVersionName"
Write-Host -ForegroundColor Cyan "Please read the following " -NoNewLine
Write-Host -ForegroundColor Green "notes" -NoNewLine
Write-Host -ForegroundColor Cyan " and " -NoNewLine
Write-Host -ForegroundColor Red "warnings"
$NotesFound = $False
try {
$NotesFound = ProcessVersionChange $updateLst "MSG" "Important notes for version" $CurrentVersion $OHVersion
} catch {
# PrintAndReturn since there have been no file changes yet
exit PrintAndReturn "Could not process 'MSG' of $updateLst" $_
}
if ($NotesFound) {
if (-Not $AutoConfirm) {
$confirmation = Read-Host "Okay to Continue? [y/N]"
if ($confirmation -ne 'y') {
exit PrintAndReturn "Cancelling update"
}
}
} else {
Write-Host -ForegroundColor Blue "No notes found for version $OHVersionName"
}
try {
Write-Host ""
Write-Host -ForegroundColor Cyan "Execute 'PRE' instructions for version $OHVersionName"
if (-NOT (ProcessVersionChange $updateLst "PRE" "Performing pre-update tasks for version" $CurrentVersion $OHVersion)) {
Write-Host -ForegroundColor Blue "No 'PRE' instructions found for version $OHVersionName"
}
} catch {
return PrintAndThrow "Could not process 'PRE' of $updateLst" $_
}
Write-Host ""
}
# Delete current userdata files
# Update openHAB
# 1. First remove all file in runtime (they will all be replaced)
# 2. Remove all the userdata\etc files listed in userdata_sysfiles.lst (they may be replaced)
# 3. Remove the cache/tmp directories
# 4. Then copy all files from our new distribution WITHOUT overwriting anything
# (by removals in 1 & 2 - that means we will replace those)
#
############## STEP 1 - remove runtime
try {
Write-Host -ForegroundColor Cyan "Deleting current runtime ($OHRuntime)"
DeleteIfExists $OHRuntime $True
} catch {
return PrintAndThrow "Could not delete current runtime ($OHRuntime)" $_
}
############## STEP 2 - remove userdata\etc files in userdata_sysfiles.lst
$updateSysFilesLst = "$TempDistribution\runtime\bin\userdata_sysfiles.lst"
if (Test-Path $updateSysFilesLst) {
Write-Host -ForegroundColor Cyan "Deleting current files in userdata that should not persist"
foreach ($FileName in Get-Content $updateSysFilesLst) {
$fileToDelete = "$OHUserData\etc\$FileName"
try {
if (Test-Path -Path $fileToDelete) {
DeleteIfExists $fileToDelete
Write-Host -ForegroundColor Cyan "Deleted $FileName from $OHUserData\etc"
}
} catch {
Write-Error $_
Write-Host "Could not delete $fileToDelete. File is no longer needed and should be manually deleted."
}
}
}
############## STEP 3 - remove cache/tmp directories
try {
Write-Host -ForegroundColor Cyan "Removing $OHUserData\cache"
DeleteIfExists "$OHUserData\cache" $True
} catch {
return PrintAndThrow "Could not delete the $OHUserData\cache directory" $_
}
try {
Write-Host -ForegroundColor Cyan "Removing $OHUserData\tmp"
DeleteIfExists "$OHUserData\tmp" $True
} catch {
return PrintAndThrow "Could not delete the $OHUserData\tmp directory" $_
}
############## STEP 4 - copy files from temporary to distribution WITHOUT replacement
Write-Host -ForegroundColor Cyan "Copying $TempDistribution to $OHDirectory without overwriting existing ones"
try {
Get-ChildItem -Path $TempDistribution -Recurse -ErrorAction Stop | ForEach-Object {
$relPath = GetRelativePath $TempDistribution $_.FullName
if ($relPath.StartsWith(".\addons")) {
$localPath = Join-Path $OHAddons $relPath.Substring(".\addons".Length)
} elseif ($relPath.StartsWith(".\conf")) {
$localPath = Join-Path $OHConf $relPath.Substring(".\conf".Length)
} elseif ($relPath.StartsWith(".\userdata")) {
$localPath = Join-Path $OHUserData $relPath.Substring(".\userdata".Length)
} elseif ($relPath.StartsWith(".\runtime")) {
$localPath = Join-Path $OHRuntime $relPath.Substring(".\runtime".Length)
} else {
$localPath = Join-Path $OHDirectory $relPath
}
if (-Not (Test-Path $localPath)) {
if (Test-Path $localPath -PathType Container) {
CreateDirectory $localPath
} else {
Copy-Item -Path $_.FullName -Destination $localPath -ErrorAction Stop
}
}
}
} catch {
return PrintAndThrow "Error occurred copying $TempDistribution to $OHDirectory" $_
}
# If we have an update.lst - process the "POST" section
if (Test-Path $updateLst) {
Write-Host ""
try {
Write-Host -ForegroundColor Cyan "Execute 'POST' instructions for version $OHVersionName"
if (-NOT (ProcessVersionChange $updateLst "POST" "Performing post-update tasks for version" $CurrentVersion $OHVersion)) {
Write-Host -ForegroundColor Blue "No 'POST' instructions found for version $OHVersionName"
}
} catch {
return PrintAndThrow "Could not process 'POST' of $updateLst" $_
}
}
Write-Host ""
# If there's an existing addons file, we need to replace it with the correct version.
try {
$AddonsFile = "$OHAddons\openhab-addons-$OHVersionName.kar"
if (Test-Path -Path $AddonsFile) {
Write-Host "Found an openHAB addons file, replacing with new version"
DeleteIfExists $AddonsFile
DownloadFiles $AddonsDownloadLocation "$OHAddons\openhab-addons-$OHVersionName.kar"
}
} catch {
return PrintAndThrow "Could not replace the $AddonsFile" $_
}
# Do the same for the legacy addons file.
try {
$LegacyAddonsFile = "$OHAddons\openhab-addons-legacy-$OHVersionName.kar"
if (Test-Path -Path $LegacyAddonsFile) {
Write-Host "Found an openHAB legacy addons file, replacing with new version"
DeleteIfExists $LegacyAddonsFile
DownloadFiles $LegacyAddonsDownloadLocation "$OHAddons\openhab-addons-legacy-$OHVersionName.kar"
}
} catch {
return PrintAndThrow "Could not replace the $LegacyAddonsFile" $_
}
# Hop for joy - we did it!
Write-Host -ForegroundColor Green "openHAB updated to version $OHVersionName!"
Write-Host -ForegroundColor Green "Run start.bat to launch it."
Write-Host -ForegroundColor Green "Check https://www.openhab.org/docs/installation/windows.html"
Write-Host -ForegroundColor Green "for instructions on re-installing the Windows Service if desired"
}
catch {
# Some issue happened - we need to copy the old distribution back
BoxMessage "Restoring your distribution from $TempBackupDir" Yellow
try {
Write-Host -ForegroundColor Cyan "Removing existing files in $OHDirectory"
Get-ChildItem $OHDirectory -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
Write-Host -ForegroundColor Cyan "Copying backup files from $TempBackupDirHome to $OHDirectory"
Get-ChildItem $TempBackupDirHome -file -ErrorAction Stop | Copy-Item -Destination $OHDirectory -Force -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Removing the directory $OHConf"
Remove-Item "$OHConf\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host -ForegroundColor Cyan "Copying backup directory $TempBackupDirConf to $OHConf"
Copy-Item -Path "$TempBackupDirConf\*" -Destination $OHConf -Recurse -Force -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Removing the directory $OHUserData"
Remove-Item "$OHUserData\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host -ForegroundColor Cyan "Copying backup directory $TempBackupDirUserData to $OHUserData"
Copy-Item -Path "$TempBackupDirUserData\*" -Destination $OHUserData -Recurse -Force -ErrorAction Stop
Write-Host -ForegroundColor Cyan "Removing the directory $OHRuntime"
Remove-Item "$OHRuntime\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host -ForegroundColor Cyan "Copying backup directory $TempBackupDirRuntime to $OHRuntime"
Copy-Item -Path "$TempBackupDirRuntime\*" -Destination $OHRuntime -Recurse -Force -ErrorAction Stop
} catch {
Write-Host -ForegroundColor Cyan "Restoration was unsuccessful - you may want to restore from $TempBackupDir yourself"
Write-Error $_
}
exit -1
}
finally {
# And we are done...
Write-Host ""
# If our temp backup directory exists - ask if we should remove it
# TODO - maybe only do this if an error occurred
try {
if (Test-Path $TempBackupDir) {
if ($AutoConfirm) {
Write-Host -ForegroundColor Cyan "Removing temporary distribution backup $TempBackupDir"
DeleteIfExists $TempBackupDir $True
} else {
Write-Host -ForegroundColor Cyan "Your prior distribution is in $TempBackupDir"
$confirmation = Read-Host "Should it be deleted? [y/N]"
if ($confirmation -eq 'y') {
Write-Host -ForegroundColor Cyan "Removing temporary distribution backup $TempBackupDir"
DeleteIfExists $TempBackupDir $True
}
}
}
}
catch {
Write-Host -ForegroundColor Red "Could not delete $TempBackupDir - delete it manually"
}
try {
# If the backup directory doesn't exist - delete the tempdir directory (and it's parent)
# (may exist if they answer "N" to the above question)
if (-NOT (Test-Path $TempBackupDir)) {
try {
Write-Host -ForegroundColor Cyan "Removing temporary directory $TempDir"
DeleteIfExists $TempDir $True
}
catch {
Write-Host -ForegroundColor Red "Could not delete $TempDir - delete it manually"
}
}
}
catch {
Write-Host -ForegroundColor Red "Could not delete $parent - delete it manually"
}
# FINALLY - set our location back to where we began
Write-Host -ForegroundColor Cyan "Setting location back to $StartDir"
Set-Location -Path $StartDir -ErrorAction Continue
}
}