Adds generic PowerShell component installer and improved usability

This commit is contained in:
Christian Stein 2020-03-26 19:43:37 +01:00
parent d62e566fea
commit 7dce37717a
3 changed files with 128 additions and 53 deletions

View file

@ -3,23 +3,44 @@ function Get-IcingaPowerShellModuleArchive()
param(
[string]$DownloadUrl = '',
[string]$ModuleName = '',
[string]$Repository = ''
[string]$Repository = '',
[string]$GitHubUser = 'Icinga',
[bool]$Stable = $FALSE,
[bool]$Snapshot = $FALSE,
[bool]$DryRun = $FALSE
);
$ProgressPreference = "SilentlyContinue";
$Tag = 'master';
[bool]$SkipRepo = $FALSE;
if ($Stable -Or $Snapshot) {
$SkipRepo = $TRUE;
}
# Fix TLS errors while connecting to GitHub with old PowerShell versions
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11";
if ([string]::IsNullOrEmpty($DownloadUrl)) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you provide a custom repository for "{0}"?', $ModuleName)) -Default 'n').result -eq 1) {
$branch = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer
if ($branch.ToLower() -eq 'snapshot') {
$DownloadUrl = [string]::Format('https://github.com/Icinga/{0}/archive/master.zip', $Repository);
if ($SkipRepo -Or (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you provide a custom repository for "{0}"?', $ModuleName)) -Default 'n').result -eq 1) {
if ($Stable -eq $FALSE -And $Snapshot -eq $FALSE) {
$branch = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer;
} elseif ($Stable) {
$branch = 'stable';
} else {
$LatestRelease = (Invoke-WebRequest -Uri ([string]::Format('https://github.com/Icinga/{0}/releases/latest', $Repository)) -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri;
$DownloadUrl = $LatestRelease.Replace('/releases/tag/', '/archive/');
$Tag = $DownloadUrl.Split('/')[-1];
$branch = 'snapshot'
}
if ($branch.ToLower() -eq 'snapshot') {
$DownloadUrl = [string]::Format('https://github.com/{0}/{1}/archive/master.zip', $GitHubUser, $Repository);
} else {
try {
$LatestRelease = (Invoke-WebRequest -Uri ([string]::Format('https://github.com/{0}/{1}/releases/latest', $GitHubUser, $Repository)) -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri;
$DownloadUrl = $LatestRelease.Replace('/releases/tag/', '/archive/');
$Tag = $DownloadUrl.Split('/')[-1];
} catch {
Write-Host 'Failed to fetch latest release from GitHub. Either the module or the GitHub account do not exist';
}
$DownloadUrl = [string]::Format('{0}/{1}.zip', $DownloadUrl, $Tag);
$CurrentVersion = Get-IcingaPowerShellModuleVersion $Repository;
@ -41,6 +62,17 @@ function Get-IcingaPowerShellModuleArchive()
}
}
if ($DryRun) {
return @{
'DownloadUrl' = $DownloadUrl;
'Version' = $Tag;
'Directory' = '';
'Archive' = '';
'ModuleRoot' = (Get-IcingaFrameworkRootPath);
'Installed' = $FALSE;
};
}
try {
$DownloadDirectory = New-IcingaTemporaryDirectory;
$DownloadDestination = (Join-Path -Path $DownloadDirectory -ChildPath ([string]::Format('{0}.zip', $Repository)));

View file

@ -0,0 +1,83 @@
function Install-IcingaFrameworkComponent()
{
param(
[string]$Name,
[string]$GitHubUser = 'Icinga',
[string]$Url,
[switch]$Stable = $FALSE,
[switch]$Snapshot = $FALSE,
[switch]$DryRun = $FALSE
);
if ([string]::IsNullOrEmpty($Name)) {
throw 'Please specify a component name to install from a GitHub/Local space';
}
$TextInfo = (Get-Culture).TextInfo;
$ComponentName = $TextInfo.ToTitleCase($Name);
$RepositoryName = [string]::Format('icinga-powershell-{0}', $Name);
$Archive = Get-IcingaPowerShellModuleArchive `
-DownloadUrl $Url `
-GitHubUser $GitHubUser `
-ModuleName (
[string]::Format(
'Icinga Component {0}', $ComponentName
)
) `
-Repository $RepositoryName `
-Stable $Stable `
-Snapshot $Snapshot `
-DryRun $DryRun;
if ($Archive.Installed -eq $FALSE -Or $DryRun) {
return @{
'RepoUrl' = $Archive.DownloadUrl
};
}
Write-Host ([string]::Format('Installing module into "{0}"', ($Archive.Directory)));
Expand-IcingaZipArchive -Path $Archive.Archive -Destination $Archive.Directory | Out-Null;
$FolderContent = Get-ChildItem -Path $Archive.Directory;
$ModuleContent = $Archive.Directory;
foreach ($entry in $FolderContent) {
if ($entry -like ([string]::Format('{0}*', $RepositoryName))) {
$ModuleContent = Join-Path -Path $ModuleContent -ChildPath $entry;
break;
}
}
Write-Host ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent));
$PluginDirectory = (Join-Path -Path $Archive.ModuleRoot -ChildPath $RepositoryName);
if ((Test-Path $PluginDirectory) -eq $FALSE) {
Write-Host ([string]::Format('{0} Module Directory "{1}" is not present. Creating Directory', $ComponentName, $PluginDirectory));
New-Item -Path $PluginDirectory -ItemType Directory | Out-Null;
}
Write-Host ([string]::Format('Copying files to {0}', $ComponentName));
Copy-ItemSecure -Path (Join-Path -Path $ModuleContent -ChildPath '/*') -Destination $PluginDirectory -Recurse -Force | Out-Null;
Write-Host 'Cleaning temporary content';
Start-Sleep -Seconds 1;
Remove-ItemSecure -Path $Archive.Directory -Recurse -Force | Out-Null;
Unblock-IcingaPowerShellFiles -Path $PluginDirectory;
# In case the plugins are not installed before, load the framework again to
# include the plugins
Use-Icinga;
# Unload the module if it was loaded before
Remove-Module $RepositoryName -Force -ErrorAction SilentlyContinue;
# Now import the module
Import-Module $RepositoryName;
Write-Host ([string]::Format('Icinga component {0} update has been completed. Please start a new PowerShell to apply it', $ComponentName));
return @{
'RepoUrl' = $Archive.DownloadUrl
};
}

View file

@ -4,52 +4,12 @@ function Install-IcingaFrameworkPlugins()
[string]$PluginsUrl
);
$RepositoryName = 'icinga-powershell-plugins';
$Archive = Get-IcingaPowerShellModuleArchive -DownloadUrl $PluginsUrl -ModuleName 'Icinga Plugins' -Repository $RepositoryName;
if ($Archive.Installed -eq $FALSE) {
return @{
'PluginUrl' = $Archive.DownloadUrl
};
}
Write-Host ([string]::Format('Installing module into "{0}"', ($Archive.Directory)));
Expand-IcingaZipArchive -Path $Archive.Archive -Destination $Archive.Directory | Out-Null;
$FolderContent = Get-ChildItem -Path $Archive.Directory;
$ModuleContent = $Archive.Directory;
foreach ($entry in $FolderContent) {
if ($entry -like ([string]::Format('{0}*', $RepositoryName))) {
$ModuleContent = Join-Path -Path $ModuleContent -ChildPath $entry;
break;
}
}
Write-Host ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent));
$PluginDirectory = (Join-Path -Path $Archive.ModuleRoot -ChildPath $RepositoryName);
if ((Test-Path $PluginDirectory) -eq $FALSE) {
Write-Host ([string]::Format('Plugin Module Directory "{0}" is not present. Creating Directory', $PluginDirectory));
New-Item -Path $PluginDirectory -ItemType Directory | Out-Null;
}
Write-Host 'Copying files to plugins';
Copy-ItemSecure -Path (Join-Path -Path $ModuleContent -ChildPath '/*') -Destination $PluginDirectory -Recurse -Force | Out-Null;
Write-Host 'Cleaning temporary content';
Start-Sleep -Seconds 1;
Remove-ItemSecure -Path $Archive.Directory -Recurse -Force | Out-Null;
Unblock-IcingaPowerShellFiles -Path $PluginDirectory;
# In case the plugins are not installed before, load the framework again to
# include the plugins
Use-Icinga;
Write-Host 'Icinga Plugin update has been completed';
[Hashtable]$Result = Install-IcingaFrameworkComponent `
-Name 'plugins' `
-GitHubUser 'Icinga' `
-Url $PluginsUrl;
return @{
'PluginUrl' = $Archive.DownloadUrl
'PluginUrl' = $Result.RepoUrl;
};
}