disk_availability.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # pylint: disable=missing-docstring
  2. from openshift_checks import OpenShiftCheck, OpenShiftCheckException, get_var
  3. from openshift_checks.mixins import NotContainerizedMixin
  4. class DiskAvailability(NotContainerizedMixin, OpenShiftCheck):
  5. """Check that recommended disk space is available before a first-time install."""
  6. name = "disk_availability"
  7. tags = ["preflight"]
  8. # Values taken from the official installation documentation:
  9. # https://docs.openshift.org/latest/install_config/install/prerequisites.html#system-requirements
  10. recommended_disk_space_bytes = {
  11. "masters": 40 * 10**9,
  12. "nodes": 15 * 10**9,
  13. "etcd": 20 * 10**9,
  14. }
  15. @classmethod
  16. def is_active(cls, task_vars):
  17. """Skip hosts that do not have recommended disk space requirements."""
  18. group_names = get_var(task_vars, "group_names", default=[])
  19. has_disk_space_recommendation = bool(set(group_names).intersection(cls.recommended_disk_space_bytes))
  20. return super(DiskAvailability, cls).is_active(task_vars) and has_disk_space_recommendation
  21. def run(self, tmp, task_vars):
  22. group_names = get_var(task_vars, "group_names")
  23. ansible_mounts = get_var(task_vars, "ansible_mounts")
  24. min_free_bytes = max(self.recommended_disk_space_bytes.get(name, 0) for name in group_names)
  25. free_bytes = self.openshift_available_disk(ansible_mounts)
  26. if free_bytes < min_free_bytes:
  27. return {
  28. 'failed': True,
  29. 'msg': (
  30. 'Available disk space ({:.1f} GB) for the volume containing '
  31. '"/var" is below minimum recommended space ({:.1f} GB)'
  32. ).format(float(free_bytes) / 10**9, float(min_free_bytes) / 10**9)
  33. }
  34. return {}
  35. @staticmethod
  36. def openshift_available_disk(ansible_mounts):
  37. """Determine the available disk space for an OpenShift installation.
  38. ansible_mounts should be a list of dicts like the 'setup' Ansible module
  39. returns.
  40. """
  41. # priority list in descending order
  42. supported_mnt_paths = ["/var", "/"]
  43. available_mnts = {mnt.get("mount"): mnt for mnt in ansible_mounts}
  44. try:
  45. for path in supported_mnt_paths:
  46. if path in available_mnts:
  47. return available_mnts[path]["size_available"]
  48. except KeyError:
  49. pass
  50. paths = ''.join(sorted(available_mnts)) or 'none'
  51. msg = "Unable to determine available disk space. Paths mounted: {}.".format(paths)
  52. raise OpenShiftCheckException(msg)