sapling/eden/cli/doctor/check_os.py
Matt Glazar 93c0f175d6 Add default parameter to get_config_value
Summary:
`EdenInstance.get_config_value` raises a KeyError if the option or section is not set in any config files. Every caller of `EdenInstance.get_config_value` handles KeyError manually. Simplify code by letting callers specify a default value.

Aside from treating some options with an empty value as if they were unset, this diff should not change behavior.

Reviewed By: chadaustin

Differential Revision: D13737806

fbshipit-source-id: fdb7fa75d601de4644704813db38b671b27f73d7
2019-01-25 18:38:36 -08:00

103 lines
3.4 KiB
Python

#!/usr/bin/env python3
#
# Copyright (c) 2018-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
import platform
import re
from typing import Tuple
from eden.cli import ui
from eden.cli.config import EdenInstance
from eden.cli.doctor.problem import Problem, ProblemTracker
class OSProblem(Problem):
pass
def _parse_os_kernel_version(version: str) -> Tuple[int, ...]:
"""Parses kernel version string.
Example version string: 4.11.3-67_fbk17_4093_g2bf19e7a0b95
Returns integer representations of the version, eg. (4, 11, 3, 67).
"""
version = re.sub(r"[_-]", ".", version)
split_version = version.split(".")[:4]
parsed_kernel_version = tuple(map(int, split_version))
if len(parsed_kernel_version) < 4:
# right pad with zeros if the kernel version isn't 4 numbers
parsed_kernel_version = (
*parsed_kernel_version,
*[0] * (4 - len(parsed_kernel_version)),
)
return parsed_kernel_version
def _os_is_kernel_version_too_old(instance: EdenInstance, release: str) -> bool:
min_kernel_version = instance.get_config_value(
"doctor.minimum-kernel-version", default=""
)
if not min_kernel_version:
return False
try:
return _parse_os_kernel_version(release) < _parse_os_kernel_version(
min_kernel_version
)
except ValueError:
# If the kernel version failed to parse because one of the
# components wasn't an int, whatever.
return False
def _os_is_bad_release(instance: EdenInstance, release: str) -> bool:
known_bad_kernel_versions = instance.get_config_value(
"doctor.known-bad-kernel-versions", default=""
)
if not known_bad_kernel_versions:
return False
for regex in known_bad_kernel_versions.split(","):
if re.search(regex, release):
return True # matched known bad release
return False # no match to bad release
def run_operating_system_checks(
tracker: ProblemTracker, instance: EdenInstance, out: ui.Output
) -> None:
if platform.system() != "Linux":
return
# get kernel version string; same as "uname -r"
current_kernel_release = platform.release()
# check if version too low
result = _os_is_kernel_version_too_old(instance, current_kernel_release)
if result:
tracker.add_problem(
OSProblem(
# TODO: Reword these messages prior to public release
description=f"Kernel version {current_kernel_release} too low.",
remediation=f"Reboot to upgrade kernel version.",
)
)
# if the kernel version is too low, return here as continuing to
# further checks has no benefit
return
# check against known bad versions
result = _os_is_bad_release(instance, current_kernel_release)
if result:
tracker.add_problem(
OSProblem(
# TODO: Reword these messages prior to public release
description=f"Kernel {current_kernel_release} is a known "
+ "bad kernel.",
remediation="Reboot to upgrade kernel version.",
)
)
return