From d2955189066364461a846e0e34d344c94b26a16b Mon Sep 17 00:00:00 2001 From: juanvallejo Date: Mon, 27 Feb 2017 17:52:02 -0500 Subject: add ram and storage preflight check --- .../openshift_checks/disk_availability.py | 73 ++++++++++++++++++++++ .../openshift_checks/memory_availability.py | 35 +++++++++++ 2 files changed, 108 insertions(+) create mode 100644 roles/openshift_health_checker/openshift_checks/disk_availability.py create mode 100644 roles/openshift_health_checker/openshift_checks/memory_availability.py (limited to 'roles/openshift_health_checker/openshift_checks') diff --git a/roles/openshift_health_checker/openshift_checks/disk_availability.py b/roles/openshift_health_checker/openshift_checks/disk_availability.py new file mode 100644 index 000000000..ecf5147fd --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/disk_availability.py @@ -0,0 +1,73 @@ +# pylint: disable=missing-docstring +from openshift_checks import OpenShiftCheck, OpenShiftCheckException, get_var +from openshift_checks.mixins import NotContainerizedMixin + + +class DiskAvailability(NotContainerizedMixin, OpenShiftCheck): + """Check that recommended disk space is available before a first-time install.""" + + name = "disk_availability" + tags = ["preflight"] + + # all values are base-10 as they are taken, as is, from + # the latest requirements for an OpenShift installation + # https://docs.openshift.org/latest/install_config/install/prerequisites.html#system-requirements + recommended_diskspace = { + "nodes": 15 * 10 ** 9, + "masters": 40 * 10 ** 9, + "etcd": 20 * 10 ** 9, + } + + def run(self, tmp, task_vars): + ansible_mounts = get_var(task_vars, "ansible_mounts") + self.recommended_diskspace["nodes"] = get_var(task_vars, + "min_recommended_diskspace_node", + default=self.recommended_diskspace["nodes"]) + self.recommended_diskspace["masters"] = get_var(task_vars, + "min_recommended_diskspace_master", + default=self.recommended_diskspace["masters"]) + self.recommended_diskspace["etcd"] = get_var(task_vars, + "min_recommended_diskspace_etcd", + default=self.recommended_diskspace["etcd"]) + + failed, msg = self.volume_check(ansible_mounts, task_vars) + return {"failed": failed, "msg": msg} + + def volume_check(self, ansible_mounts, task_vars): + group_names = get_var(task_vars, "group_names", default=[]) + + if not set(self.recommended_diskspace).intersection(group_names): + msg = "Unable to determine recommended volume size for group_name {group_name}" + raise OpenShiftCheckException(msg.format(group_name=group_names)) + + recommended_diskspace_bytes = max(self.recommended_diskspace.get(group, 0) for group in group_names) + openshift_diskfree_bytes = self.get_openshift_disk_availability(ansible_mounts) + + if openshift_diskfree_bytes < recommended_diskspace_bytes: + msg = ("Available disk space ({diskfree} GB) for the volume containing \"/var\" is " + "below recommended storage. Minimum required disk space: {recommended} GB") + return True, msg.format(diskfree=self.to_gigabytes(openshift_diskfree_bytes), + recommended=self.to_gigabytes(recommended_diskspace_bytes)) + + return False, "" + + @staticmethod + def get_openshift_disk_availability(ansible_mounts): + """Iterates through a map of mounted volumes to determine space remaining on the OpenShift volume""" + if not ansible_mounts: + msg = "Unable to determine existing volume mounts from ansible_mounts" + raise OpenShiftCheckException(msg) + + # priority list in descending order + supported_mnt_paths = ["/var", "/"] + available_mnts = {mnt.get("mount"): mnt for mnt in ansible_mounts} + + for path in supported_mnt_paths: + if path in available_mnts: + return available_mnts[path].get("size_available") + + return 0 + + @staticmethod + def to_gigabytes(total_bytes): + return total_bytes / 10**9 diff --git a/roles/openshift_health_checker/openshift_checks/memory_availability.py b/roles/openshift_health_checker/openshift_checks/memory_availability.py new file mode 100644 index 000000000..aa54b9535 --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/memory_availability.py @@ -0,0 +1,35 @@ +# pylint: disable=missing-docstring +from openshift_checks import OpenShiftCheck, get_var + + +class MemoryAvailability(OpenShiftCheck): + """Check that recommended memory is available.""" + + name = "memory_availability" + tags = ["preflight"] + + recommended_memory_mb = { + "nodes": 8 * 1000, + "masters": 16 * 1000, + "etcd": 10 * 1000, + } + + @classmethod + def is_active(cls, task_vars): + """Skip hosts that do not have recommended memory space requirements.""" + group_names = get_var(task_vars, "group_names", default=[]) + has_mem_space_recommendation = bool(set(group_names).intersection(cls.recommended_memory_mb)) + return super(MemoryAvailability, cls).is_active(task_vars) and has_mem_space_recommendation + + def run(self, tmp, task_vars): + group_names = get_var(task_vars, "group_names", default=[]) + total_memory = get_var(task_vars, "ansible_memtotal_mb") + + recommended_memory_mb = max(self.recommended_memory_mb.get(group, 0) for group in group_names) + + if total_memory < recommended_memory_mb: + msg = ("Available memory ({available} MB) below recommended storage. " + "Minimum required memory: {recommended} MB") + return {"failed": True, "msg": msg.format(available=total_memory, recommended=recommended_memory_mb)} + + return {"changed": False} -- cgit v1.2.3