livepatch-charmers team mailing list archive
-
livepatch-charmers team
-
Mailing list archive
-
Message #00211
Re: [Merge] ~barryprice/canonical-livepatch-charm/+git/canonical-livepatch-charm:master into canonical-livepatch-charm:master
Review: Approve
Seems ok. Some comments inline.
Diff comments:
> diff --git a/files/check_canonical-livepatch.py b/files/check_canonical-livepatch.py
> index 7878169..c6fffd8 100755
> --- a/files/check_canonical-livepatch.py
> +++ b/files/check_canonical-livepatch.py
> @@ -5,72 +5,122 @@
> import os
> import nagios_plugin
> from subprocess import check_output, call
> +from yaml import safe_load
>
> supported_archs = ['x86_64']
>
>
> ##############################################################################
>
> -def check_package_installed():
> +def check_snap_installed():
> + """Confirm the snap is installed, raise an error if not"""
> cmd = ['snap', 'list', 'canonical-livepatch']
> try:
> check_output(cmd, universal_newlines=True)
> except Exception:
> - raise nagios_plugin.CriticalError("canonical-livepatch snap is not installed")
> + raise nagios_plugin.CriticalError('canonical-livepatch snap is not installed')
>
>
> ##############################################################################
>
> -def check_vmlinuz():
> - vmlinuz = '/vmlinuz'
> - if os.path.exists(vmlinuz):
> - full_kernel_path = os.path.realpath(vmlinuz)
> - elif os.path.exists('/boot' + vmlinuz):
> - vmlinuz = '/boot' + vmlinuz
> - full_kernel_path = os.path.realpath(vmlinuz)
> - else:
> - return 'no /vmlinuz or /boot/vmlinuz'
> - kernel_filename = os.path.basename(full_kernel_path)
> - # remove 'vmlinuz'-' from start:
> - kernel_version = '-'.join(kernel_filename.split('-', 1)[1:])
> - # check for '-generic-pae' kernels that need two removes:
> - if '-generic-pae' in kernel_version:
> - kernel_version = '-'.join(kernel_version.split('-')[:-1])
> - # remove e.g. '-generic' from end:
> - kernel_version = '-'.join(kernel_version.split('-')[:-1])
> - return kernel_version.strip()
> +def load_status():
> + """Load the cached status from disk, return it as a string"""
> + livepatch_output_path = '/var/lib/nagios/canonical-livepatch-status.txt'
> +
> + with open(livepatch_output_path, 'r') as canonical_livepatch_log:
> + livepatch_status = canonical_livepatch_log.read()
> +
> + return livepatch_status
All the call sites decode this as YAML, so you might as well do that here.
> +
> +
> +##############################################################################
These lines are not really PEP8, which recommends functions be separated by two blank lines. I'd strip these everywhere, rather than perpetuate the antique formatting.
> +
> +def check_enabled():
> + """Confirm machine is enabled, raise an error if not"""
> + livepatch_status = load_status()
> + if 'Machine is not enabled' in livepatch_status:
> + raise nagios_plugin.CriticalError('Machine is not enabled.')
> +
> +
> +##############################################################################
> +
> +def active_kernel_version():
> + """Return the active kernel version, from livepatch's perspective"""
> + livepatch_status = load_status()
> + status_yaml = safe_load(livepatch_status)
> + for kernel in status_yaml.get('status'):
> + if kernel.get('running') is True:
> + return kernel.get('kernel')
>
>
> ##############################################################################
>
> def check_status():
> - livepatch_output_path = '/var/lib/nagios/canonical-livepatch-status.txt'
> - err_lines = []
> - wrn_lines = []
> + """Check the cached status, raise an error if we find any issues"""
> + livepatch_status = load_status()
> + err = ''
>
> - with open(livepatch_output_path, 'r') as canonical_livepatch_log:
> - for line in canonical_livepatch_log:
> - line = line.strip()
> - if 'State:' in line:
> - if 'apply-failed' in line:
> - err_lines.append('Livepatch failed to apply patches.')
> - elif 'check-failed' in line:
> - err_lines.append('Livepatch failed to check the remote service for patches.')
> - elif 'unknown' in line:
> - err_lines.append('Livepatch reports an unknown error.')
> - elif 'kernel-upgrade-required' in line:
> - err_lines.append('A kernel upgrade (and reboot) is required.')
> - elif 'Machine is not enabled' in line:
> - err_lines.append('Machine is not enabled.')
> -
> - if err_lines:
> - err = " ".join(err_lines)
> + status_yaml = safe_load(livepatch_status)
> +
> + for kernel in status_yaml.get('status'):
> + if kernel.get('running') is True:
> + check_state = kernel.get('livepatch').get('checkState')
> + patch_state = kernel.get('livepatch').get('patchState')
> +
> + check_state_errors = check_check_state(check_state)
> + patch_state_errors = check_patch_state(patch_state)
> +
> + if check_state_errors:
> + err = err + ' '.join(check_state_errors)
> +
> + if err != '':
> + err = err + ' '
> +
> + if patch_state_errors:
> + err = err + ' '.join(patch_state_errors)
> +
> + if err != '':
> raise nagios_plugin.CriticalError(err)
> - elif wrn_lines:
> - wrn = " ".join(wrn_lines)
> - raise nagios_plugin.WarnError(wrn)
>
>
> +##############################################################################
> +
> +def check_check_state(check_state):
> + """Check for issues with checkState, including unexpected output"""
> + error_list = []
> + if check_state in ['checked', 'needs-check']:
> + pass
> + elif check_state == 'check-failed':
> + error_list.append('Livepatch failed to check the remote service for patches.')
> + else:
> + error_list.append('Unknown check state: {}'.format(check_state))
> +
> + return error_list
This is weird, returning a list of errors when there can only be 0 or 1 elements. Changing this would simplify check_status
> +
> +
> +##############################################################################
> +
> +def check_patch_state(patch_state):
> + """Check for issues with patchState, including unexpected output"""
> + error_list = []
> + if patch_state in ['applied', 'nothing-to-apply']:
> + pass
> + elif patch_state == 'unapplied':
> + error_list.append('Livepatch has not applied the downloaded patches.')
> + elif patch_state == 'applied-with-bug':
> + error_list.append('Livepatch has detected a kernel bug while applying patches.')
> + elif patch_state == 'apply-failed':
> + error_list.append('Livepatch failed to apply patches.')
> + elif patch_state == 'kernel-upgrade-required':
> + error_list.append('A kernel upgrade (and reboot) is required.')
> + else:
> + error_list.append('Unknown patch state: {}'.format(patch_state))
> +
> + return error_list
Again, list of errors but there can only be 0 or 1 elements.
> +
> +
> +##############################################################################
> +
> def lsb_release():
> """Return /etc/lsb-release in a dict"""
> d = {}
--
https://code.launchpad.net/~barryprice/canonical-livepatch-charm/+git/canonical-livepatch-charm/+merge/355822
Your team Livepatch charm developers is subscribed to branch canonical-livepatch-charm:master.
References