mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2025-12-20 23:00:35 -05:00
Merge pull request #531 from Icinga:feature/icinga_state_file_test_and_repair
Feature: Adds test and repair for the Icinga Agent state file Adds new Cmdlets to test and repair the Icinga Agent state file, in case the file is corrupt. The `Test-IcingaAgent` will now check by default of the state is present and in case it is, if the file is healthy or corrupted. A repair command `Repair-IcingaStateFile` will remove the corrupted files afterwards to ensure the Icinga Agent can be started as service again.
This commit is contained in:
commit
1b2e3a6ee1
8 changed files with 112 additions and 2 deletions
|
|
@ -19,6 +19,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
|
||||||
|
|
||||||
* [#40](https://github.com/Icinga/icinga-powershell-framework/issues/40) Adds support to set service recovery for the Icinga Agent and Icinga for Windows service, to restart them in case of a crash or error
|
* [#40](https://github.com/Icinga/icinga-powershell-framework/issues/40) Adds support to set service recovery for the Icinga Agent and Icinga for Windows service, to restart them in case of a crash or error
|
||||||
* [#525](https://github.com/Icinga/icinga-powershell-framework/pull/525) Adds new developer mode for `icinga` command and improved cache handling, to ensure within `-DeveloperMode` and inside a VS Code environment, the framework cache file is never overwritten, while still all functions are loaded and imported.
|
* [#525](https://github.com/Icinga/icinga-powershell-framework/pull/525) Adds new developer mode for `icinga` command and improved cache handling, to ensure within `-DeveloperMode` and inside a VS Code environment, the framework cache file is never overwritten, while still all functions are loaded and imported.
|
||||||
|
* [#531](https://github.com/Icinga/icinga-powershell-framework/pull/531) Adds `Test-IcingaStateFile` and `Repair-IcingaStateFile`, which is integrated into `Test-IcingaAgent`, to ensure the Icinga Agent state file is healthy and not corrupt, causing the Icinga Agent to fail on start
|
||||||
|
|
||||||
## 1.9.1 (2022-05-13)
|
## 1.9.1 (2022-05-13)
|
||||||
|
|
||||||
|
|
|
||||||
46
lib/core/icingaagent/readers/Read-IcingaStateFile.psm1
Normal file
46
lib/core/icingaagent/readers/Read-IcingaStateFile.psm1
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
function Read-IcingaStateFile()
|
||||||
|
{
|
||||||
|
param (
|
||||||
|
[switch]$WriteOutput = $FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
[string]$StateFilePath = Join-Path -Path $ENV:ProgramData -ChildPath 'icinga2\var\lib\icinga2\icinga2.state';
|
||||||
|
|
||||||
|
if ((Test-Path $StateFilePath) -eq $FALSE) {
|
||||||
|
return $TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$StateFileContent = Get-Content -Path $StateFilePath -Encoding 'UTF8' -Raw;
|
||||||
|
$FileInformation = Get-Item -Path $StateFilePath;
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($StateFileContent)) {
|
||||||
|
return $FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($TRUE) {
|
||||||
|
try {
|
||||||
|
if ([string]::IsNullOrEmpty($StateFileContent)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($StateFileContent.Contains(':') -eq $FALSE) {
|
||||||
|
Write-IcingaTestOutput -Severity 'Failed' -Message 'The start index of the Icinga Agent state file could not be found. The file seems to be corrupt.' -DropMessage:(-Not $WriteOutput);
|
||||||
|
return $FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[int]$IndexOfJSON = $StateFileContent.IndexOf(':');
|
||||||
|
[int]$StatementSize = $StateFileContent.SubString(0, $IndexOfJSON);
|
||||||
|
[string]$JSONString = $StateFileContent.Substring($IndexOfJSON + 1, $StatementSize);
|
||||||
|
[int]$TotalMsgLen = $IndexOfJSON + $StatementSize + 2;
|
||||||
|
$StateFileContent = $StateFileContent.Substring($TotalMsgLen, $StateFileContent.Length - $TotalMsgLen);
|
||||||
|
$JsonValid = ConvertFrom-Json -InputObject $JSONString -ErrorAction Stop;
|
||||||
|
} catch {
|
||||||
|
[string]$ErrMessage = [string]::Format('The Icinga Agent state file validation failed with an exception: "{0}"', $_.Exception.Message);
|
||||||
|
Write-IcingaTestOutput -Severity 'Failed' -Message $ErrMessage -DropMessage:(-Not $WriteOutput);
|
||||||
|
|
||||||
|
return $FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $TRUE;
|
||||||
|
}
|
||||||
21
lib/core/icingaagent/repair/Repair-IcingaStateFile.psm1
Normal file
21
lib/core/icingaagent/repair/Repair-IcingaStateFile.psm1
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
function Repair-IcingaStateFile()
|
||||||
|
{
|
||||||
|
param (
|
||||||
|
[switch]$Force
|
||||||
|
);
|
||||||
|
|
||||||
|
[string]$StateFilePath = Join-Path -Path $ENV:ProgramData -ChildPath 'icinga2\var\lib\icinga2\icinga2.state*';
|
||||||
|
|
||||||
|
if ((Test-IcingaStateFile) -And $Force -eq $FALSE) {
|
||||||
|
Write-IcingaConsoleNotice -Message 'The Icinga Agent state file seems to be okay';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$Success = Remove-ItemSecure -Path $StateFilePath -Force -Retries 5;
|
||||||
|
|
||||||
|
if ($Success) {
|
||||||
|
Write-IcingaConsoleNotice -Message 'The corrupted Icinga Agent State files have been removed';
|
||||||
|
} else {
|
||||||
|
Write-IcingaConsoleError -Message 'Failed to remove the corrupted Icinga Agent state files';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ function Test-IcingaAgent()
|
||||||
Test-IcingaAcl (Get-IcingaCacheDir) -WriteOutput | Out-Null;
|
Test-IcingaAcl (Get-IcingaCacheDir) -WriteOutput | Out-Null;
|
||||||
Test-IcingaAcl (Get-IcingaPowerShellConfigDir) -WriteOutput | Out-Null;
|
Test-IcingaAcl (Get-IcingaPowerShellConfigDir) -WriteOutput | Out-Null;
|
||||||
Test-IcingaAcl -Directory (Join-Path -Path (Get-IcingaFrameworkRootPath) -ChildPath 'certificate') -WriteOutput | Out-Null;
|
Test-IcingaAcl -Directory (Join-Path -Path (Get-IcingaFrameworkRootPath) -ChildPath 'certificate') -WriteOutput | Out-Null;
|
||||||
|
Test-IcingaStateFile -WriteOutput | Out-Null;
|
||||||
|
|
||||||
if ($IcingaAgentData.Installed) {
|
if ($IcingaAgentData.Installed) {
|
||||||
Test-IcingaAgentConfig | Out-Null;
|
Test-IcingaAgentConfig | Out-Null;
|
||||||
|
|
|
||||||
25
lib/core/icingaagent/tests/Test-IcingaStateFile.psm1
Normal file
25
lib/core/icingaagent/tests/Test-IcingaStateFile.psm1
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
function Test-IcingaStateFile()
|
||||||
|
{
|
||||||
|
param (
|
||||||
|
[switch]$WriteOutput = $FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
$IcingaAgentData = Get-IcingaAgentInstallation;
|
||||||
|
[string]$StateFilePath = Join-Path -Path $ENV:ProgramData -ChildPath 'icinga2\var\lib\icinga2\icinga2.state';
|
||||||
|
|
||||||
|
if ((Test-Path $StateFilePath) -eq $FALSE) {
|
||||||
|
Write-IcingaTestOutput -Severity 'Passed' -Message 'The Icinga Agent state file does not exist' -DropMessage:(-Not $WriteOutput);
|
||||||
|
return $TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$Success = Read-IcingaStateFile;
|
||||||
|
|
||||||
|
if ($Success) {
|
||||||
|
Write-IcingaTestOutput -Severity 'Passed' -Message 'The Icinga Agent state file is healthy' -DropMessage:(-Not $WriteOutput);
|
||||||
|
return $TRUE;
|
||||||
|
} else {
|
||||||
|
Write-IcingaTestOutput -Severity 'Failed' -Message 'The Icinga Agent state file is corrupt. Use the "Repair-IcingaStateFile" command to repair the file or "Read-IcingaStateFile -WriteOutput" for further details' -DropMessage:(-Not $WriteOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $FALSE;
|
||||||
|
}
|
||||||
|
|
@ -3,9 +3,14 @@ function Write-IcingaTestOutput()
|
||||||
param(
|
param(
|
||||||
[ValidateSet('Passed', 'Warning', 'Failed')]
|
[ValidateSet('Passed', 'Warning', 'Failed')]
|
||||||
$Severity,
|
$Severity,
|
||||||
$Message
|
$Message,
|
||||||
|
[switch]$DropMessage = $FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($DropMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$Color = 'Green';
|
$Color = 'Green';
|
||||||
|
|
||||||
Switch ($Severity) {
|
Switch ($Severity) {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ function Show-IcingaForWindowsMenuManageTroubleshooting()
|
||||||
},
|
},
|
||||||
@{
|
@{
|
||||||
'Caption' = 'Repair Icinga Agent service';
|
'Caption' = 'Repair Icinga Agent service';
|
||||||
'Command' = 'Show-IcingaForWindowsMenuManageIcingaForWindowsServices';
|
'Command' = 'Show-IcingaForWindowsMenuManageTroubleshooting';
|
||||||
'Help' = 'Allows to repair the Icinga Agent service in case it was removed or broke during installation/upgrade';
|
'Help' = 'Allows to repair the Icinga Agent service in case it was removed or broke during installation/upgrade';
|
||||||
'Disabled' = ($null -ne $IcingaAgentService);
|
'Disabled' = ($null -ne $IcingaAgentService);
|
||||||
'DisabledReason' = 'The Icinga Agent service is already present';
|
'DisabledReason' = 'The Icinga Agent service is already present';
|
||||||
|
|
@ -52,6 +52,17 @@ function Show-IcingaForWindowsMenuManageTroubleshooting()
|
||||||
'Command' = 'Repair-IcingaService';
|
'Command' = 'Repair-IcingaService';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@{
|
||||||
|
'Caption' = 'Repair Icinga Agent state file';
|
||||||
|
'Command' = 'Show-IcingaForWindowsMenuManageTroubleshooting';
|
||||||
|
'Help' = 'Allows to repair the Icinga Agent state file, in case the file is corrupt';
|
||||||
|
'Disabled' = (Test-IcingaStateFile);
|
||||||
|
'DisabledReason' = 'The Icinga Agent state file is healthy';
|
||||||
|
'AdminMenu' = $TRUE;
|
||||||
|
'Action' = @{
|
||||||
|
'Command' = 'Repair-IcingaStateFile';
|
||||||
|
}
|
||||||
|
},
|
||||||
@{
|
@{
|
||||||
'Caption' = 'Allow untrusted certificate communication (This session)';
|
'Caption' = 'Allow untrusted certificate communication (This session)';
|
||||||
'Command' = 'Show-IcingaForWindowsMenuManageTroubleshooting';
|
'Command' = 'Show-IcingaForWindowsMenuManageTroubleshooting';
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue