PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/mdadm_raid.py |
""" Salt module to manage RAID arrays with mdadm """ import logging import os import re import salt.utils.path from salt.exceptions import CommandExecutionError, SaltInvocationError # Set up logger log = logging.getLogger(__name__) # Define a function alias in order not to shadow built-in's __func_alias__ = {"list_": "list"} # Define the module's virtual name __virtualname__ = "raid" _VOL_REGEX_PATTERN_MATCH = r"^ARRAY\s+{0}\s+.*$" def __virtual__(): """ mdadm provides raid functions for Linux """ if __grains__["kernel"] != "Linux": return ( False, "The mdadm execution module cannot be loaded: only available on Linux.", ) if not salt.utils.path.which("mdadm"): return ( False, "The mdadm execution module cannot be loaded: the mdadm binary is not in" " the path.", ) return __virtualname__ def list_(): """ List the RAID devices. CLI Example: .. code-block:: bash salt '*' raid.list """ ret = {} for line in __salt__["cmd.run_stdout"]( ["mdadm", "--detail", "--scan"], python_shell=False ).splitlines(): if " " not in line: continue comps = line.split() device = comps[1] ret[device] = {"device": device} for comp in comps[2:]: key = comp.split("=")[0].lower() value = comp.split("=")[1] ret[device][key] = value return ret def detail(device="/dev/md0"): """ Show detail for a specified RAID device CLI Example: .. code-block:: bash salt '*' raid.detail '/dev/md0' """ ret = {} ret["members"] = {} # Lets make sure the device exists before running mdadm if not os.path.exists(device): msg = "Device {0} doesn't exist!" raise CommandExecutionError(msg.format(device)) cmd = ["mdadm", "--detail", device] for line in __salt__["cmd.run_stdout"](cmd, python_shell=False).splitlines(): if line.startswith(device): continue if " " not in line: continue if ":" not in line: if "/dev/" in line: comps = line.split() state = comps[4:-1] ret["members"][comps[0]] = { "device": comps[-1], "major": comps[1], "minor": comps[2], "number": comps[0], "raiddevice": comps[3], "state": " ".join(state), } continue comps = line.split(" : ") comps[0] = comps[0].lower() comps[0] = comps[0].strip() comps[0] = comps[0].replace(" ", "_") ret[comps[0]] = comps[1].strip() return ret def destroy(device): """ Destroy a RAID device. WARNING This will zero the superblock of all members of the RAID array.. CLI Example: .. code-block:: bash salt '*' raid.destroy /dev/md0 """ try: details = detail(device) except CommandExecutionError: return False stop_cmd = ["mdadm", "--stop", device] zero_cmd = ["mdadm", "--zero-superblock"] if __salt__["cmd.retcode"](stop_cmd, python_shell=False) == 0: for number in details["members"]: zero_cmd.append(details["members"][number]["device"]) __salt__["cmd.retcode"](zero_cmd, python_shell=False) # Remove entry from config file: if __grains__.get("os_family") == "Debian": cfg_file = "/etc/mdadm/mdadm.conf" else: cfg_file = "/etc/mdadm.conf" try: __salt__["file.replace"](cfg_file, f"ARRAY {device} .*", "") except SaltInvocationError: pass if __salt__["raid.list"]().get(device) is None: return True else: return False def stop(): """ Shut down all arrays that can be shut down (i.e. are not currently in use). CLI Example: .. code-block:: bash salt '*' raid.stop """ cmd = "mdadm --stop --scan" if __salt__["cmd.retcode"](cmd): return True return False def create(name, level, devices, metadata="default", test_mode=False, **kwargs): """ Create a RAID device. .. versionchanged:: 2014.7.0 .. warning:: Use with CAUTION, as this function can be very destructive if not used properly! CLI Examples: .. code-block:: bash salt '*' raid.create /dev/md0 level=1 chunk=256 devices="['/dev/xvdd', '/dev/xvde']" test_mode=True .. note:: Adding ``test_mode=True`` as an argument will print out the mdadm command that would have been run. name The name of the array to create. level The RAID level to use when creating the raid. devices A list of devices used to build the array. metadata Version of metadata to use when creating the array. kwargs Optional arguments to be passed to mdadm. returns test_mode=True: Prints out the full command. test_mode=False (Default): Executes command on remote the host(s) and Prints out the mdadm output. .. note:: It takes time to create a RAID array. You can check the progress in "resync_status:" field of the results from the following command: .. code-block:: bash salt '*' raid.detail /dev/md0 For more info, read the ``mdadm(8)`` manpage """ opts = [] raid_devices = len(devices) for key in kwargs: if not key.startswith("__"): opts.append(f"--{key}") if kwargs[key] is not True: opts.append(str(kwargs[key])) if key == "spare-devices": raid_devices -= int(kwargs[key]) cmd = ( ["mdadm", "-C", name, "-R", "-v", "-l", str(level)] + opts + ["-e", str(metadata), "-n", str(raid_devices)] + devices ) cmd_str = " ".join(cmd) if test_mode is True: return cmd_str elif test_mode is False: return __salt__["cmd.run"](cmd, python_shell=False) def save_config(): """ Save RAID configuration to config file. Same as: mdadm --detail --scan >> /etc/mdadm/mdadm.conf Fixes this issue with Ubuntu REF: http://askubuntu.com/questions/209702/why-is-my-raid-dev-md1-showing-up-as-dev-md126-is-mdadm-conf-being-ignored CLI Example: .. code-block:: bash salt '*' raid.save_config """ scan = __salt__["cmd.run"]("mdadm --detail --scan", python_shell=False).splitlines() # Issue with mdadm and ubuntu # REF: http://askubuntu.com/questions/209702/why-is-my-raid-dev-md1-showing-up-as-dev-md126-is-mdadm-conf-being-ignored if __grains__["os"] == "Ubuntu": buggy_ubuntu_tags = ["name", "metadata"] for i, elem in enumerate(scan): for bad_tag in buggy_ubuntu_tags: pattern = rf"\s{re.escape(bad_tag)}=\S+" pattern = re.compile(pattern, flags=re.I) scan[i] = re.sub(pattern, "", scan[i]) if __grains__.get("os_family") == "Debian": cfg_file = "/etc/mdadm/mdadm.conf" else: cfg_file = "/etc/mdadm.conf" try: vol_d = {line.split()[1]: line for line in scan} for vol in vol_d: pattern = _VOL_REGEX_PATTERN_MATCH.format(re.escape(vol)) __salt__["file.replace"]( cfg_file, pattern, vol_d[vol], append_if_not_found=True ) except SaltInvocationError: # File is missing __salt__["file.write"](cfg_file, args=scan) if __grains__.get("os_family") == "Debian": return __salt__["cmd.run"]("update-initramfs -u") elif __grains__.get("os_family") == "RedHat": return __salt__["cmd.run"]("dracut --force") def assemble(name, devices, test_mode=False, **kwargs): """ Assemble a RAID device. CLI Examples: .. code-block:: bash salt '*' raid.assemble /dev/md0 ['/dev/xvdd', '/dev/xvde'] .. note:: Adding ``test_mode=True`` as an argument will print out the mdadm command that would have been run. name The name of the array to assemble. devices The list of devices comprising the array to assemble. kwargs Optional arguments to be passed to mdadm. returns test_mode=True: Prints out the full command. test_mode=False (Default): Executes command on the host(s) and prints out the mdadm output. For more info, read the ``mdadm`` manpage. """ opts = [] for key in kwargs: if not key.startswith("__"): opts.append(f"--{key}") if kwargs[key] is not True: opts.append(kwargs[key]) # Devices may have been written with a blob: if isinstance(devices, str): devices = devices.split(",") cmd = ["mdadm", "-A", name, "-v"] + opts + devices if test_mode is True: return cmd elif test_mode is False: return __salt__["cmd.run"](cmd, python_shell=False) def examine(device, quiet=False): """ Show detail for a specified RAID component device device Device to examine, that is part of the RAID quiet If the device is not part of the RAID, do not show any error CLI Example: .. code-block:: bash salt '*' raid.examine '/dev/sda1' """ res = __salt__["cmd.run_stdout"]( f"mdadm -Y -E {device}", python_shell=False, ignore_retcode=quiet ) ret = {} for line in res.splitlines(): name, var = line.partition("=")[::2] ret[name] = var return ret def add(name, device): """ Add new device to RAID array. CLI Example: .. code-block:: bash salt '*' raid.add /dev/md0 /dev/sda1 """ cmd = f"mdadm --manage {name} --add {device}" if __salt__["cmd.retcode"](cmd) == 0: return True return False