bd305606ba
Rebase to latest upstream (1937938) Related: rhbz#1961404
3662 lines
136 KiB
Diff
3662 lines
136 KiB
Diff
From 0a69c057b41890d3d426ac10dfc198e7a3dbab4e Mon Sep 17 00:00:00 2001
|
|
From: Rich Megginson <rmeggins@redhat.com>
|
|
Date: Wed, 3 Mar 2021 07:55:20 -0700
|
|
Subject: [PATCH] resolve ansible-test issues
|
|
|
|
This fixes many formatting issues as well to make black, flake8,
|
|
pylint, yamllint, and ansible-lint happier.
|
|
---
|
|
.github/workflows/tox.yml | 4 +-
|
|
.sanity-ansible-ignore-2.9.txt | 13 +
|
|
library/blivet.py | 968 +++++++++++-------
|
|
library/blockdev_info.py | 45 +-
|
|
library/bsize.py | 56 +-
|
|
library/find_unused_disk.py | 101 +-
|
|
library/lvm_gensym.py | 119 ++-
|
|
library/resolve_blockdev.py | 71 +-
|
|
module_utils/storage_lsr/size.py | 86 +-
|
|
tests/setup_module_utils.sh | 41 -
|
|
tests/test-verify-volume-device.yml | 4 +-
|
|
tests/test-verify-volume-md.yml | 2 +-
|
|
tests/test.yml | 2 +-
|
|
tests/tests_create_lv_size_equal_to_vg.yml | 28 +-
|
|
...ts_create_partition_volume_then_remove.yml | 4 +-
|
|
tests/tests_existing_lvm_pool.yml | 12 +-
|
|
tests/tests_lvm_auto_size_cap.yml | 42 +-
|
|
tests/tests_lvm_one_disk_one_volume.yml | 46 +-
|
|
tests/tests_misc.yml | 2 +-
|
|
tests/tests_null_raid_pool.yml | 14 +-
|
|
tests/tests_resize.yml | 86 +-
|
|
tests/unit/bsize_test.py | 5 +
|
|
tests/unit/gensym_test.py | 103 +-
|
|
tests/unit/resolve_blockdev_test.py | 74 +-
|
|
tests/unit/test_unused_disk.py | 73 +-
|
|
tox.ini | 6 -
|
|
26 files changed, 1177 insertions(+), 830 deletions(-)
|
|
create mode 100644 .sanity-ansible-ignore-2.9.txt
|
|
delete mode 100755 tests/setup_module_utils.sh
|
|
|
|
diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml
|
|
index eceb71f..ec3ec9f 100644
|
|
--- a/.github/workflows/tox.yml
|
|
+++ b/.github/workflows/tox.yml
|
|
@@ -3,7 +3,7 @@ name: tox
|
|
on: # yamllint disable-line rule:truthy
|
|
- pull_request
|
|
env:
|
|
- TOX_LSR: "git+https://github.com/linux-system-roles/tox-lsr@2.2.0"
|
|
+ TOX_LSR: "git+https://github.com/linux-system-roles/tox-lsr@2.3.0"
|
|
LSR_ANSIBLES: 'ansible==2.8.* ansible==2.9.*'
|
|
LSR_MSCENARIOS: default
|
|
# LSR_EXTRA_PACKAGES: libdbus-1-dev
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
toxenvs="py${toxpyver}"
|
|
case "$toxpyver" in
|
|
27) toxenvs="${toxenvs},coveralls,flake8,pylint,custom" ;;
|
|
- 36) toxenvs="${toxenvs},coveralls,black,yamllint,ansible-lint,shellcheck,custom,collection" ;;
|
|
+ 36) toxenvs="${toxenvs},coveralls,black,yamllint,ansible-lint,shellcheck,custom,collection,ansible-test" ;;
|
|
37) toxenvs="${toxenvs},coveralls,custom" ;;
|
|
38) toxenvs="${toxenvs},coveralls,custom" ;;
|
|
esac
|
|
diff --git a/.sanity-ansible-ignore-2.9.txt b/.sanity-ansible-ignore-2.9.txt
|
|
new file mode 100644
|
|
index 0000000..bf700c6
|
|
--- /dev/null
|
|
+++ b/.sanity-ansible-ignore-2.9.txt
|
|
@@ -0,0 +1,13 @@
|
|
+plugins/modules/blivet.py import-2.7!skip
|
|
+plugins/modules/blivet.py import-3.5!skip
|
|
+plugins/modules/blivet.py import-3.6!skip
|
|
+plugins/modules/blivet.py import-3.7!skip
|
|
+plugins/modules/blivet.py import-3.8!skip
|
|
+tests/storage/unit/gensym_test.py shebang!skip
|
|
+plugins/modules/blivet.py validate-modules:import-error
|
|
+plugins/modules/blivet.py validate-modules:missing-gplv3-license
|
|
+plugins/modules/blockdev_info.py validate-modules:missing-gplv3-license
|
|
+plugins/modules/bsize.py validate-modules:missing-gplv3-license
|
|
+plugins/modules/find_unused_disk.py validate-modules:missing-gplv3-license
|
|
+plugins/modules/lvm_gensym.py validate-modules:missing-gplv3-license
|
|
+plugins/modules/resolve_blockdev.py validate-modules:missing-gplv3-license
|
|
diff --git a/library/blivet.py b/library/blivet.py
|
|
index 946b640..0e0b30c 100644
|
|
--- a/library/blivet.py
|
|
+++ b/library/blivet.py
|
|
@@ -1,12 +1,16 @@
|
|
#!/usr/bin/python
|
|
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
ANSIBLE_METADATA = {
|
|
- 'metadata_version': '1.1',
|
|
- 'status': ['preview'],
|
|
- 'supported_by': 'community'
|
|
+ "metadata_version": "1.1",
|
|
+ "status": ["preview"],
|
|
+ "supported_by": "community",
|
|
}
|
|
|
|
-DOCUMENTATION = '''
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: blivet
|
|
|
|
@@ -15,6 +19,7 @@ short_description: Module for management of linux block device stacks
|
|
version_added: "2.5"
|
|
|
|
description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
- "Module configures storage pools and volumes to match the state specified
|
|
in input parameters. It does not do any management of /etc/fstab entries."
|
|
|
|
@@ -30,7 +35,8 @@ options:
|
|
- boolean indicating whether to create partitions on disks for pool backing devices
|
|
disklabel_type:
|
|
description:
|
|
- - disklabel type string (eg: 'gpt') to use, overriding the built-in logic in blivet
|
|
+ - |
|
|
+ disklabel type string (eg: 'gpt') to use, overriding the built-in logic in blivet
|
|
safe_mode:
|
|
description:
|
|
- boolean indicating that we should fail rather than implicitly/automatically
|
|
@@ -41,10 +47,10 @@ options:
|
|
when creating a disk volume (that is, a whole disk filesystem)
|
|
|
|
author:
|
|
- - David Lehman (dlehman@redhat.com)
|
|
-'''
|
|
+ - David Lehman (@dwlehman)
|
|
+"""
|
|
|
|
-EXAMPLES = '''
|
|
+EXAMPLES = """
|
|
|
|
- name: Manage devices
|
|
blivet:
|
|
@@ -64,28 +70,40 @@ EXAMPLES = '''
|
|
mount_point: /whole_disk1
|
|
fs_type: ext4
|
|
mount_options: journal_checksum,async,noexec
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
actions:
|
|
description: list of dicts describing actions taken
|
|
- type: list of dict
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
leaves:
|
|
description: list of paths to leaf devices
|
|
- type: list of str
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
mounts:
|
|
description: list of dicts describing mounts to set up
|
|
- type: list of dict
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
crypts:
|
|
description: list of dicts describing crypttab entries to set up
|
|
- type: list of dict
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
pools:
|
|
description: list of dicts describing the pools w/ device path for each volume
|
|
- type: list of dict
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
volumes:
|
|
description: list of dicts describing the volumes w/ device path for each
|
|
- type: list of dict
|
|
-'''
|
|
+ returned: success
|
|
+ type: list
|
|
+ elements: dict
|
|
+"""
|
|
|
|
import logging
|
|
import os
|
|
@@ -106,7 +124,8 @@ try:
|
|
from blivet3.size import Size
|
|
from blivet3.udev import trigger
|
|
from blivet3.util import set_up_logging
|
|
- BLIVET_PACKAGE = 'blivet3'
|
|
+
|
|
+ BLIVET_PACKAGE = "blivet3"
|
|
except ImportError:
|
|
LIB_IMP_ERR3 = traceback.format_exc()
|
|
try:
|
|
@@ -119,7 +138,8 @@ except ImportError:
|
|
from blivet.size import Size
|
|
from blivet.udev import trigger
|
|
from blivet.util import set_up_logging
|
|
- BLIVET_PACKAGE = 'blivet'
|
|
+
|
|
+ BLIVET_PACKAGE = "blivet"
|
|
except ImportError:
|
|
LIB_IMP_ERR = traceback.format_exc()
|
|
|
|
@@ -135,23 +155,23 @@ MAX_TRIM_PERCENT = 2
|
|
|
|
use_partitions = None # create partitions on pool backing device disks?
|
|
disklabel_type = None # user-specified disklabel type
|
|
-safe_mode = None # do not remove any existing devices or formatting
|
|
+safe_mode = None # do not remove any existing devices or formatting
|
|
pool_defaults = dict()
|
|
volume_defaults = dict()
|
|
|
|
|
|
def find_duplicate_names(dicts):
|
|
- """ Return a list of names that appear more than once in a list of dicts.
|
|
+ """Return a list of names that appear more than once in a list of dicts.
|
|
|
|
- Items can be a list of any dicts with a 'name' key; that's all we're
|
|
- looking at. """
|
|
+ Items can be a list of any dicts with a 'name' key; that's all we're
|
|
+ looking at."""
|
|
names = list()
|
|
duplicates = list()
|
|
for item in dicts:
|
|
- if item['name'] in names and item['name'] not in duplicates:
|
|
- duplicates.append(item['name'])
|
|
+ if item["name"] in names and item["name"] not in duplicates:
|
|
+ duplicates.append(item["name"])
|
|
else:
|
|
- names.append(item['name'])
|
|
+ names.append(item["name"])
|
|
|
|
return duplicates
|
|
|
|
@@ -177,41 +197,54 @@ class BlivetBase(object):
|
|
global safe_mode
|
|
ret = device
|
|
# Make sure to handle adjusting both existing stacks and future stacks.
|
|
- if device == device.raw_device and self._spec_dict['encryption']:
|
|
+ if device == device.raw_device and self._spec_dict["encryption"]:
|
|
# add luks
|
|
luks_name = "luks-%s" % device._name
|
|
- if safe_mode and (device.original_format.type is not None or
|
|
- device.original_format.name != get_format(None).name):
|
|
- raise BlivetAnsibleError("cannot remove existing formatting on device '%s' in safe mode due to adding encryption" %
|
|
- device._name)
|
|
+ if safe_mode and (
|
|
+ device.original_format.type is not None
|
|
+ or device.original_format.name != get_format(None).name
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove existing formatting on device '%s' in safe mode due to adding encryption"
|
|
+ % device._name
|
|
+ )
|
|
if not device.format.exists:
|
|
fmt = device.format
|
|
else:
|
|
fmt = get_format(None)
|
|
|
|
- self._blivet.format_device(device,
|
|
- get_format("luks",
|
|
- name=luks_name,
|
|
- cipher=self._spec_dict.get('encryption_cipher'),
|
|
- key_size=self._spec_dict.get('encryption_key_size'),
|
|
- luks_version=self._spec_dict.get('encryption_luks_version'),
|
|
- passphrase=self._spec_dict.get('encryption_password') or None,
|
|
- key_file=self._spec_dict.get('encryption_key') or None))
|
|
+ self._blivet.format_device(
|
|
+ device,
|
|
+ get_format(
|
|
+ "luks",
|
|
+ name=luks_name,
|
|
+ cipher=self._spec_dict.get("encryption_cipher"),
|
|
+ key_size=self._spec_dict.get("encryption_key_size"),
|
|
+ luks_version=self._spec_dict.get("encryption_luks_version"),
|
|
+ passphrase=self._spec_dict.get("encryption_password") or None,
|
|
+ key_file=self._spec_dict.get("encryption_key") or None,
|
|
+ ),
|
|
+ )
|
|
|
|
if not device.format.has_key:
|
|
- raise BlivetAnsibleError("encrypted %s '%s' missing key/password" % (self._type, self._spec_dict['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "encrypted %s '%s' missing key/password"
|
|
+ % (self._type, self._spec_dict["name"])
|
|
+ )
|
|
|
|
- luks_device = devices.LUKSDevice(luks_name,
|
|
- fmt=fmt,
|
|
- parents=[device])
|
|
+ luks_device = devices.LUKSDevice(luks_name, fmt=fmt, parents=[device])
|
|
self._blivet.create_device(luks_device)
|
|
ret = luks_device
|
|
- elif device != device.raw_device and not self._spec_dict['encryption']:
|
|
+ elif device != device.raw_device and not self._spec_dict["encryption"]:
|
|
# remove luks
|
|
- if safe_mode and (device.original_format.type is not None or
|
|
- device.original_format.name != get_format(None).name):
|
|
- raise BlivetAnsibleError("cannot remove existing formatting on device '%s' in safe mode due to encryption removal" %
|
|
- device._name)
|
|
+ if safe_mode and (
|
|
+ device.original_format.type is not None
|
|
+ or device.original_format.name != get_format(None).name
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove existing formatting on device '%s' in safe mode due to encryption removal"
|
|
+ % device._name
|
|
+ )
|
|
if not device.format.exists:
|
|
fmt = device.format
|
|
else:
|
|
@@ -240,12 +273,21 @@ class BlivetBase(object):
|
|
requested_spares = self._spec_dict.get("raid_spare_count")
|
|
|
|
if requested_actives is not None and requested_spares is not None:
|
|
- if (requested_actives + requested_spares != len(members) or
|
|
- requested_actives < 0 or requested_spares < 0):
|
|
- raise BlivetAnsibleError("failed to set up '%s': cannot create RAID "
|
|
- "with %s members (%s active and %s spare)"
|
|
- % (self._spec_dict["name"], len(members),
|
|
- requested_actives, requested_spares))
|
|
+ if (
|
|
+ requested_actives + requested_spares != len(members)
|
|
+ or requested_actives < 0
|
|
+ or requested_spares < 0
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to set up '%s': cannot create RAID "
|
|
+ "with %s members (%s active and %s spare)"
|
|
+ % (
|
|
+ self._spec_dict["name"],
|
|
+ len(members),
|
|
+ requested_actives,
|
|
+ requested_spares,
|
|
+ )
|
|
+ )
|
|
|
|
if requested_actives is not None:
|
|
active_count = requested_actives
|
|
@@ -264,16 +306,20 @@ class BlivetBase(object):
|
|
raise BlivetAnsibleError("chunk size must be multiple of 4 KiB")
|
|
|
|
try:
|
|
- raid_array = self._blivet.new_mdarray(name=raid_name,
|
|
- level=self._spec_dict["raid_level"],
|
|
- member_devices=active_count,
|
|
- total_devices=len(members),
|
|
- parents=members,
|
|
- chunk_size=chunk_size,
|
|
- metadata_version=self._spec_dict.get("raid_metadata_version"),
|
|
- fmt=self._get_format())
|
|
+ raid_array = self._blivet.new_mdarray(
|
|
+ name=raid_name,
|
|
+ level=self._spec_dict["raid_level"],
|
|
+ member_devices=active_count,
|
|
+ total_devices=len(members),
|
|
+ parents=members,
|
|
+ chunk_size=chunk_size,
|
|
+ metadata_version=self._spec_dict.get("raid_metadata_version"),
|
|
+ fmt=self._get_format(),
|
|
+ )
|
|
except ValueError as e:
|
|
- raise BlivetAnsibleError("cannot create RAID '%s': %s" % (raid_name, str(e)))
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot create RAID '%s': %s" % (raid_name, str(e))
|
|
+ )
|
|
|
|
return raid_array
|
|
|
|
@@ -298,17 +344,18 @@ class BlivetVolume(BlivetBase):
|
|
if self.__class__.blivet_device_class is not None:
|
|
packages.extend(self.__class__.blivet_device_class._packages)
|
|
|
|
- fmt = get_format(self._volume.get('fs_type'))
|
|
+ fmt = get_format(self._volume.get("fs_type"))
|
|
packages.extend(fmt.packages)
|
|
- if self._volume.get('encryption'):
|
|
- packages.extend(get_format('luks').packages)
|
|
+ if self._volume.get("encryption"):
|
|
+ packages.extend(get_format("luks").packages)
|
|
return packages
|
|
|
|
@property
|
|
def ultimately_present(self):
|
|
""" Should this volume be present when we are finished? """
|
|
- return (self._volume.get('state', 'present') == 'present' and
|
|
- (self._blivet_pool is None or self._blivet_pool.ultimately_present))
|
|
+ return self._volume.get("state", "present") == "present" and (
|
|
+ self._blivet_pool is None or self._blivet_pool.ultimately_present
|
|
+ )
|
|
|
|
def _type_check(self): # pylint: disable=no-self-use
|
|
""" Is self._device of the correct type? """
|
|
@@ -316,7 +363,7 @@ class BlivetVolume(BlivetBase):
|
|
|
|
def _get_device_id(self):
|
|
""" Return an identifier by which to try looking the volume up. """
|
|
- return self._volume['name']
|
|
+ return self._volume["name"]
|
|
|
|
def _look_up_device(self):
|
|
""" Try to look up this volume in blivet's device tree. """
|
|
@@ -331,14 +378,14 @@ class BlivetVolume(BlivetBase):
|
|
if device is None:
|
|
return
|
|
|
|
- if device.format.type == 'luks':
|
|
+ if device.format.type == "luks":
|
|
# XXX If we have no key we will always re-encrypt.
|
|
- device.format._key_file = self._volume.get('encryption_key')
|
|
- device.format.passphrase = self._volume.get('encryption_password')
|
|
+ device.format._key_file = self._volume.get("encryption_key")
|
|
+ device.format.passphrase = self._volume.get("encryption_password")
|
|
|
|
# set up the original format as well since it'll get used for processing
|
|
- device.original_format._key_file = self._volume.get('encryption_key')
|
|
- device.original_format.passphrase = self._volume.get('encryption_password')
|
|
+ device.original_format._key_file = self._volume.get("encryption_key")
|
|
+ device.original_format.passphrase = self._volume.get("encryption_password")
|
|
if device.isleaf:
|
|
self._blivet.populate()
|
|
|
|
@@ -361,26 +408,31 @@ class BlivetVolume(BlivetBase):
|
|
elif encrypted:
|
|
luks_fmt = self._device.format
|
|
|
|
- if param_name == 'size':
|
|
- self._volume['size'] = int(self._device.size.convert_to())
|
|
- elif param_name == 'fs_type' and (self._device.format.type or self._device.format.name != get_format(None).name):
|
|
- self._volume['fs_type'] = self._device.format.type
|
|
- elif param_name == 'fs_label':
|
|
- self._volume['fs_label'] = getattr(self._device.format, 'label', "") or ""
|
|
- elif param_name == 'mount_point':
|
|
- self._volume['mount_point'] = getattr(self._device.format, 'mountpoint', None)
|
|
- elif param_name == 'disks':
|
|
- self._volume['disks'] = [d.name for d in self._device.disks]
|
|
- elif param_name == 'encryption':
|
|
- self._volume['encryption'] = encrypted
|
|
- elif param_name == 'encryption_key_size' and encrypted:
|
|
- self._volume['encryption_key_size'] = luks_fmt.key_size
|
|
- elif param_name == 'encryption_key_file' and encrypted:
|
|
- self._volume['encryption_key_file'] = luks_fmt.key_file
|
|
- elif param_name == 'encryption_cipher' and encrypted:
|
|
- self._volume['encryption_cipher'] = luks_fmt.cipher
|
|
- elif param_name == 'encryption_luks_version' and encrypted:
|
|
- self._volume['encryption_luks_version'] = luks_fmt.luks_version
|
|
+ if param_name == "size":
|
|
+ self._volume["size"] = int(self._device.size.convert_to())
|
|
+ elif param_name == "fs_type" and (
|
|
+ self._device.format.type
|
|
+ or self._device.format.name != get_format(None).name
|
|
+ ):
|
|
+ self._volume["fs_type"] = self._device.format.type
|
|
+ elif param_name == "fs_label":
|
|
+ self._volume["fs_label"] = getattr(self._device.format, "label", "") or ""
|
|
+ elif param_name == "mount_point":
|
|
+ self._volume["mount_point"] = getattr(
|
|
+ self._device.format, "mountpoint", None
|
|
+ )
|
|
+ elif param_name == "disks":
|
|
+ self._volume["disks"] = [d.name for d in self._device.disks]
|
|
+ elif param_name == "encryption":
|
|
+ self._volume["encryption"] = encrypted
|
|
+ elif param_name == "encryption_key_size" and encrypted:
|
|
+ self._volume["encryption_key_size"] = luks_fmt.key_size
|
|
+ elif param_name == "encryption_key_file" and encrypted:
|
|
+ self._volume["encryption_key_file"] = luks_fmt.key_file
|
|
+ elif param_name == "encryption_cipher" and encrypted:
|
|
+ self._volume["encryption_cipher"] = luks_fmt.cipher
|
|
+ elif param_name == "encryption_luks_version" and encrypted:
|
|
+ self._volume["encryption_luks_version"] = luks_fmt.luks_version
|
|
else:
|
|
return False
|
|
|
|
@@ -392,7 +444,7 @@ class BlivetVolume(BlivetBase):
|
|
if name in self._volume:
|
|
continue
|
|
|
|
- default = None if default in ('none', 'None', 'null') else default
|
|
+ default = None if default in ("none", "None", "null") else default
|
|
|
|
if self._device:
|
|
# Apply values from the device if it already exists.
|
|
@@ -403,12 +455,17 @@ class BlivetVolume(BlivetBase):
|
|
|
|
def _get_format(self):
|
|
""" Return a blivet.formats.DeviceFormat instance for this volume. """
|
|
- fmt = get_format(self._volume['fs_type'],
|
|
- mountpoint=self._volume.get('mount_point'),
|
|
- label=self._volume['fs_label'],
|
|
- create_options=self._volume['fs_create_options'])
|
|
+ fmt = get_format(
|
|
+ self._volume["fs_type"],
|
|
+ mountpoint=self._volume.get("mount_point"),
|
|
+ label=self._volume["fs_label"],
|
|
+ create_options=self._volume["fs_create_options"],
|
|
+ )
|
|
if not fmt.supported or not fmt.formattable:
|
|
- raise BlivetAnsibleError("required tools for file system '%s' are missing" % self._volume['fs_type'])
|
|
+ raise BlivetAnsibleError(
|
|
+ "required tools for file system '%s' are missing"
|
|
+ % self._volume["fs_type"]
|
|
+ )
|
|
|
|
return fmt
|
|
|
|
@@ -422,9 +479,9 @@ class BlivetVolume(BlivetBase):
|
|
return
|
|
|
|
# save device identifiers for use by the role
|
|
- self._volume['_device'] = self._device.path
|
|
- self._volume['_raw_device'] = self._device.raw_device.path
|
|
- self._volume['_mount_id'] = self._device.fstab_spec
|
|
+ self._volume["_device"] = self._device.path
|
|
+ self._volume["_raw_device"] = self._device.raw_device.path
|
|
+ self._volume["_mount_id"] = self._device.fstab_spec
|
|
|
|
# schedule removal of this device and any descendant devices
|
|
self._blivet.devicetree.recursive_remove(self._device.raw_device)
|
|
@@ -435,9 +492,12 @@ class BlivetVolume(BlivetBase):
|
|
def _resize(self):
|
|
""" Schedule actions as needed to ensure the device has the desired size. """
|
|
try:
|
|
- size = Size(self._volume['size'])
|
|
+ size = Size(self._volume["size"])
|
|
except Exception:
|
|
- raise BlivetAnsibleError("invalid size specification for volume '%s': '%s'" % (self._volume['name'], self._volume['size']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "invalid size specification for volume '%s': '%s'"
|
|
+ % (self._volume["name"], self._volume["size"])
|
|
+ )
|
|
|
|
if size and self._device.size != size:
|
|
try:
|
|
@@ -448,28 +508,44 @@ class BlivetVolume(BlivetBase):
|
|
if not self._device.resizable:
|
|
return
|
|
|
|
- trim_percent = (1.0 - float(self._device.max_size / size))*100
|
|
- log.debug("resize: size=%s->%s ; trim=%s", self._device.size, size, trim_percent)
|
|
+ trim_percent = (1.0 - float(self._device.max_size / size)) * 100
|
|
+ log.debug(
|
|
+ "resize: size=%s->%s ; trim=%s", self._device.size, size, trim_percent
|
|
+ )
|
|
if size > self._device.max_size and trim_percent <= MAX_TRIM_PERCENT:
|
|
- log.info("adjusting %s resize target from %s to %s to fit in free space",
|
|
- self._volume['name'],
|
|
- size,
|
|
- self._device.max_size)
|
|
+ log.info(
|
|
+ "adjusting %s resize target from %s to %s to fit in free space",
|
|
+ self._volume["name"],
|
|
+ size,
|
|
+ self._device.max_size,
|
|
+ )
|
|
size = self._device.max_size
|
|
if size == self._device.size:
|
|
return
|
|
|
|
if not self._device.min_size <= size <= self._device.max_size:
|
|
- raise BlivetAnsibleError("volume '%s' cannot be resized to '%s'" % (self._volume['name'], size))
|
|
+ raise BlivetAnsibleError(
|
|
+ "volume '%s' cannot be resized to '%s'"
|
|
+ % (self._volume["name"], size)
|
|
+ )
|
|
|
|
try:
|
|
self._blivet.resize_device(self._device, size)
|
|
except ValueError as e:
|
|
- raise BlivetAnsibleError("volume '%s' cannot be resized from %s to %s: %s" % (self._device.name,
|
|
- self._device.size,
|
|
- size, str(e)))
|
|
- elif size and self._device.exists and self._device.size != size and not self._device.resizable:
|
|
- raise BlivetAnsibleError("volume '%s' cannot be resized from %s to %s" % (self._device.name, self._device.size, size))
|
|
+ raise BlivetAnsibleError(
|
|
+ "volume '%s' cannot be resized from %s to %s: %s"
|
|
+ % (self._device.name, self._device.size, size, str(e))
|
|
+ )
|
|
+ elif (
|
|
+ size
|
|
+ and self._device.exists
|
|
+ and self._device.size != size
|
|
+ and not self._device.resizable
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "volume '%s' cannot be resized from %s to %s"
|
|
+ % (self._device.name, self._device.size, size)
|
|
+ )
|
|
|
|
def _reformat(self):
|
|
""" Schedule actions as needed to ensure the volume is formatted as specified. """
|
|
@@ -477,10 +553,18 @@ class BlivetVolume(BlivetBase):
|
|
if self._device.format.type == fmt.type:
|
|
return
|
|
|
|
- if safe_mode and (self._device.format.type is not None or self._device.format.name != get_format(None).name):
|
|
- raise BlivetAnsibleError("cannot remove existing formatting on volume '%s' in safe mode" % self._volume['name'])
|
|
-
|
|
- if self._device.format.status and (self._device.format.mountable or self._device.format.type == "swap"):
|
|
+ if safe_mode and (
|
|
+ self._device.format.type is not None
|
|
+ or self._device.format.name != get_format(None).name
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove existing formatting on volume '%s' in safe mode"
|
|
+ % self._volume["name"]
|
|
+ )
|
|
+
|
|
+ if self._device.format.status and (
|
|
+ self._device.format.mountable or self._device.format.type == "swap"
|
|
+ ):
|
|
self._device.format.teardown()
|
|
if not self._device.isleaf:
|
|
self._blivet.devicetree.recursive_remove(self._device, remove_device=False)
|
|
@@ -503,7 +587,9 @@ class BlivetVolume(BlivetBase):
|
|
|
|
# at this point we should have a blivet.devices.StorageDevice instance
|
|
if self._device is None:
|
|
- raise BlivetAnsibleError("failed to look up or create device '%s'" % self._volume['name'])
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to look up or create device '%s'" % self._volume["name"]
|
|
+ )
|
|
|
|
self._manage_encryption()
|
|
|
|
@@ -511,24 +597,31 @@ class BlivetVolume(BlivetBase):
|
|
if self._device.raw_device.exists:
|
|
self._reformat()
|
|
|
|
- if self.ultimately_present and self._volume['mount_point'] and not self._device.format.mountable:
|
|
- raise BlivetAnsibleError("volume '%s' has a mount point but no mountable file system" % self._volume['name'])
|
|
+ if (
|
|
+ self.ultimately_present
|
|
+ and self._volume["mount_point"]
|
|
+ and not self._device.format.mountable
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "volume '%s' has a mount point but no mountable file system"
|
|
+ % self._volume["name"]
|
|
+ )
|
|
|
|
# schedule resize if appropriate
|
|
- if self._device.raw_device.exists and self._volume['size']:
|
|
+ if self._device.raw_device.exists and self._volume["size"]:
|
|
self._resize()
|
|
|
|
# save device identifiers for use by the role
|
|
- self._volume['_device'] = self._device.path
|
|
- self._volume['_raw_device'] = self._device.raw_device.path
|
|
- self._volume['_mount_id'] = self._device.fstab_spec
|
|
+ self._volume["_device"] = self._device.path
|
|
+ self._volume["_raw_device"] = self._device.raw_device.path
|
|
+ self._volume["_mount_id"] = self._device.fstab_spec
|
|
|
|
|
|
class BlivetDiskVolume(BlivetVolume):
|
|
blivet_device_class = devices.DiskDevice
|
|
|
|
def _get_device_id(self):
|
|
- return self._volume['disks'][0]
|
|
+ return self._volume["disks"][0]
|
|
|
|
def _type_check(self):
|
|
return self._device.raw_device.is_disk
|
|
@@ -536,7 +629,7 @@ class BlivetDiskVolume(BlivetVolume):
|
|
def _get_format(self):
|
|
fmt = super(BlivetDiskVolume, self)._get_format()
|
|
# pass -F to mke2fs on whole disks in RHEL7
|
|
- mkfs_options = diskvolume_mkfs_option_map.get(self._volume['fs_type'])
|
|
+ mkfs_options = diskvolume_mkfs_option_map.get(self._volume["fs_type"])
|
|
if mkfs_options:
|
|
if fmt.create_options:
|
|
fmt.create_options += " "
|
|
@@ -552,23 +645,31 @@ class BlivetDiskVolume(BlivetVolume):
|
|
def _look_up_device(self):
|
|
super(BlivetDiskVolume, self)._look_up_device()
|
|
if not self._get_device_id():
|
|
- raise BlivetAnsibleError("no disks specified for volume '%s'" % self._volume['name'])
|
|
- elif not isinstance(self._volume['disks'], list):
|
|
+ raise BlivetAnsibleError(
|
|
+ "no disks specified for volume '%s'" % self._volume["name"]
|
|
+ )
|
|
+ elif not isinstance(self._volume["disks"], list):
|
|
raise BlivetAnsibleError("volume disks must be specified as a list")
|
|
|
|
if self._device is None:
|
|
- raise BlivetAnsibleError("unable to resolve disk specified for volume '%s' (%s)" % (self._volume['name'], self._volume['disks']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "unable to resolve disk specified for volume '%s' (%s)"
|
|
+ % (self._volume["name"], self._volume["disks"])
|
|
+ )
|
|
|
|
|
|
class BlivetPartitionVolume(BlivetVolume):
|
|
blivet_device_class = devices.PartitionDevice
|
|
|
|
def _type_check(self):
|
|
- return self._device.raw_device.type == 'partition'
|
|
+ return self._device.raw_device.type == "partition"
|
|
|
|
def _get_device_id(self):
|
|
device_id = None
|
|
- if self._blivet_pool._disks[0].partitioned and len(self._blivet_pool._disks[0].children) == 1:
|
|
+ if (
|
|
+ self._blivet_pool._disks[0].partitioned
|
|
+ and len(self._blivet_pool._disks[0].children) == 1
|
|
+ ):
|
|
device_id = self._blivet_pool._disks[0].children[0].name
|
|
|
|
return device_id
|
|
@@ -583,22 +684,29 @@ class BlivetPartitionVolume(BlivetVolume):
|
|
if self._blivet_pool:
|
|
parent = self._blivet_pool._device
|
|
else:
|
|
- parent = self._blivet.devicetree.resolve_device(self._volume['pool'])
|
|
+ parent = self._blivet.devicetree.resolve_device(self._volume["pool"])
|
|
|
|
if parent is None:
|
|
- raise BlivetAnsibleError("failed to find pool '%s' for volume '%s'" % (self._blivet_pool['name'], self._volume['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to find pool '%s' for volume '%s'"
|
|
+ % (self._blivet_pool["name"], self._volume["name"])
|
|
+ )
|
|
|
|
size = Size("256 MiB")
|
|
try:
|
|
- device = self._blivet.new_partition(parents=[parent], size=size, grow=True, fmt=self._get_format())
|
|
+ device = self._blivet.new_partition(
|
|
+ parents=[parent], size=size, grow=True, fmt=self._get_format()
|
|
+ )
|
|
except Exception:
|
|
- raise BlivetAnsibleError("failed set up volume '%s'" % self._volume['name'])
|
|
+ raise BlivetAnsibleError("failed set up volume '%s'" % self._volume["name"])
|
|
|
|
self._blivet.create_device(device)
|
|
try:
|
|
do_partitioning(self._blivet)
|
|
except Exception:
|
|
- raise BlivetAnsibleError("partition allocation failed for volume '%s'" % self._volume['name'])
|
|
+ raise BlivetAnsibleError(
|
|
+ "partition allocation failed for volume '%s'" % self._volume["name"]
|
|
+ )
|
|
|
|
self._device = device
|
|
|
|
@@ -609,7 +717,7 @@ class BlivetLVMVolume(BlivetVolume):
|
|
def _get_device_id(self):
|
|
if not self._blivet_pool._device:
|
|
return None
|
|
- return "%s-%s" % (self._blivet_pool._device.name, self._volume['name'])
|
|
+ return "%s-%s" % (self._blivet_pool._device.name, self._volume["name"])
|
|
|
|
def _create(self):
|
|
if self._device:
|
|
@@ -617,51 +725,75 @@ class BlivetLVMVolume(BlivetVolume):
|
|
|
|
parent = self._blivet_pool._device
|
|
if parent is None:
|
|
- raise BlivetAnsibleError("failed to find pool '%s' for volume '%s'" % (self._blivet_pool['name'], self._volume['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to find pool '%s' for volume '%s'"
|
|
+ % (self._blivet_pool["name"], self._volume["name"])
|
|
+ )
|
|
|
|
try:
|
|
- size = Size(self._volume['size'])
|
|
+ size = Size(self._volume["size"])
|
|
except Exception:
|
|
- raise BlivetAnsibleError("invalid size '%s' specified for volume '%s'" % (self._volume['size'], self._volume['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "invalid size '%s' specified for volume '%s'"
|
|
+ % (self._volume["size"], self._volume["name"])
|
|
+ )
|
|
|
|
fmt = self._get_format()
|
|
- trim_percent = (1.0 - float(parent.free_space / size))*100
|
|
+ trim_percent = (1.0 - float(parent.free_space / size)) * 100
|
|
log.debug("size: %s ; %s", size, trim_percent)
|
|
if size > parent.free_space:
|
|
if trim_percent > MAX_TRIM_PERCENT:
|
|
- raise BlivetAnsibleError("specified size for volume '%s' exceeds available space in pool '%s' (%s)"
|
|
- % (size, parent.name, parent.free_space))
|
|
+ raise BlivetAnsibleError(
|
|
+ "specified size for volume '%s' exceeds available space in pool '%s' (%s)"
|
|
+ % (size, parent.name, parent.free_space)
|
|
+ )
|
|
else:
|
|
- log.info("adjusting %s size from %s to %s to fit in %s free space", self._volume['name'],
|
|
- size,
|
|
- parent.free_space,
|
|
- parent.name)
|
|
+ log.info(
|
|
+ "adjusting %s size from %s to %s to fit in %s free space",
|
|
+ self._volume["name"],
|
|
+ size,
|
|
+ parent.free_space,
|
|
+ parent.name,
|
|
+ )
|
|
size = parent.free_space
|
|
|
|
try:
|
|
- device = self._blivet.new_lv(name=self._volume['name'],
|
|
- parents=[parent], size=size, fmt=fmt)
|
|
+ device = self._blivet.new_lv(
|
|
+ name=self._volume["name"], parents=[parent], size=size, fmt=fmt
|
|
+ )
|
|
except Exception as e:
|
|
- raise BlivetAnsibleError("failed to set up volume '%s': %s" % (self._volume['name'], str(e)))
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to set up volume '%s': %s" % (self._volume["name"], str(e))
|
|
+ )
|
|
|
|
self._blivet.create_device(device)
|
|
self._device = device
|
|
|
|
|
|
class BlivetMDRaidVolume(BlivetVolume):
|
|
-
|
|
- def _process_device_numbers(self, members_count, requested_actives, requested_spares):
|
|
+ def _process_device_numbers(
|
|
+ self, members_count, requested_actives, requested_spares
|
|
+ ):
|
|
|
|
active_count = members_count
|
|
spare_count = 0
|
|
|
|
if requested_actives is not None and requested_spares is not None:
|
|
- if (requested_actives + requested_spares != members_count or
|
|
- requested_actives < 0 or requested_spares < 0):
|
|
- raise BlivetAnsibleError("failed to set up volume '%s': cannot create RAID "
|
|
- "with %s members (%s active and %s spare)"
|
|
- % (self._volume['name'], members_count,
|
|
- requested_actives, requested_spares))
|
|
+ if (
|
|
+ requested_actives + requested_spares != members_count
|
|
+ or requested_actives < 0
|
|
+ or requested_spares < 0
|
|
+ ):
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to set up volume '%s': cannot create RAID "
|
|
+ "with %s members (%s active and %s spare)"
|
|
+ % (
|
|
+ self._volume["name"],
|
|
+ members_count,
|
|
+ requested_actives,
|
|
+ requested_spares,
|
|
+ )
|
|
+ )
|
|
|
|
if requested_actives is not None:
|
|
active_count = requested_actives
|
|
@@ -685,7 +817,9 @@ class BlivetMDRaidVolume(BlivetVolume):
|
|
self._blivet.format_device(member_disk, label)
|
|
|
|
# create new partition
|
|
- member = self._blivet.new_partition(parents=[member_disk], grow=True)
|
|
+ member = self._blivet.new_partition(
|
|
+ parents=[member_disk], grow=True
|
|
+ )
|
|
self._blivet.create_device(member)
|
|
self._blivet.format_device(member, fmt=get_format("mdmember"))
|
|
members.append(member)
|
|
@@ -697,16 +831,16 @@ class BlivetMDRaidVolume(BlivetVolume):
|
|
|
|
def _update_from_device(self, param_name):
|
|
""" Return True if param_name's value was retrieved from a looked-up device. """
|
|
- if param_name == 'raid_level':
|
|
- self._volume['raid_level'] = self._device.level.name
|
|
- elif param_name == 'raid_chunk_size':
|
|
- self._volume['raid_chunk_size'] = str(self._device.chunk_size)
|
|
- elif param_name == 'raid_device_count':
|
|
- self._volume['raid_device_count'] = self._device.member_devices
|
|
- elif param_name == 'raid_spare_count':
|
|
- self._volume['raid_spare_count'] = self._device.spares
|
|
- elif param_name == 'raid_metadata_version':
|
|
- self._volume['raid_metadata_version'] = self._device.metadata_version
|
|
+ if param_name == "raid_level":
|
|
+ self._volume["raid_level"] = self._device.level.name
|
|
+ elif param_name == "raid_chunk_size":
|
|
+ self._volume["raid_chunk_size"] = str(self._device.chunk_size)
|
|
+ elif param_name == "raid_device_count":
|
|
+ self._volume["raid_device_count"] = self._device.member_devices
|
|
+ elif param_name == "raid_spare_count":
|
|
+ self._volume["raid_spare_count"] = self._device.spares
|
|
+ elif param_name == "raid_metadata_version":
|
|
+ self._volume["raid_metadata_version"] = self._device.metadata_version
|
|
else:
|
|
return super(BlivetMDRaidVolume, self)._update_from_device(param_name)
|
|
|
|
@@ -728,7 +862,10 @@ class BlivetMDRaidVolume(BlivetVolume):
|
|
try:
|
|
do_partitioning(self._blivet)
|
|
except Exception as e:
|
|
- raise BlivetAnsibleError("failed to allocate partitions for mdraid '%s': %s" % (self._volume['name'], str(e)))
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to allocate partitions for mdraid '%s': %s"
|
|
+ % (self._volume["name"], str(e))
|
|
+ )
|
|
|
|
raid_array = self._new_mdarray(members)
|
|
|
|
@@ -764,16 +901,20 @@ _BLIVET_VOLUME_TYPES = {
|
|
"disk": BlivetDiskVolume,
|
|
"lvm": BlivetLVMVolume,
|
|
"partition": BlivetPartitionVolume,
|
|
- "raid": BlivetMDRaidVolume
|
|
+ "raid": BlivetMDRaidVolume,
|
|
}
|
|
|
|
|
|
def _get_blivet_volume(blivet_obj, volume, bpool=None):
|
|
""" Return a BlivetVolume instance appropriate for the volume dict. """
|
|
global volume_defaults
|
|
- volume_type = volume.get('type', bpool._pool['type'] if bpool else volume_defaults['type'])
|
|
+ volume_type = volume.get(
|
|
+ "type", bpool._pool["type"] if bpool else volume_defaults["type"]
|
|
+ )
|
|
if volume_type not in _BLIVET_VOLUME_TYPES:
|
|
- raise BlivetAnsibleError("Volume '%s' has unknown type '%s'" % (volume['name'], volume_type))
|
|
+ raise BlivetAnsibleError(
|
|
+ "Volume '%s' has unknown type '%s'" % (volume["name"], volume_type)
|
|
+ )
|
|
|
|
return _BLIVET_VOLUME_TYPES[volume_type](blivet_obj, volume, bpool=bpool)
|
|
|
|
@@ -796,19 +937,19 @@ class BlivetPool(BlivetBase):
|
|
if self.ultimately_present and self.__class__.blivet_device_class is not None:
|
|
packages.extend(self.__class__.blivet_device_class._packages)
|
|
|
|
- if self._pool.get('encryption'):
|
|
- packages.extend(get_format('luks').packages)
|
|
+ if self._pool.get("encryption"):
|
|
+ packages.extend(get_format("luks").packages)
|
|
|
|
return packages
|
|
|
|
@property
|
|
def ultimately_present(self):
|
|
""" Should this pool be present when we are finished? """
|
|
- return self._pool.get('state', 'present') == 'present'
|
|
+ return self._pool.get("state", "present") == "present"
|
|
|
|
@property
|
|
def _is_raid(self):
|
|
- return self._pool.get('raid_level') not in [None, "null", ""]
|
|
+ return self._pool.get("raid_level") not in [None, "null", ""]
|
|
|
|
def _member_management_is_destructive(self):
|
|
return False
|
|
@@ -849,25 +990,30 @@ class BlivetPool(BlivetBase):
|
|
if self._disks:
|
|
return
|
|
|
|
- if not self._device and not self._pool['disks']:
|
|
- raise BlivetAnsibleError("no disks specified for pool '%s'" % self._pool['name'])
|
|
- elif not isinstance(self._pool['disks'], list):
|
|
+ if not self._device and not self._pool["disks"]:
|
|
+ raise BlivetAnsibleError(
|
|
+ "no disks specified for pool '%s'" % self._pool["name"]
|
|
+ )
|
|
+ elif not isinstance(self._pool["disks"], list):
|
|
raise BlivetAnsibleError("pool disks must be specified as a list")
|
|
|
|
disks = list()
|
|
- for spec in self._pool['disks']:
|
|
+ for spec in self._pool["disks"]:
|
|
device = self._blivet.devicetree.resolve_device(spec)
|
|
if device is not None: # XXX fail if any disk isn't resolved?
|
|
disks.append(device)
|
|
|
|
- if self._pool['disks'] and not self._device and not disks:
|
|
- raise BlivetAnsibleError("unable to resolve any disks specified for pool '%s' (%s)" % (self._pool['name'], self._pool['disks']))
|
|
+ if self._pool["disks"] and not self._device and not disks:
|
|
+ raise BlivetAnsibleError(
|
|
+ "unable to resolve any disks specified for pool '%s' (%s)"
|
|
+ % (self._pool["name"], self._pool["disks"])
|
|
+ )
|
|
|
|
self._disks = disks
|
|
|
|
def _look_up_device(self):
|
|
""" Look up the pool in blivet's device tree. """
|
|
- device = self._blivet.devicetree.resolve_device(self._pool['name'])
|
|
+ device = self._blivet.devicetree.resolve_device(self._pool["name"])
|
|
if device is None:
|
|
return
|
|
|
|
@@ -895,45 +1041,62 @@ class BlivetPool(BlivetBase):
|
|
""" Return True if param_name's value was retrieved from a looked-up device. """
|
|
# We wouldn't have the pool device if the member devices weren't unlocked, so we do not
|
|
# have to consider the case where the devices are unlocked like we do for volumes.
|
|
- encrypted = bool(self._device.parents) and all("luks" in d.type for d in self._device.parents)
|
|
- raid = len(self._device.parents) == 1 and hasattr(self._device.parents[0].raw_device, 'level')
|
|
+ encrypted = bool(self._device.parents) and all(
|
|
+ "luks" in d.type for d in self._device.parents
|
|
+ )
|
|
+ raid = len(self._device.parents) == 1 and hasattr(
|
|
+ self._device.parents[0].raw_device, "level"
|
|
+ )
|
|
log.debug("BlivetPool._update_from_device: %s", self._device)
|
|
|
|
- if param_name == 'disks':
|
|
- self._pool['disks'] = [d.name for d in self._device.disks]
|
|
- elif param_name == 'encryption':
|
|
- self._pool['encryption'] = encrypted
|
|
- elif param_name == 'encryption_key_size' and encrypted:
|
|
- self._pool['encryption_key_size'] = self._device.parents[0].parents[0].format.key_size
|
|
- elif param_name == 'encryption_key_file' and encrypted:
|
|
- self._pool['encryption_key_file'] = self._device.parents[0].parents[0].format.key_file
|
|
- elif param_name == 'encryption_cipher' and encrypted:
|
|
- self._pool['encryption_cipher'] = self._device.parents[0].parents[0].format.cipher
|
|
- elif param_name == 'encryption_luks_version' and encrypted:
|
|
- self._pool['encryption_luks_version'] = self._device.parents[0].parents[0].format.luks_version
|
|
- elif param_name == 'raid_level' and raid:
|
|
- self._pool['raid_level'] = self._device.parents[0].raw_device.level.name
|
|
- elif param_name == 'raid_chunk_size' and raid:
|
|
- self._pool['raid_chunk_size'] = str(self._device.parents[0].raw_device.chunk_size)
|
|
- elif param_name == 'raid_device_count' and raid:
|
|
- self._pool['raid_device_count'] = self._device.parents[0].raw_device.member_devices
|
|
- elif param_name == 'raid_spare_count' and raid:
|
|
- self._pool['raid_spare_count'] = self._device.parents[0].raw_device.spares
|
|
- elif param_name == 'raid_metadata_version' and raid:
|
|
- self._pool['raid_metadata_version'] = self._device.parents[0].raw_device.metadata_version
|
|
+ if param_name == "disks":
|
|
+ self._pool["disks"] = [d.name for d in self._device.disks]
|
|
+ elif param_name == "encryption":
|
|
+ self._pool["encryption"] = encrypted
|
|
+ elif param_name == "encryption_key_size" and encrypted:
|
|
+ self._pool["encryption_key_size"] = (
|
|
+ self._device.parents[0].parents[0].format.key_size
|
|
+ )
|
|
+ elif param_name == "encryption_key_file" and encrypted:
|
|
+ self._pool["encryption_key_file"] = (
|
|
+ self._device.parents[0].parents[0].format.key_file
|
|
+ )
|
|
+ elif param_name == "encryption_cipher" and encrypted:
|
|
+ self._pool["encryption_cipher"] = (
|
|
+ self._device.parents[0].parents[0].format.cipher
|
|
+ )
|
|
+ elif param_name == "encryption_luks_version" and encrypted:
|
|
+ self._pool["encryption_luks_version"] = (
|
|
+ self._device.parents[0].parents[0].format.luks_version
|
|
+ )
|
|
+ elif param_name == "raid_level" and raid:
|
|
+ self._pool["raid_level"] = self._device.parents[0].raw_device.level.name
|
|
+ elif param_name == "raid_chunk_size" and raid:
|
|
+ self._pool["raid_chunk_size"] = str(
|
|
+ self._device.parents[0].raw_device.chunk_size
|
|
+ )
|
|
+ elif param_name == "raid_device_count" and raid:
|
|
+ self._pool["raid_device_count"] = self._device.parents[
|
|
+ 0
|
|
+ ].raw_device.member_devices
|
|
+ elif param_name == "raid_spare_count" and raid:
|
|
+ self._pool["raid_spare_count"] = self._device.parents[0].raw_device.spares
|
|
+ elif param_name == "raid_metadata_version" and raid:
|
|
+ self._pool["raid_metadata_version"] = self._device.parents[
|
|
+ 0
|
|
+ ].raw_device.metadata_version
|
|
else:
|
|
return False
|
|
|
|
return True
|
|
|
|
-
|
|
def _apply_defaults(self):
|
|
global pool_defaults
|
|
for name, default in pool_defaults.items():
|
|
if name in self._pool:
|
|
continue
|
|
|
|
- default = None if default in ('none', 'None', 'null') else default
|
|
+ default = None if default in ("none", "None", "null") else default
|
|
|
|
if self._device:
|
|
if not self._update_from_device(name):
|
|
@@ -948,14 +1111,19 @@ class BlivetPool(BlivetBase):
|
|
for disk in self._disks:
|
|
if not disk.isleaf or disk.format.type is not None:
|
|
if safe_mode:
|
|
- raise BlivetAnsibleError("cannot remove existing formatting and/or devices on disk '%s' (pool '%s') in safe mode" % (disk.name, self._pool['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove existing formatting and/or devices on disk '%s' (pool '%s') in safe mode"
|
|
+ % (disk.name, self._pool["name"])
|
|
+ )
|
|
else:
|
|
self._blivet.devicetree.recursive_remove(disk)
|
|
|
|
if use_partitions:
|
|
label = get_format("disklabel", device=disk.path)
|
|
self._blivet.format_device(disk, label)
|
|
- member = self._blivet.new_partition(parents=[disk], size=Size("256MiB"), grow=True)
|
|
+ member = self._blivet.new_partition(
|
|
+ parents=[disk], size=Size("256MiB"), grow=True
|
|
+ )
|
|
self._blivet.create_device(member)
|
|
else:
|
|
member = disk
|
|
@@ -966,9 +1134,8 @@ class BlivetPool(BlivetBase):
|
|
self._blivet.format_device(member, self._get_format())
|
|
members.append(member)
|
|
|
|
-
|
|
if self._is_raid:
|
|
- raid_name = "%s-1" % self._pool['name']
|
|
+ raid_name = "%s-1" % self._pool["name"]
|
|
|
|
raid_array = self._new_mdarray(members, raid_name=raid_name)
|
|
|
|
@@ -981,14 +1148,15 @@ class BlivetPool(BlivetBase):
|
|
try:
|
|
do_partitioning(self._blivet)
|
|
except Exception:
|
|
- raise BlivetAnsibleError("failed to allocate partitions for pool '%s'" % self._pool['name'])
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to allocate partitions for pool '%s'" % self._pool["name"]
|
|
+ )
|
|
|
|
return result
|
|
|
|
-
|
|
def _get_volumes(self):
|
|
""" Set up BlivetVolume instances for this pool's volumes. """
|
|
- for volume in self._pool.get('volumes', []):
|
|
+ for volume in self._pool.get("volumes", []):
|
|
bvolume = _get_blivet_volume(self._blivet, volume, self)
|
|
self._blivet_volumes.append(bvolume)
|
|
|
|
@@ -1013,7 +1181,10 @@ class BlivetPool(BlivetBase):
|
|
return
|
|
elif self._member_management_is_destructive():
|
|
if safe_mode:
|
|
- raise BlivetAnsibleError("cannot remove and recreate existing pool '%s' in safe mode" % self._pool['name'])
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove and recreate existing pool '%s' in safe mode"
|
|
+ % self._pool["name"]
|
|
+ )
|
|
else:
|
|
self._destroy()
|
|
|
|
@@ -1031,15 +1202,22 @@ class BlivetPartitionPool(BlivetPool):
|
|
self._device = self._disks[0]
|
|
|
|
def _create(self):
|
|
- if self._device.format.type != "disklabel" or \
|
|
- (disklabel_type and self._device.format.label_type != disklabel_type):
|
|
+ if self._device.format.type != "disklabel" or (
|
|
+ disklabel_type and self._device.format.label_type != disklabel_type
|
|
+ ):
|
|
if safe_mode:
|
|
- raise BlivetAnsibleError("cannot remove existing formatting and/or devices on disk '%s' "
|
|
- "(pool '%s') in safe mode" % (self._device.name, self._pool['name']))
|
|
+ raise BlivetAnsibleError(
|
|
+ "cannot remove existing formatting and/or devices on disk '%s' "
|
|
+ "(pool '%s') in safe mode" % (self._device.name, self._pool["name"])
|
|
+ )
|
|
else:
|
|
- self._blivet.devicetree.recursive_remove(self._device, remove_device=False)
|
|
+ self._blivet.devicetree.recursive_remove(
|
|
+ self._device, remove_device=False
|
|
+ )
|
|
|
|
- label = get_format("disklabel", device=self._device.path, label_type=disklabel_type)
|
|
+ label = get_format(
|
|
+ "disklabel", device=self._device.path, label_type=disklabel_type
|
|
+ )
|
|
self._blivet.format_device(self._device, label)
|
|
|
|
|
|
@@ -1053,9 +1231,13 @@ class BlivetLVMPool(BlivetPool):
|
|
if self._device is None:
|
|
return False
|
|
|
|
- if self._pool['encryption'] and not all(m.encrypted for m in self._device.parents):
|
|
+ if self._pool["encryption"] and not all(
|
|
+ m.encrypted for m in self._device.parents
|
|
+ ):
|
|
return True
|
|
- elif not self._pool['encryption'] and any(m.encrypted for m in self._device.parents):
|
|
+ elif not self._pool["encryption"] and any(
|
|
+ m.encrypted for m in self._device.parents
|
|
+ ):
|
|
return True
|
|
|
|
return False
|
|
@@ -1080,49 +1262,50 @@ class BlivetLVMPool(BlivetPool):
|
|
|
|
members = self._manage_encryption(self._create_members())
|
|
try:
|
|
- pool_device = self._blivet.new_vg(name=self._pool['name'], parents=members)
|
|
+ pool_device = self._blivet.new_vg(name=self._pool["name"], parents=members)
|
|
except Exception as e:
|
|
- raise BlivetAnsibleError("failed to set up pool '%s': %s" % (self._pool['name'], str(e)))
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to set up pool '%s': %s" % (self._pool["name"], str(e))
|
|
+ )
|
|
|
|
self._blivet.create_device(pool_device)
|
|
self._device = pool_device
|
|
|
|
|
|
-_BLIVET_POOL_TYPES = {
|
|
- "partition": BlivetPartitionPool,
|
|
- "lvm": BlivetLVMPool
|
|
-}
|
|
+_BLIVET_POOL_TYPES = {"partition": BlivetPartitionPool, "lvm": BlivetLVMPool}
|
|
|
|
|
|
def _get_blivet_pool(blivet_obj, pool):
|
|
""" Return an appropriate BlivetPool instance for the pool dict. """
|
|
- if 'type' not in pool:
|
|
+ if "type" not in pool:
|
|
global pool_defaults
|
|
- pool['type'] = pool_defaults['type']
|
|
+ pool["type"] = pool_defaults["type"]
|
|
|
|
- if pool['type'] not in _BLIVET_POOL_TYPES:
|
|
- raise BlivetAnsibleError("Pool '%s' has unknown type '%s'" % (pool['name'], pool['type']))
|
|
+ if pool["type"] not in _BLIVET_POOL_TYPES:
|
|
+ raise BlivetAnsibleError(
|
|
+ "Pool '%s' has unknown type '%s'" % (pool["name"], pool["type"])
|
|
+ )
|
|
|
|
- return _BLIVET_POOL_TYPES[pool['type']](blivet_obj, pool)
|
|
+ return _BLIVET_POOL_TYPES[pool["type"]](blivet_obj, pool)
|
|
|
|
|
|
def manage_volume(b, volume):
|
|
""" Schedule actions as needed to manage a single standalone volume. """
|
|
bvolume = _get_blivet_volume(b, volume)
|
|
bvolume.manage()
|
|
- volume['_device'] = bvolume._volume.get('_device', '')
|
|
- volume['_raw_device'] = bvolume._volume.get('_raw_device', '')
|
|
- volume['_mount_id'] = bvolume._volume.get('_mount_id', '')
|
|
+ volume["_device"] = bvolume._volume.get("_device", "")
|
|
+ volume["_raw_device"] = bvolume._volume.get("_raw_device", "")
|
|
+ volume["_mount_id"] = bvolume._volume.get("_mount_id", "")
|
|
|
|
|
|
def manage_pool(b, pool):
|
|
""" Schedule actions as needed to manage a single pool and its volumes. """
|
|
bpool = _get_blivet_pool(b, pool)
|
|
bpool.manage()
|
|
- for (volume, bvolume) in zip(pool['volumes'], bpool._blivet_volumes):
|
|
- volume['_device'] = bvolume._volume.get('_device', '')
|
|
- volume['_raw_device'] = bvolume._volume.get('_raw_device', '')
|
|
- volume['_mount_id'] = bvolume._volume.get('_mount_id', '')
|
|
+ for (volume, bvolume) in zip(pool["volumes"], bpool._blivet_volumes):
|
|
+ volume["_device"] = bvolume._volume.get("_device", "")
|
|
+ volume["_raw_device"] = bvolume._volume.get("_raw_device", "")
|
|
+ volume["_mount_id"] = bvolume._volume.get("_mount_id", "")
|
|
|
|
|
|
class FSTab(object):
|
|
@@ -1141,7 +1324,7 @@ class FSTab(object):
|
|
if self._entries:
|
|
self.reset()
|
|
|
|
- for line in open('/etc/fstab').readlines():
|
|
+ for line in open("/etc/fstab").readlines():
|
|
if line.lstrip().startswith("#"):
|
|
continue
|
|
|
|
@@ -1150,23 +1333,27 @@ class FSTab(object):
|
|
continue
|
|
|
|
device = self._blivet.devicetree.resolve_device(fields[0])
|
|
- self._entries.append(dict(device_id=fields[0],
|
|
- device_path=getattr(device, 'path', None),
|
|
- fs_type=fields[2],
|
|
- mount_point=fields[1],
|
|
- mount_options=fields[3]))
|
|
+ self._entries.append(
|
|
+ dict(
|
|
+ device_id=fields[0],
|
|
+ device_path=getattr(device, "path", None),
|
|
+ fs_type=fields[2],
|
|
+ mount_point=fields[1],
|
|
+ mount_options=fields[3],
|
|
+ )
|
|
+ )
|
|
|
|
|
|
def get_mount_info(pools, volumes, actions, fstab):
|
|
- """ Return a list of argument dicts to pass to the mount module to manage mounts.
|
|
+ """Return a list of argument dicts to pass to the mount module to manage mounts.
|
|
|
|
- The overall approach is to remove existing mounts associated with file systems
|
|
- we are removing and those with changed mount points, re-adding them with the
|
|
- new mount point later.
|
|
+ The overall approach is to remove existing mounts associated with file systems
|
|
+ we are removing and those with changed mount points, re-adding them with the
|
|
+ new mount point later.
|
|
|
|
- Removed mounts go directly into the mount_info list, which is the return value,
|
|
- while added/active mounts to a list that gets appended to the mount_info list
|
|
- at the end to ensure that removals happen first.
|
|
+ Removed mounts go directly into the mount_info list, which is the return value,
|
|
+ while added/active mounts to a list that gets appended to the mount_info list
|
|
+ at the end to ensure that removals happen first.
|
|
"""
|
|
mount_info = list()
|
|
mount_vols = list()
|
|
@@ -1174,33 +1361,50 @@ def get_mount_info(pools, volumes, actions, fstab):
|
|
# account for mounts removed by removing or reformatting volumes
|
|
if actions:
|
|
for action in actions:
|
|
- if action.is_destroy and action.is_format and action.format.type is not None:
|
|
- mount = fstab.lookup('device_path', action.device.path)
|
|
+ if (
|
|
+ action.is_destroy
|
|
+ and action.is_format
|
|
+ and action.format.type is not None
|
|
+ ):
|
|
+ mount = fstab.lookup("device_path", action.device.path)
|
|
if mount is not None:
|
|
- mount_info.append({"src": mount['device_id'], "path": mount['mount_point'],
|
|
- 'state': 'absent', 'fstype': mount['fs_type']})
|
|
+ mount_info.append(
|
|
+ {
|
|
+ "src": mount["device_id"],
|
|
+ "path": mount["mount_point"],
|
|
+ "state": "absent",
|
|
+ "fstype": mount["fs_type"],
|
|
+ }
|
|
+ )
|
|
|
|
def handle_new_mount(volume, fstab):
|
|
replace = None
|
|
mounted = False
|
|
|
|
- mount = fstab.lookup('device_path', volume['_device'])
|
|
- if (volume['mount_point'] and volume['mount_point'].startswith('/')) \
|
|
- or volume['fs_type'] == 'swap':
|
|
+ mount = fstab.lookup("device_path", volume["_device"])
|
|
+ if (volume["mount_point"] and volume["mount_point"].startswith("/")) or volume[
|
|
+ "fs_type"
|
|
+ ] == "swap":
|
|
mounted = True
|
|
|
|
# handle removal of existing mounts of this volume
|
|
- if mount and mount['fs_type'] != 'swap' and mount['mount_point'] != volume['mount_point']:
|
|
- replace = dict(path=mount['mount_point'], state="absent")
|
|
- elif mount and mount['fs_type'] == 'swap':
|
|
- replace = dict(src=mount['device_id'], fstype="swap", path="none", state="absent")
|
|
+ if (
|
|
+ mount
|
|
+ and mount["fs_type"] != "swap"
|
|
+ and mount["mount_point"] != volume["mount_point"]
|
|
+ ):
|
|
+ replace = dict(path=mount["mount_point"], state="absent")
|
|
+ elif mount and mount["fs_type"] == "swap":
|
|
+ replace = dict(
|
|
+ src=mount["device_id"], fstype="swap", path="none", state="absent"
|
|
+ )
|
|
|
|
return mounted, replace
|
|
|
|
# account for mounts that we set up or are replacing in pools
|
|
for pool in pools:
|
|
- for volume in pool['volumes']:
|
|
- if pool['state'] == 'present' and volume['state'] == 'present':
|
|
+ for volume in pool["volumes"]:
|
|
+ if pool["state"] == "present" and volume["state"] == "present":
|
|
mounted, replace = handle_new_mount(volume, fstab)
|
|
if replace:
|
|
mount_info.append(replace)
|
|
@@ -1209,7 +1413,7 @@ def get_mount_info(pools, volumes, actions, fstab):
|
|
|
|
# account for mounts that we set up or are replacing in standalone volumes
|
|
for volume in volumes:
|
|
- if volume['state'] == 'present':
|
|
+ if volume["state"] == "present":
|
|
mounted, replace = handle_new_mount(volume, fstab)
|
|
if replace:
|
|
mount_info.append(replace)
|
|
@@ -1217,13 +1421,19 @@ def get_mount_info(pools, volumes, actions, fstab):
|
|
mount_vols.append(volume)
|
|
|
|
for volume in mount_vols:
|
|
- mount_info.append({'src': volume['_mount_id'],
|
|
- 'path': volume['mount_point'] if volume['fs_type'] != "swap" else "none",
|
|
- 'fstype': volume['fs_type'],
|
|
- 'opts': volume['mount_options'],
|
|
- 'dump': volume['mount_check'],
|
|
- 'passno': volume['mount_passno'],
|
|
- 'state': 'mounted' if volume['fs_type'] != "swap" else "present"})
|
|
+ mount_info.append(
|
|
+ {
|
|
+ "src": volume["_mount_id"],
|
|
+ "path": volume["mount_point"]
|
|
+ if volume["fs_type"] != "swap"
|
|
+ else "none",
|
|
+ "fstype": volume["fs_type"],
|
|
+ "opts": volume["mount_options"],
|
|
+ "dump": volume["mount_check"],
|
|
+ "passno": volume["mount_passno"],
|
|
+ "state": "mounted" if volume["fs_type"] != "swap" else "present",
|
|
+ }
|
|
+ )
|
|
|
|
return mount_info
|
|
|
|
@@ -1231,15 +1441,19 @@ def get_mount_info(pools, volumes, actions, fstab):
|
|
def get_crypt_info(actions):
|
|
info = list()
|
|
for action in actions:
|
|
- if not (action.is_format and action.format.type == 'luks'):
|
|
+ if not (action.is_format and action.format.type == "luks"):
|
|
continue
|
|
|
|
- info.append(dict(backing_device=action.device.path,
|
|
- name=action.format.map_name,
|
|
- password=action.format.key_file or '-',
|
|
- state='present' if action.is_create else 'absent'))
|
|
+ info.append(
|
|
+ dict(
|
|
+ backing_device=action.device.path,
|
|
+ name=action.format.map_name,
|
|
+ password=action.format.key_file or "-",
|
|
+ state="present" if action.is_create else "absent",
|
|
+ )
|
|
+ )
|
|
|
|
- return sorted(info, key=lambda e: e['state'])
|
|
+ return sorted(info, key=lambda e: e["state"])
|
|
|
|
|
|
def get_required_packages(b, pools, volumes):
|
|
@@ -1259,66 +1473,70 @@ def get_required_packages(b, pools, volumes):
|
|
|
|
|
|
def update_fstab_identifiers(b, pools, volumes):
|
|
- """ Update fstab device identifiers.
|
|
+ """Update fstab device identifiers.
|
|
|
|
- This is to pick up new UUIDs for newly-formatted devices.
|
|
+ This is to pick up new UUIDs for newly-formatted devices.
|
|
"""
|
|
all_volumes = volumes[:]
|
|
for pool in pools:
|
|
- if not pool['state'] == 'present':
|
|
+ if not pool["state"] == "present":
|
|
continue
|
|
|
|
- all_volumes += pool['volumes']
|
|
+ all_volumes += pool["volumes"]
|
|
|
|
for volume in all_volumes:
|
|
- if volume['state'] == 'present':
|
|
- device = b.devicetree.resolve_device(volume['_mount_id'])
|
|
- if device is None and volume['encryption']:
|
|
- device = b.devicetree.resolve_device(volume['_raw_device'])
|
|
+ if volume["state"] == "present":
|
|
+ device = b.devicetree.resolve_device(volume["_mount_id"])
|
|
+ if device is None and volume["encryption"]:
|
|
+ device = b.devicetree.resolve_device(volume["_raw_device"])
|
|
if device is not None and not device.isleaf:
|
|
device = device.children[0]
|
|
- volume['_device'] = device.path
|
|
+ volume["_device"] = device.path
|
|
|
|
if device is None:
|
|
- raise BlivetAnsibleError("failed to look up device for volume %s (%s/%s)" % (volume['name'], volume['_device'], volume['_mount_id']))
|
|
- volume['_mount_id'] = device.fstab_spec
|
|
- if device.format.type == 'swap':
|
|
+ raise BlivetAnsibleError(
|
|
+ "failed to look up device for volume %s (%s/%s)"
|
|
+ % (volume["name"], volume["_device"], volume["_mount_id"])
|
|
+ )
|
|
+ volume["_mount_id"] = device.fstab_spec
|
|
+ if device.format.type == "swap":
|
|
device.format.setup()
|
|
|
|
if device.status:
|
|
- volume['_kernel_device'] = os.path.realpath(device.path)
|
|
+ volume["_kernel_device"] = os.path.realpath(device.path)
|
|
if device.raw_device.status:
|
|
- volume['_raw_kernel_device'] = os.path.realpath(device.raw_device.path)
|
|
+ volume["_raw_kernel_device"] = os.path.realpath(device.raw_device.path)
|
|
|
|
|
|
def activate_swaps(b, pools, volumes):
|
|
""" Activate all swaps specified as present. """
|
|
all_volumes = volumes[:]
|
|
for pool in pools:
|
|
- if not pool['state'] == 'present':
|
|
+ if not pool["state"] == "present":
|
|
continue
|
|
|
|
- all_volumes += pool['volumes']
|
|
+ all_volumes += pool["volumes"]
|
|
|
|
for volume in all_volumes:
|
|
- if volume['state'] == 'present':
|
|
- device = b.devicetree.resolve_device(volume['_mount_id'])
|
|
- if device.format.type == 'swap':
|
|
+ if volume["state"] == "present":
|
|
+ device = b.devicetree.resolve_device(volume["_mount_id"])
|
|
+ if device.format.type == "swap":
|
|
device.format.setup()
|
|
|
|
|
|
def run_module():
|
|
# available arguments/parameters that a user can pass
|
|
module_args = dict(
|
|
- pools=dict(type='list'),
|
|
- volumes=dict(type='list'),
|
|
- packages_only=dict(type='bool', required=False, default=False),
|
|
- disklabel_type=dict(type='str', required=False, default=None),
|
|
- safe_mode=dict(type='bool', required=False, default=True),
|
|
- pool_defaults=dict(type='dict', required=False),
|
|
- volume_defaults=dict(type='dict', required=False),
|
|
- use_partitions=dict(type='bool', required=False, default=True),
|
|
- diskvolume_mkfs_option_map=dict(type='dict', required=False, default={}))
|
|
+ pools=dict(type="list"),
|
|
+ volumes=dict(type="list"),
|
|
+ packages_only=dict(type="bool", required=False, default=False),
|
|
+ disklabel_type=dict(type="str", required=False, default=None),
|
|
+ safe_mode=dict(type="bool", required=False, default=True),
|
|
+ pool_defaults=dict(type="dict", required=False),
|
|
+ volume_defaults=dict(type="dict", required=False),
|
|
+ use_partitions=dict(type="bool", required=False, default=True),
|
|
+ diskvolume_mkfs_option_map=dict(type="dict", required=False, default={}),
|
|
+ )
|
|
|
|
# seed the result dict in the object
|
|
result = dict(
|
|
@@ -1332,47 +1550,52 @@ def run_module():
|
|
packages=list(),
|
|
)
|
|
|
|
- module = AnsibleModule(argument_spec=module_args,
|
|
- supports_check_mode=True)
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
if not BLIVET_PACKAGE:
|
|
- module.fail_json(msg="Failed to import the blivet or blivet3 Python modules",
|
|
- exception=inspect.cleandoc("""
|
|
+ module.fail_json(
|
|
+ msg="Failed to import the blivet or blivet3 Python modules",
|
|
+ exception=inspect.cleandoc(
|
|
+ """
|
|
blivet3 exception:
|
|
{}
|
|
blivet exception:
|
|
- {}""").format(LIB_IMP_ERR3, LIB_IMP_ERR))
|
|
+ {}"""
|
|
+ ).format(LIB_IMP_ERR3, LIB_IMP_ERR),
|
|
+ )
|
|
|
|
- if not module.params['pools'] and not module.params['volumes']:
|
|
+ if not module.params["pools"] and not module.params["volumes"]:
|
|
module.exit_json(**result)
|
|
|
|
global disklabel_type
|
|
- disklabel_type = module.params['disklabel_type']
|
|
+ disklabel_type = module.params["disklabel_type"]
|
|
|
|
global use_partitions
|
|
- use_partitions = module.params['use_partitions']
|
|
+ use_partitions = module.params["use_partitions"]
|
|
|
|
global safe_mode
|
|
- safe_mode = module.params['safe_mode']
|
|
+ safe_mode = module.params["safe_mode"]
|
|
|
|
global diskvolume_mkfs_option_map
|
|
- diskvolume_mkfs_option_map = module.params['diskvolume_mkfs_option_map']
|
|
+ diskvolume_mkfs_option_map = module.params["diskvolume_mkfs_option_map"]
|
|
|
|
global pool_defaults
|
|
- if 'pool_defaults' in module.params:
|
|
- pool_defaults = module.params['pool_defaults']
|
|
+ if "pool_defaults" in module.params:
|
|
+ pool_defaults = module.params["pool_defaults"]
|
|
|
|
global volume_defaults
|
|
- if 'volume_defaults' in module.params:
|
|
- volume_defaults = module.params['volume_defaults']
|
|
+ if "volume_defaults" in module.params:
|
|
+ volume_defaults = module.params["volume_defaults"]
|
|
|
|
b = Blivet()
|
|
b.reset()
|
|
fstab = FSTab(b)
|
|
actions = list()
|
|
|
|
- if module.params['packages_only']:
|
|
+ if module.params["packages_only"]:
|
|
try:
|
|
- result['packages'] = get_required_packages(b, module.params['pools'], module.params['volumes'])
|
|
+ result["packages"] = get_required_packages(
|
|
+ b, module.params["pools"], module.params["volumes"]
|
|
+ )
|
|
except BlivetAnsibleError as e:
|
|
module.fail_json(msg=str(e), **result)
|
|
module.exit_json(**result)
|
|
@@ -1388,44 +1611,56 @@ def run_module():
|
|
sys_path = action.device.path
|
|
if os.path.islink(sys_path):
|
|
sys_path = os.readlink(action.device.path)
|
|
- trigger(action='change', subsystem='block', name=os.path.basename(sys_path))
|
|
+ trigger(action="change", subsystem="block", name=os.path.basename(sys_path))
|
|
|
|
def action_dict(action):
|
|
- return dict(action=action.type_desc_str,
|
|
- fs_type=action.format.type if action.is_format else None,
|
|
- device=action.device.path)
|
|
+ return dict(
|
|
+ action=action.type_desc_str,
|
|
+ fs_type=action.format.type if action.is_format else None,
|
|
+ device=action.device.path,
|
|
+ )
|
|
|
|
- duplicates = find_duplicate_names(module.params['pools'])
|
|
+ duplicates = find_duplicate_names(module.params["pools"])
|
|
if duplicates:
|
|
- module.fail_json(msg="multiple pools with the same name: {0}".format(",".join(duplicates)),
|
|
- **result)
|
|
- for pool in module.params['pools']:
|
|
- duplicates = find_duplicate_names(pool.get('volumes', list()))
|
|
+ module.fail_json(
|
|
+ msg="multiple pools with the same name: {0}".format(",".join(duplicates)),
|
|
+ **result
|
|
+ )
|
|
+ for pool in module.params["pools"]:
|
|
+ duplicates = find_duplicate_names(pool.get("volumes", list()))
|
|
if duplicates:
|
|
- module.fail_json(msg="multiple volumes in pool '{0}' with the "
|
|
- "same name: {1}".format(pool['name'], ",".join(duplicates)),
|
|
- **result)
|
|
+ module.fail_json(
|
|
+ msg="multiple volumes in pool '{0}' with the "
|
|
+ "same name: {1}".format(pool["name"], ",".join(duplicates)),
|
|
+ **result
|
|
+ )
|
|
try:
|
|
manage_pool(b, pool)
|
|
except BlivetAnsibleError as e:
|
|
module.fail_json(msg=str(e), **result)
|
|
|
|
- duplicates = find_duplicate_names(module.params['volumes'])
|
|
+ duplicates = find_duplicate_names(module.params["volumes"])
|
|
if duplicates:
|
|
- module.fail_json(msg="multiple volumes with the same name: {0}".format(",".join(duplicates)),
|
|
- **result)
|
|
- for volume in module.params['volumes']:
|
|
+ module.fail_json(
|
|
+ msg="multiple volumes with the same name: {0}".format(",".join(duplicates)),
|
|
+ **result
|
|
+ )
|
|
+ for volume in module.params["volumes"]:
|
|
try:
|
|
manage_volume(b, volume)
|
|
except BlivetAnsibleError as e:
|
|
module.fail_json(msg=str(e), **result)
|
|
|
|
scheduled = b.devicetree.actions.find()
|
|
- result['packages'] = b.packages[:]
|
|
+ result["packages"] = b.packages[:]
|
|
|
|
for action in scheduled:
|
|
- if (action.is_destroy or action.is_resize) and action.is_format and action.format.exists and \
|
|
- (action.format.mountable or action.format.type == "swap"):
|
|
+ if (
|
|
+ (action.is_destroy or action.is_resize)
|
|
+ and action.is_format
|
|
+ and action.format.exists
|
|
+ and (action.format.mountable or action.format.type == "swap")
|
|
+ ):
|
|
action.format.teardown()
|
|
|
|
if scheduled:
|
|
@@ -1433,21 +1668,27 @@ def run_module():
|
|
callbacks.action_executed.add(record_action)
|
|
callbacks.action_executed.add(ensure_udev_update)
|
|
try:
|
|
- b.devicetree.actions.process(devices=b.devicetree.devices, dry_run=module.check_mode)
|
|
+ b.devicetree.actions.process(
|
|
+ devices=b.devicetree.devices, dry_run=module.check_mode
|
|
+ )
|
|
except Exception as e:
|
|
- module.fail_json(msg="Failed to commit changes to disk: %s" % str(e), **result)
|
|
+ module.fail_json(
|
|
+ msg="Failed to commit changes to disk: %s" % str(e), **result
|
|
+ )
|
|
finally:
|
|
- result['changed'] = True
|
|
- result['actions'] = [action_dict(a) for a in actions]
|
|
+ result["changed"] = True
|
|
+ result["actions"] = [action_dict(a) for a in actions]
|
|
|
|
- update_fstab_identifiers(b, module.params['pools'], module.params['volumes'])
|
|
- activate_swaps(b, module.params['pools'], module.params['volumes'])
|
|
+ update_fstab_identifiers(b, module.params["pools"], module.params["volumes"])
|
|
+ activate_swaps(b, module.params["pools"], module.params["volumes"])
|
|
|
|
- result['mounts'] = get_mount_info(module.params['pools'], module.params['volumes'], actions, fstab)
|
|
- result['crypts'] = get_crypt_info(actions)
|
|
- result['leaves'] = [d.path for d in b.devicetree.leaves]
|
|
- result['pools'] = module.params['pools']
|
|
- result['volumes'] = module.params['volumes']
|
|
+ result["mounts"] = get_mount_info(
|
|
+ module.params["pools"], module.params["volumes"], actions, fstab
|
|
+ )
|
|
+ result["crypts"] = get_crypt_info(actions)
|
|
+ result["leaves"] = [d.path for d in b.devicetree.leaves]
|
|
+ result["pools"] = module.params["pools"]
|
|
+ result["volumes"] = module.params["volumes"]
|
|
|
|
# success - return result
|
|
module.exit_json(**result)
|
|
@@ -1456,5 +1697,6 @@ def run_module():
|
|
def main():
|
|
run_module()
|
|
|
|
-if __name__ == '__main__':
|
|
+
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/library/blockdev_info.py b/library/blockdev_info.py
|
|
index 52ddd78..ca1577f 100644
|
|
--- a/library/blockdev_info.py
|
|
+++ b/library/blockdev_info.py
|
|
@@ -1,35 +1,41 @@
|
|
#!/usr/bin/python
|
|
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
ANSIBLE_METADATA = {
|
|
- 'metadata_version': '1.1',
|
|
- 'status': ['preview'],
|
|
- 'supported_by': 'community'
|
|
+ "metadata_version": "1.1",
|
|
+ "status": ["preview"],
|
|
+ "supported_by": "community",
|
|
}
|
|
|
|
-DOCUMENTATION = '''
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: blockdev_info
|
|
short_description: Collect info about block devices in the system.
|
|
version_added: "2.5"
|
|
description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
- "This module collects information about block devices"
|
|
-options:
|
|
+options: {}
|
|
author:
|
|
- - David Lehman (dlehman@redhat.com)
|
|
-'''
|
|
+ - David Lehman (@dwlehman)
|
|
+"""
|
|
|
|
-EXAMPLES = '''
|
|
+EXAMPLES = """
|
|
- name: Get info about block devices
|
|
blockdev_info:
|
|
register: blk_info
|
|
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
info:
|
|
description: dict w/ device path keys and device info dict values
|
|
+ returned: success
|
|
type: dict
|
|
-'''
|
|
+"""
|
|
|
|
import os
|
|
import shlex
|
|
@@ -38,7 +44,7 @@ from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
|
LSBLK_DEVICE_TYPES = {"part": "partition"}
|
|
-DEV_MD_DIR = '/dev/md'
|
|
+DEV_MD_DIR = "/dev/md"
|
|
|
|
|
|
def fixup_md_path(path):
|
|
@@ -59,7 +65,9 @@ def fixup_md_path(path):
|
|
|
|
|
|
def get_block_info(run_cmd):
|
|
- buf = run_cmd(["lsblk", "-o", "NAME,FSTYPE,LABEL,UUID,TYPE,SIZE", "-p", "-P", "-a"])[1]
|
|
+ buf = run_cmd(
|
|
+ ["lsblk", "-o", "NAME,FSTYPE,LABEL,UUID,TYPE,SIZE", "-p", "-P", "-a"]
|
|
+ )[1]
|
|
info = dict()
|
|
for line in buf.splitlines():
|
|
dev = dict()
|
|
@@ -75,7 +83,7 @@ def get_block_info(run_cmd):
|
|
|
|
dev[key.lower()] = LSBLK_DEVICE_TYPES.get(value, value)
|
|
if dev:
|
|
- info[dev['name']] = dev
|
|
+ info[dev["name"]] = dev
|
|
|
|
return info
|
|
|
|
@@ -87,13 +95,10 @@ def run_module():
|
|
info=None,
|
|
)
|
|
|
|
- module = AnsibleModule(
|
|
- argument_spec=module_args,
|
|
- supports_check_mode=True
|
|
- )
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
|
|
try:
|
|
- result['info'] = get_block_info(module.run_command)
|
|
+ result["info"] = get_block_info(module.run_command)
|
|
except Exception:
|
|
module.fail_json(msg="Failed to collect block device info.")
|
|
|
|
@@ -104,5 +109,5 @@ def main():
|
|
run_module()
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/library/bsize.py b/library/bsize.py
|
|
index 40442f5..524b0f9 100644
|
|
--- a/library/bsize.py
|
|
+++ b/library/bsize.py
|
|
@@ -1,12 +1,16 @@
|
|
#!/usr/bin/python
|
|
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
ANSIBLE_METADATA = {
|
|
- 'metadata_version': '1.1',
|
|
- 'status': ['preview'],
|
|
- 'supported_by': 'community'
|
|
+ "metadata_version": "1.1",
|
|
+ "status": ["preview"],
|
|
+ "supported_by": "community",
|
|
}
|
|
|
|
-DOCUMENTATION = '''
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: bsize
|
|
|
|
@@ -15,6 +19,7 @@ short_description: Module for basic manipulation with byte sizes
|
|
version_added: "2.5"
|
|
|
|
description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
- "Module accepts byte size strings with the units and produces strings in
|
|
form of input accepted by different storage tools"
|
|
|
|
@@ -23,67 +28,72 @@ options:
|
|
description:
|
|
- String containing number and byte units
|
|
required: true
|
|
+ type: str
|
|
|
|
author:
|
|
- - Jan Pokorny (japokorn@redhat.com)
|
|
-'''
|
|
+ - Jan Pokorny (@japokorn)
|
|
+"""
|
|
|
|
-EXAMPLES = '''
|
|
+EXAMPLES = """
|
|
# Obtain sizes in format for various tools
|
|
- name: Get 10 KiB size
|
|
bsize:
|
|
size: 10 KiB
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
size:
|
|
description: Size in binary format units
|
|
type: str
|
|
+ returned: success
|
|
bytes:
|
|
description: Size in bytes
|
|
type: int
|
|
+ returned: success
|
|
lvm:
|
|
description: Size in binary format. No space after the number,
|
|
first letter of unit prefix in lowercase only
|
|
type: str
|
|
+ returned: success
|
|
parted:
|
|
description: Size in binary format. No space after the number
|
|
type: str
|
|
-'''
|
|
+ returned: success
|
|
+"""
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible.module_utils.storage_lsr.size import Size
|
|
|
|
+
|
|
def run_module():
|
|
# available arguments/parameters that a user can pass
|
|
module_args = dict(
|
|
- size=dict(type='str', required=True),
|
|
+ size=dict(type="str", required=True),
|
|
)
|
|
|
|
# seed the result dict in the object
|
|
- result = dict(
|
|
- changed=False
|
|
- )
|
|
+ result = dict(changed=False)
|
|
|
|
- module = AnsibleModule(argument_spec=module_args,
|
|
- supports_check_mode=True)
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
|
|
- size = Size(module.params['size'])
|
|
+ size = Size(module.params["size"])
|
|
|
|
- result['size'] = size.get(fmt="%d %sb")
|
|
- result['bytes'] = size.bytes
|
|
- result['lvm'] = size.get(fmt="%d%sb").lower()[:-2]
|
|
- result['parted'] = size.get(fmt="%d%sb")
|
|
+ result["size"] = size.get(fmt="%d %sb")
|
|
+ result["bytes"] = size.bytes
|
|
+ result["lvm"] = size.get(fmt="%d%sb").lower()[:-2]
|
|
+ result["parted"] = size.get(fmt="%d%sb")
|
|
|
|
# use whatever logic you need to determine whether or not this module
|
|
# made any modifications to your target
|
|
- result['changed'] = False
|
|
+ result["changed"] = False
|
|
|
|
# success - return result
|
|
module.exit_json(**result)
|
|
|
|
+
|
|
def main():
|
|
run_module()
|
|
|
|
-if __name__ == '__main__':
|
|
+
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/library/find_unused_disk.py b/library/find_unused_disk.py
|
|
index 0a6fc7d..c688170 100644
|
|
--- a/library/find_unused_disk.py
|
|
+++ b/library/find_unused_disk.py
|
|
@@ -1,10 +1,15 @@
|
|
#!/usr/bin/python
|
|
|
|
-DOCUMENTATION = '''
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: find_unused_disk
|
|
short_description: Gets unused disks
|
|
description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
- Disks are considered in ascending alphanumeric sorted order.
|
|
- Disks that meet all conditions are considered 'empty' and returned (using kernel device name) in a list.
|
|
- 1. No known signatures exist on the disk, with the exception of partition tables.
|
|
@@ -15,18 +20,18 @@ description:
|
|
- Number of returned disks defaults to first 10, but can be specified with 'max_return' argument.
|
|
author: Eda Zhou (@edamamez)
|
|
options:
|
|
- option-name: max_return
|
|
- description: Sets the maximum number of unused disks to return.
|
|
- default: 10
|
|
- type: int
|
|
-
|
|
- option-name: min_size
|
|
- description: Specifies the minimum disk size to return an unused disk.
|
|
- default: 0
|
|
- type: str
|
|
-'''
|
|
-
|
|
-EXAMPLES = '''
|
|
+ max_return:
|
|
+ description: Sets the maximum number of unused disks to return.
|
|
+ default: 10
|
|
+ type: int
|
|
+
|
|
+ min_size:
|
|
+ description: Specifies the minimum disk size to return an unused disk.
|
|
+ default: 0
|
|
+ type: str
|
|
+"""
|
|
+
|
|
+EXAMPLES = """
|
|
- name: test finding first unused device module
|
|
hosts: localhost
|
|
tasks:
|
|
@@ -38,9 +43,9 @@ EXAMPLES = '''
|
|
- name: dump test output
|
|
debug:
|
|
msg: '{{ testout }}'
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
disk_name:
|
|
description: Information about unused disks
|
|
returned: On success
|
|
@@ -50,14 +55,15 @@ disk_name:
|
|
description: Unused disk(s) that have been found
|
|
returned: On success
|
|
type: list
|
|
- samples: ["sda1", "dm-0", "dm-3"]
|
|
- ["sda"]
|
|
+ samples: |
|
|
+ ["sda1", "dm-0", "dm-3"]
|
|
+ ["sda"]
|
|
none:
|
|
description: No unused disks were found
|
|
returned: On success
|
|
type: string
|
|
sample: "Unable to find unused disk"
|
|
-'''
|
|
+"""
|
|
|
|
|
|
import os
|
|
@@ -68,7 +74,7 @@ from ansible.module_utils.storage_lsr.size import Size
|
|
|
|
|
|
SYS_CLASS_BLOCK = "/sys/class/block/"
|
|
-IGNORED_DEVICES = [re.compile(r'^/dev/nullb\d+$')]
|
|
+IGNORED_DEVICES = [re.compile(r"^/dev/nullb\d+$")]
|
|
|
|
|
|
def is_ignored(disk_path):
|
|
@@ -78,13 +84,13 @@ def is_ignored(disk_path):
|
|
|
|
def no_signature(run_command, disk_path):
|
|
"""Return true if no known signatures exist on the disk."""
|
|
- signatures = run_command(['blkid', '-p', disk_path])
|
|
- return not 'UUID' in signatures[1]
|
|
+ signatures = run_command(["blkid", "-p", disk_path])
|
|
+ return "UUID" not in signatures[1]
|
|
|
|
|
|
def no_holders(disk_path):
|
|
"""Return true if the disk has no holders."""
|
|
- holders = os.listdir(SYS_CLASS_BLOCK + get_sys_name(disk_path) + '/holders/')
|
|
+ holders = os.listdir(SYS_CLASS_BLOCK + get_sys_name(disk_path) + "/holders/")
|
|
return len(holders) == 0
|
|
|
|
|
|
@@ -101,36 +107,45 @@ def get_sys_name(disk_path):
|
|
if not os.path.islink(disk_path):
|
|
return os.path.basename(disk_path)
|
|
|
|
- node_dir = '/'.join(disk_path.split('/')[-1])
|
|
- return os.path.normpath(node_dir + '/' + os.readlink(disk_path))
|
|
+ node_dir = "/".join(disk_path.split("/")[-1])
|
|
+ return os.path.normpath(node_dir + "/" + os.readlink(disk_path))
|
|
|
|
|
|
def get_partitions(disk_path):
|
|
sys_name = get_sys_name(disk_path)
|
|
partitions = list()
|
|
for filename in os.listdir(SYS_CLASS_BLOCK + sys_name):
|
|
- if re.match(sys_name + r'p?\d+$', filename):
|
|
+ if re.match(sys_name + r"p?\d+$", filename):
|
|
partitions.append(filename)
|
|
|
|
return partitions
|
|
|
|
|
|
def get_disks(run_command):
|
|
- buf = run_command(["lsblk", "-p", "--pairs", "--bytes", "-o", "NAME,TYPE,SIZE,FSTYPE"])[1]
|
|
+ buf = run_command(
|
|
+ ["lsblk", "-p", "--pairs", "--bytes", "-o", "NAME,TYPE,SIZE,FSTYPE"]
|
|
+ )[1]
|
|
disks = dict()
|
|
for line in buf.splitlines():
|
|
if not line:
|
|
continue
|
|
|
|
- m = re.search(r'NAME="(?P<path>[^"]*)" TYPE="(?P<type>[^"]*)" SIZE="(?P<size>\d+)" FSTYPE="(?P<fstype>[^"]*)"', line)
|
|
+ m = re.search(
|
|
+ r'NAME="(?P<path>[^"]*)" TYPE="(?P<type>[^"]*)" SIZE="(?P<size>\d+)" FSTYPE="(?P<fstype>[^"]*)"',
|
|
+ line,
|
|
+ )
|
|
if m is None:
|
|
print(line)
|
|
continue
|
|
|
|
- if m.group('type') != "disk":
|
|
+ if m.group("type") != "disk":
|
|
continue
|
|
|
|
- disks[m.group('path')] = {"type": m.group('type'), "size": m.group('size'), "fstype": m.group('fstype')}
|
|
+ disks[m.group("path")] = {
|
|
+ "type": m.group("type"),
|
|
+ "size": m.group("size"),
|
|
+ "fstype": m.group("fstype"),
|
|
+ }
|
|
|
|
return disks
|
|
|
|
@@ -138,19 +153,13 @@ def get_disks(run_command):
|
|
def run_module():
|
|
"""Create the module"""
|
|
module_args = dict(
|
|
- max_return=dict(type='int', required=False, default=10),
|
|
- min_size=dict(type='str', required=False, default=0)
|
|
+ max_return=dict(type="int", required=False, default=10),
|
|
+ min_size=dict(type="str", required=False, default=0),
|
|
)
|
|
|
|
- result = dict(
|
|
- changed=False,
|
|
- disks=[]
|
|
- )
|
|
+ result = dict(changed=False, disks=[])
|
|
|
|
- module = AnsibleModule(
|
|
- argument_spec=module_args,
|
|
- supports_check_mode=True
|
|
- )
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
|
|
run_command = module.run_command
|
|
|
|
@@ -161,7 +170,7 @@ def run_module():
|
|
if attrs["fstype"]:
|
|
continue
|
|
|
|
- if Size(attrs["size"]).bytes < Size(module.params['min_size']).bytes:
|
|
+ if Size(attrs["size"]).bytes < Size(module.params["min_size"]).bytes:
|
|
continue
|
|
|
|
if get_partitions(path):
|
|
@@ -173,14 +182,14 @@ def run_module():
|
|
if not can_open(path):
|
|
continue
|
|
|
|
- result['disks'].append(os.path.basename(path))
|
|
- if len(result['disks']) >= module.params['max_return']:
|
|
+ result["disks"].append(os.path.basename(path))
|
|
+ if len(result["disks"]) >= module.params["max_return"]:
|
|
break
|
|
|
|
- if not result['disks']:
|
|
- result['disks'] = "Unable to find unused disk"
|
|
+ if not result["disks"]:
|
|
+ result["disks"] = "Unable to find unused disk"
|
|
else:
|
|
- result['disks'].sort()
|
|
+ result["disks"].sort()
|
|
|
|
module.exit_json(**result)
|
|
|
|
@@ -190,5 +199,5 @@ def main():
|
|
run_module()
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/library/lvm_gensym.py b/library/lvm_gensym.py
|
|
index 49d1822..3e0f613 100644
|
|
--- a/library/lvm_gensym.py
|
|
+++ b/library/lvm_gensym.py
|
|
@@ -1,66 +1,75 @@
|
|
#!/usr/bin/python
|
|
"""Generates unique, default names for a volume group and logical volume"""
|
|
|
|
-from ansible.module_utils.basic import AnsibleModule
|
|
-from ansible.module_utils import facts
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
|
|
ANSIBLE_METADATA = {
|
|
- 'metadata_version': '1.1',
|
|
- 'status': ['preview'],
|
|
- 'supported_by': 'community'
|
|
+ "metadata_version": "1.1",
|
|
+ "status": ["preview"],
|
|
+ "supported_by": "community",
|
|
}
|
|
|
|
-DOCUMENTATION = '''
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: lvm_gensym
|
|
short_description: Generate default names for lvm variables
|
|
version_added: "2.4"
|
|
-description:
|
|
- - "Module accepts two input strings consisting of a file system type and
|
|
+description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
+ - "Module accepts two input strings consisting of a file system type and
|
|
a mount point path, and outputs names based on system information"
|
|
options:
|
|
fs_type:
|
|
description:
|
|
- - String describing the desired file system type
|
|
- required: true
|
|
+ - String describing the desired file system type
|
|
+ required: true
|
|
+ type: str
|
|
mount:
|
|
description:
|
|
- - String describing the mount point path
|
|
+ - String describing the mount point path
|
|
required: true
|
|
-author:
|
|
- - Tim Flannagan (tflannag@redhat.com)
|
|
-'''
|
|
+ type: str
|
|
+author:
|
|
+ - Tim Flannagan (@timflannagan)
|
|
+"""
|
|
|
|
-EXAMPLES = '''
|
|
-- name: Generate names
|
|
+EXAMPLES = """
|
|
+- name: Generate names
|
|
lvm_gensym:
|
|
fs_type: "{{ fs_type }}"
|
|
mount: "{{ mount_point }}"
|
|
register: lvm_results
|
|
when: lvm_vg == "" and mount_point != "" and fs_type != ""
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
vg_name:
|
|
description: The default generated name for an unspecified volume group
|
|
type: str
|
|
-
|
|
+ returned: success
|
|
lv_name:
|
|
description: The default generated name for an unspecified logical volume
|
|
type: str
|
|
-'''
|
|
+ returned: success
|
|
+"""
|
|
+
|
|
+from ansible.module_utils.basic import AnsibleModule
|
|
+from ansible.module_utils import facts
|
|
|
|
|
|
def get_os_name():
|
|
"""Search the host file and return the name in the ID column"""
|
|
- for line in open('/etc/os-release').readlines():
|
|
- if not line.find('ID='):
|
|
+ for line in open("/etc/os-release").readlines():
|
|
+ if not line.find("ID="):
|
|
os_name = line[3:]
|
|
break
|
|
|
|
- os_name = os_name.replace('\n', '').replace('"', '')
|
|
+ os_name = os_name.replace("\n", "").replace('"', "")
|
|
return os_name
|
|
|
|
+
|
|
def name_is_unique(name, used_names):
|
|
"""Check if name is contained in the used_names list and return boolean value"""
|
|
if name not in used_names:
|
|
@@ -68,14 +77,15 @@ def name_is_unique(name, used_names):
|
|
|
|
return False
|
|
|
|
+
|
|
def get_unique_name_from_base(base_name, used_names):
|
|
"""Generate a unique name given a base name and a list of used names, and return that unique name"""
|
|
counter = 0
|
|
while not name_is_unique(base_name, used_names):
|
|
if counter == 0:
|
|
- base_name = base_name + '_' + str(counter)
|
|
+ base_name = base_name + "_" + str(counter)
|
|
else:
|
|
- base_name = base_name[:-2] + '_' + str(counter)
|
|
+ base_name = base_name[:-2] + "_" + str(counter)
|
|
counter += 1
|
|
|
|
return base_name
|
|
@@ -83,8 +93,8 @@ def get_unique_name_from_base(base_name, used_names):
|
|
|
|
def get_vg_name_base(host_name, os_name):
|
|
"""Return a base name for a volume group based on the host and os names"""
|
|
- if host_name != None and len(host_name) != 0:
|
|
- vg_default = os_name + '_' + host_name
|
|
+ if host_name is not None and len(host_name) != 0:
|
|
+ vg_default = os_name + "_" + host_name
|
|
else:
|
|
vg_default = os_name
|
|
|
|
@@ -93,65 +103,68 @@ def get_vg_name_base(host_name, os_name):
|
|
|
|
def get_vg_name(host_name, lvm_facts):
|
|
"""Generate a base volume group name, verify its uniqueness, and return that unique name"""
|
|
- used_vg_names = lvm_facts['vgs'].keys()
|
|
+ used_vg_names = lvm_facts["vgs"].keys()
|
|
os_name = get_os_name()
|
|
name = get_vg_name_base(host_name, os_name)
|
|
|
|
return get_unique_name_from_base(name, used_vg_names)
|
|
|
|
+
|
|
def get_lv_name_base(fs_type, mount_point):
|
|
"""Return a logical volume base name using given parameters"""
|
|
- if 'swap' in fs_type.lower():
|
|
- lv_default = 'swap'
|
|
- elif mount_point.startswith('/'):
|
|
- if mount_point == '/':
|
|
- lv_default = 'root'
|
|
+ if "swap" in fs_type.lower():
|
|
+ lv_default = "swap"
|
|
+ elif mount_point.startswith("/"):
|
|
+ if mount_point == "/":
|
|
+ lv_default = "root"
|
|
else:
|
|
- lv_default = mount_point[1:].replace('/', '_')
|
|
+ lv_default = mount_point[1:].replace("/", "_")
|
|
else:
|
|
- lv_default = 'lv'
|
|
+ lv_default = "lv"
|
|
|
|
return lv_default
|
|
|
|
|
|
def get_lv_name(fs_type, mount_point, lvm_facts):
|
|
"""Return a unique logical volume name based on specified file system type, mount point, and system facts"""
|
|
- used_lv_names = lvm_facts['lvs'].keys()
|
|
+ used_lv_names = lvm_facts["lvs"].keys()
|
|
name = get_lv_name_base(fs_type, mount_point)
|
|
|
|
return get_unique_name_from_base(name, used_lv_names)
|
|
|
|
+
|
|
def run_module():
|
|
"""Setup and initialize all relevant ansible module data"""
|
|
module_args = dict(
|
|
- mount=dict(type='str', required=True),
|
|
- fs_type=dict(type='str', required=True)
|
|
+ mount=dict(type="str", required=True), fs_type=dict(type="str", required=True)
|
|
)
|
|
|
|
- result = dict(
|
|
- changed=False,
|
|
- vg_name='',
|
|
- lv_name=''
|
|
- )
|
|
+ result = dict(changed=False, vg_name="", lv_name="")
|
|
|
|
- module = AnsibleModule(
|
|
- argument_spec=module_args,
|
|
- supports_check_mode=True
|
|
- )
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
|
|
- lvm_facts = facts.ansible_facts(module)['lvm']
|
|
- host_name = facts.ansible_facts(module)['nodename'].lower().replace('.', '_').replace('-', '_')
|
|
+ lvm_facts = facts.ansible_facts(module)["lvm"]
|
|
+ host_name = (
|
|
+ facts.ansible_facts(module)["nodename"]
|
|
+ .lower()
|
|
+ .replace(".", "_")
|
|
+ .replace("-", "_")
|
|
+ )
|
|
|
|
- result['lv_name'] = get_lv_name(module.params['fs_type'], module.params['mount'], lvm_facts)
|
|
- result['vg_name'] = get_vg_name(host_name, lvm_facts)
|
|
+ result["lv_name"] = get_lv_name(
|
|
+ module.params["fs_type"], module.params["mount"], lvm_facts
|
|
+ )
|
|
+ result["vg_name"] = get_vg_name(host_name, lvm_facts)
|
|
|
|
- if result['lv_name'] != '' and result['vg_name'] != '':
|
|
+ if result["lv_name"] != "" and result["vg_name"] != "":
|
|
module.exit_json(**result)
|
|
else:
|
|
module.fail_json(msg="Unable to initialize both group and volume names")
|
|
|
|
+
|
|
def main():
|
|
run_module()
|
|
|
|
-if __name__ == '__main__':
|
|
+
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/library/resolve_blockdev.py b/library/resolve_blockdev.py
|
|
index 007bb28..df9dcb1 100644
|
|
--- a/library/resolve_blockdev.py
|
|
+++ b/library/resolve_blockdev.py
|
|
@@ -1,17 +1,22 @@
|
|
#!/usr/bin/python
|
|
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
ANSIBLE_METADATA = {
|
|
- 'metadata_version': '1.1',
|
|
- 'status': ['preview'],
|
|
- 'supported_by': 'community'
|
|
+ "metadata_version": "1.1",
|
|
+ "status": ["preview"],
|
|
+ "supported_by": "community",
|
|
}
|
|
|
|
-DOCUMENTATION = '''
|
|
+DOCUMENTATION = """
|
|
---
|
|
module: resolve_blockdev
|
|
short_description: Resolve block device specification to device node path.
|
|
version_added: "2.5"
|
|
description:
|
|
+ - "WARNING: Do not use this module directly! It is only for role internal use."
|
|
- "This module accepts various forms of block device identifiers and
|
|
resolves them to the correct block device node path."
|
|
options:
|
|
@@ -19,11 +24,12 @@ options:
|
|
description:
|
|
- String describing a block device
|
|
required: true
|
|
+ type: str
|
|
author:
|
|
- - David Lehman (dlehman@redhat.com)
|
|
-'''
|
|
+ - David Lehman (@dwlehman)
|
|
+"""
|
|
|
|
-EXAMPLES = '''
|
|
+EXAMPLES = """
|
|
- name: Resolve device by label
|
|
resolve_blockdev:
|
|
spec: LABEL=MyData
|
|
@@ -35,13 +41,14 @@ EXAMPLES = '''
|
|
- name: Resolve device by /dev/disk/by-id symlink name
|
|
resolve_blockdev:
|
|
spec: wwn-0x5000c5005bc37f3f
|
|
-'''
|
|
+"""
|
|
|
|
-RETURN = '''
|
|
+RETURN = """
|
|
device:
|
|
description: Path to block device node
|
|
type: str
|
|
-'''
|
|
+ returned: success
|
|
+"""
|
|
|
|
import glob
|
|
import os
|
|
@@ -52,37 +59,42 @@ from ansible.module_utils.basic import AnsibleModule
|
|
DEV_MD = "/dev/md"
|
|
DEV_MAPPER = "/dev/mapper"
|
|
SYS_CLASS_BLOCK = "/sys/class/block"
|
|
-SEARCH_DIRS = ['/dev', DEV_MAPPER, DEV_MD] + glob.glob("/dev/disk/by-*")
|
|
-MD_KERNEL_DEV = re.compile(r'/dev/md\d+(p\d+)?$')
|
|
+SEARCH_DIRS = ["/dev", DEV_MAPPER, DEV_MD] + glob.glob("/dev/disk/by-*")
|
|
+MD_KERNEL_DEV = re.compile(r"/dev/md\d+(p\d+)?$")
|
|
|
|
|
|
def resolve_blockdev(spec, run_cmd):
|
|
if "=" in spec:
|
|
device = run_cmd("blkid -t %s -o device" % spec)[1].strip()
|
|
- elif not spec.startswith('/'):
|
|
+ elif not spec.startswith("/"):
|
|
for devdir in SEARCH_DIRS:
|
|
device = "%s/%s" % (devdir, spec)
|
|
if os.path.exists(device):
|
|
break
|
|
else:
|
|
- device = ''
|
|
+ device = ""
|
|
else:
|
|
device = spec
|
|
|
|
if not device or not os.path.exists(device):
|
|
- return ''
|
|
+ return ""
|
|
|
|
return canonical_device(os.path.realpath(device))
|
|
|
|
|
|
def _get_dm_name_from_kernel_dev(kdev):
|
|
- return open("%s/%s/dm/name" % (SYS_CLASS_BLOCK, os.path.basename(kdev))).read().strip()
|
|
+ return (
|
|
+ open("%s/%s/dm/name" % (SYS_CLASS_BLOCK, os.path.basename(kdev))).read().strip()
|
|
+ )
|
|
|
|
|
|
def _get_md_name_from_kernel_dev(kdev):
|
|
minor = os.minor(os.stat(kdev).st_rdev)
|
|
- return next(name for name in os.listdir(DEV_MD)
|
|
- if os.minor(os.stat("%s/%s" % (DEV_MD, name)).st_rdev) == minor)
|
|
+ return next(
|
|
+ name
|
|
+ for name in os.listdir(DEV_MD)
|
|
+ if os.minor(os.stat("%s/%s" % (DEV_MD, name)).st_rdev) == minor
|
|
+ )
|
|
|
|
|
|
def canonical_device(device):
|
|
@@ -94,26 +106,27 @@ def canonical_device(device):
|
|
|
|
|
|
def run_module():
|
|
- module_args = dict(
|
|
- spec=dict(type='str')
|
|
- )
|
|
+ module_args = dict(spec=dict(type="str"))
|
|
|
|
result = dict(
|
|
device=None,
|
|
)
|
|
|
|
- module = AnsibleModule(
|
|
- argument_spec=module_args,
|
|
- supports_check_mode=True
|
|
- )
|
|
+ module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
|
|
try:
|
|
- result['device'] = resolve_blockdev(module.params['spec'], run_cmd=module.run_command)
|
|
+ result["device"] = resolve_blockdev(
|
|
+ module.params["spec"], run_cmd=module.run_command
|
|
+ )
|
|
except Exception:
|
|
pass
|
|
|
|
- if not result['device'] or not os.path.exists(result['device']):
|
|
- module.fail_json(msg="The {} device spec could not be resolved".format(module.params['spec']))
|
|
+ if not result["device"] or not os.path.exists(result["device"]):
|
|
+ module.fail_json(
|
|
+ msg="The {0} device spec could not be resolved".format(
|
|
+ module.params["spec"]
|
|
+ )
|
|
+ )
|
|
|
|
module.exit_json(**result)
|
|
|
|
@@ -122,5 +135,5 @@ def main():
|
|
run_module()
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
+if __name__ == "__main__":
|
|
main()
|
|
diff --git a/module_utils/storage_lsr/size.py b/module_utils/storage_lsr/size.py
|
|
index 16f3d7c..1e91faa 100644
|
|
--- a/module_utils/storage_lsr/size.py
|
|
+++ b/module_utils/storage_lsr/size.py
|
|
@@ -1,4 +1,6 @@
|
|
-#!/bin/python2
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
|
|
import re
|
|
|
|
@@ -7,15 +9,20 @@ BINARY_FACTOR = 2 ** 10
|
|
|
|
# index of the item in the list determines the exponent for size computation
|
|
# e.g. size_in_bytes = value * (DECIMAL_FACTOR ** (index(mega)+1)) = value * (1000 ** (1+1))
|
|
-PREFIXES_DECIMAL = [["k", "M", "G", "T", "P", "E", "Z", "Y"],
|
|
- ["kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta"]]
|
|
-PREFIXES_BINARY = [["Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"],
|
|
- ["kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"]]
|
|
+# pylint: disable=bad-whitespace
|
|
+PREFIXES_DECIMAL = [
|
|
+ ["k", "M", "G", "T", "P", "E", "Z", "Y"], # nopep8
|
|
+ ["kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta"],
|
|
+] # nopep8
|
|
+PREFIXES_BINARY = [
|
|
+ ["Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"], # nopep8
|
|
+ ["kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"],
|
|
+] # nopep8
|
|
SUFFIXES = ["bytes", "byte", "B"]
|
|
|
|
+
|
|
class Size(object):
|
|
- ''' Class for basic manipulation of the sizes in *bytes
|
|
- '''
|
|
+ """Class for basic manipulation of the sizes in *bytes"""
|
|
|
|
def __init__(self, value):
|
|
raw_number, raw_units = self._parse_input(str(value))
|
|
@@ -25,9 +32,9 @@ class Size(object):
|
|
self.units = raw_units
|
|
|
|
def _parse_input(self, value):
|
|
- ''' splits input string into number and unit parts
|
|
- returns number part, unit part
|
|
- '''
|
|
+ """splits input string into number and unit parts
|
|
+ returns number part, unit part
|
|
+ """
|
|
m = re.search("^(.*?)([^0-9]*)$", value)
|
|
|
|
raw_number = m.group(1).strip()
|
|
@@ -39,12 +46,12 @@ class Size(object):
|
|
return raw_number, raw_units
|
|
|
|
def _parse_units(self, raw_units):
|
|
- '''
|
|
- gets string containing size units and
|
|
- returns *_FACTOR (BINARY or DECIMAL) and the prefix position (not index!)
|
|
- in the PREFIXES_* list
|
|
- If no unit is specified defaults to BINARY and Bytes
|
|
- '''
|
|
+ """
|
|
+ gets string containing size units and
|
|
+ returns *_FACTOR (BINARY or DECIMAL) and the prefix position (not index!)
|
|
+ in the PREFIXES_* list
|
|
+ If no unit is specified defaults to BINARY and Bytes
|
|
+ """
|
|
|
|
prefix = raw_units
|
|
no_suffix_flag = True
|
|
@@ -54,7 +61,7 @@ class Size(object):
|
|
for suffix in SUFFIXES:
|
|
if raw_units.lower().endswith(suffix.lower()):
|
|
no_suffix_flag = False
|
|
- prefix = raw_units[:-len(suffix)]
|
|
+ prefix = raw_units[: -len(suffix)]
|
|
break
|
|
|
|
if prefix == "":
|
|
@@ -87,18 +94,18 @@ class Size(object):
|
|
if idx < 0 or not valid_suffix:
|
|
raise ValueError("Unable to identify unit '%s'" % raw_units)
|
|
|
|
- return used_factor, idx+1
|
|
+ return used_factor, idx + 1
|
|
|
|
def _parse_number(self, raw_number):
|
|
- ''' parse input string containing number
|
|
- return float
|
|
- '''
|
|
+ """parse input string containing number
|
|
+ return float
|
|
+ """
|
|
return float(raw_number)
|
|
|
|
def _get_unit(self, factor, exponent, unit_type=0):
|
|
- ''' based on decimal or binary factor and exponent
|
|
- obtain and return correct unit
|
|
- '''
|
|
+ """based on decimal or binary factor and exponent
|
|
+ obtain and return correct unit
|
|
+ """
|
|
|
|
if unit_type == 0:
|
|
suffix = "B"
|
|
@@ -112,12 +119,11 @@ class Size(object):
|
|
prefix_lst = PREFIXES_DECIMAL[unit_type]
|
|
else:
|
|
prefix_lst = PREFIXES_BINARY[unit_type]
|
|
- return prefix_lst[exponent-1] + suffix
|
|
+ return prefix_lst[exponent - 1] + suffix
|
|
|
|
@property
|
|
def bytes(self):
|
|
- ''' returns size value in bytes as int
|
|
- '''
|
|
+ """returns size value in bytes as int"""
|
|
return int((self.factor ** self.exponent) * self.number)
|
|
|
|
def _format(self, format_str, factor, exponent):
|
|
@@ -129,20 +135,20 @@ class Size(object):
|
|
return result
|
|
|
|
def get(self, units="autobin", fmt="%0.1f %sb"):
|
|
- ''' returns size value as a string with given units and format
|
|
+ """returns size value as a string with given units and format
|
|
|
|
- "units" parameter allows to select preferred unit:
|
|
- for example "KiB" or "megabytes"
|
|
- accepted values are also:
|
|
- "autobin" (default) - uses the highest human readable unit (binary)
|
|
- "autodec" - uses the highest human readable unit (decimal)
|
|
+ "units" parameter allows to select preferred unit:
|
|
+ for example "KiB" or "megabytes"
|
|
+ accepted values are also:
|
|
+ "autobin" (default) - uses the highest human readable unit (binary)
|
|
+ "autodec" - uses the highest human readable unit (decimal)
|
|
|
|
- "fmt" parameter allows to specify the output format:
|
|
- %sb - will be replaced with the short byte size unit (e.g. MiB)
|
|
- %lb - will be replaced with the long byte size unit (e.g. kilobytes)
|
|
- value can be formatted using standard string replacements (e.g. %d, %f)
|
|
+ "fmt" parameter allows to specify the output format:
|
|
+ %sb - will be replaced with the short byte size unit (e.g. MiB)
|
|
+ %lb - will be replaced with the long byte size unit (e.g. kilobytes)
|
|
+ value can be formatted using standard string replacements (e.g. %d, %f)
|
|
|
|
- '''
|
|
+ """
|
|
|
|
ftr = BINARY_FACTOR
|
|
if units == "autodec":
|
|
@@ -155,6 +161,8 @@ class Size(object):
|
|
exp += 1
|
|
else:
|
|
ftr, exp = self._parse_units(units.strip())
|
|
- value = (float(self.factor ** self.exponent) / float(ftr ** exp)) * self.number
|
|
+ value = (
|
|
+ float(self.factor ** self.exponent) / float(ftr ** exp)
|
|
+ ) * self.number
|
|
|
|
return self._format(fmt, ftr, exp) % value
|
|
diff --git a/tests/setup_module_utils.sh b/tests/setup_module_utils.sh
|
|
deleted file mode 100755
|
|
index 94d102d..0000000
|
|
--- a/tests/setup_module_utils.sh
|
|
+++ /dev/null
|
|
@@ -1,41 +0,0 @@
|
|
-#!/bin/bash
|
|
-# SPDX-License-Identifier: MIT
|
|
-
|
|
-set -euo pipefail
|
|
-
|
|
-if [ -n "${DEBUG:-}" ] ; then
|
|
- set -x
|
|
-fi
|
|
-
|
|
-if [ ! -d "${1:-}" ] ; then
|
|
- echo Either ansible is not installed, or there is no ansible/module_utils
|
|
- echo in "$1" - Skipping
|
|
- exit 0
|
|
-fi
|
|
-
|
|
-if [ ! -d "${2:-}" ] ; then
|
|
- echo Role has no module_utils - Skipping
|
|
- exit 0
|
|
-fi
|
|
-
|
|
-# we need absolute path for $2
|
|
-absmoddir=$( readlink -f "$2" )
|
|
-
|
|
-# clean up old links to module_utils
|
|
-for item in "$1"/* ; do
|
|
- if lnitem=$( readlink "$item" ) && test -n "$lnitem" ; then
|
|
- case "$lnitem" in
|
|
- *"${2}"*) rm -f "$item" ;;
|
|
- esac
|
|
- fi
|
|
-done
|
|
-
|
|
-# add new links to module_utils
|
|
-for item in "$absmoddir"/* ; do
|
|
- case "$item" in
|
|
- *__pycache__) continue;;
|
|
- *.pyc) continue;;
|
|
- esac
|
|
- bnitem=$( basename "$item" )
|
|
- ln -s "$item" "$1/$bnitem"
|
|
-done
|
|
diff --git a/tests/test-verify-volume-device.yml b/tests/test-verify-volume-device.yml
|
|
index 3fb56a6..c7ba5ec 100644
|
|
--- a/tests/test-verify-volume-device.yml
|
|
+++ b/tests/test-verify-volume-device.yml
|
|
@@ -23,11 +23,11 @@
|
|
|
|
- name: (1/2) Process volume type (set initial value)
|
|
set_fact:
|
|
- st_volume_type: "{{ storage_test_volume.type }}"
|
|
+ st_volume_type: "{{ storage_test_volume.type }}"
|
|
|
|
- name: (2/2) Process volume type (get RAID value)
|
|
set_fact:
|
|
- st_volume_type: "{{ storage_test_volume.raid_level }}"
|
|
+ st_volume_type: "{{ storage_test_volume.raid_level }}"
|
|
when: storage_test_volume.type == "raid"
|
|
|
|
- name: Verify the volume's device type
|
|
diff --git a/tests/test-verify-volume-md.yml b/tests/test-verify-volume-md.yml
|
|
index b21d8d2..27e8333 100644
|
|
--- a/tests/test-verify-volume-md.yml
|
|
+++ b/tests/test-verify-volume-md.yml
|
|
@@ -9,7 +9,7 @@
|
|
register: storage_test_mdadm
|
|
changed_when: false
|
|
|
|
- # pre-chew regex search patterns
|
|
+ # pre-chew regex search patterns
|
|
- set_fact:
|
|
storage_test_md_active_devices_re: "{{ ('Active Devices : ' ~ storage_test_volume.raid_device_count ~ '\n')|regex_escape() }}"
|
|
when: storage_test_volume.raid_device_count is defined
|
|
diff --git a/tests/test.yml b/tests/test.yml
|
|
index 944b3cd..cb718a7 100644
|
|
--- a/tests/test.yml
|
|
+++ b/tests/test.yml
|
|
@@ -16,7 +16,7 @@
|
|
mount_point: '/opt/test1'
|
|
- name: bar
|
|
disks: ['vdc']
|
|
- #state: "absent"
|
|
+ # state: "absent"
|
|
volumes:
|
|
- name: test2
|
|
size: 8g
|
|
diff --git a/tests/tests_create_lv_size_equal_to_vg.yml b/tests/tests_create_lv_size_equal_to_vg.yml
|
|
index 21a5788..1737036 100644
|
|
--- a/tests/tests_create_lv_size_equal_to_vg.yml
|
|
+++ b/tests/tests_create_lv_size_equal_to_vg.yml
|
|
@@ -23,13 +23,13 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ lv_size }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ lv_size }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -37,12 +37,12 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: "absent"
|
|
- volumes:
|
|
- - name: test1
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: "absent"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
diff --git a/tests/tests_create_partition_volume_then_remove.yml b/tests/tests_create_partition_volume_then_remove.yml
|
|
index 351b022..567f8dd 100644
|
|
--- a/tests/tests_create_partition_volume_then_remove.yml
|
|
+++ b/tests/tests_create_partition_volume_then_remove.yml
|
|
@@ -53,7 +53,7 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: "{{ unused_disks[0] }}"
|
|
+ - name: "{{ unused_disks[0] }}"
|
|
type: partition
|
|
disks: "{{ unused_disks }}"
|
|
state: absent
|
|
@@ -70,7 +70,7 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: "{{ unused_disks[0] }}"
|
|
+ - name: "{{ unused_disks[0] }}"
|
|
type: partition
|
|
disks: "{{ unused_disks }}"
|
|
state: absent
|
|
diff --git a/tests/tests_existing_lvm_pool.yml b/tests/tests_existing_lvm_pool.yml
|
|
index 854ac0d..2490914 100644
|
|
--- a/tests/tests_existing_lvm_pool.yml
|
|
+++ b/tests/tests_existing_lvm_pool.yml
|
|
@@ -20,12 +20,12 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: "{{ pool_name }}"
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size }}"
|
|
+ storage_pools:
|
|
+ - name: "{{ pool_name }}"
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
diff --git a/tests/tests_lvm_auto_size_cap.yml b/tests/tests_lvm_auto_size_cap.yml
|
|
index 30aa6a7..eae7ff3 100644
|
|
--- a/tests/tests_lvm_auto_size_cap.yml
|
|
+++ b/tests/tests_lvm_auto_size_cap.yml
|
|
@@ -35,12 +35,12 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: foo
|
|
- type: lvm
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ doubled_size.stdout|trim }}"
|
|
+ - name: foo
|
|
+ type: lvm
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ doubled_size.stdout|trim }}"
|
|
- name: unreachable task
|
|
fail:
|
|
msg: UNREACH
|
|
@@ -58,11 +58,11 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ test_disk_size }}"
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ test_disk_size }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -71,12 +71,12 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: foo
|
|
- type: lvm
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ test_disk_size }}"
|
|
+ - name: foo
|
|
+ type: lvm
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ test_disk_size }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -85,7 +85,7 @@
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: absent
|
|
- volumes: []
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: absent
|
|
+ volumes: []
|
|
diff --git a/tests/tests_lvm_one_disk_one_volume.yml b/tests/tests_lvm_one_disk_one_volume.yml
|
|
index b1096cf..6452f54 100644
|
|
--- a/tests/tests_lvm_one_disk_one_volume.yml
|
|
+++ b/tests/tests_lvm_one_disk_one_volume.yml
|
|
@@ -19,13 +19,13 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -33,13 +33,13 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -47,14 +47,14 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: absent
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
- state: absent
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: absent
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
+ state: absent
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
diff --git a/tests/tests_misc.yml b/tests/tests_misc.yml
|
|
index 3139bc7..afe753a 100644
|
|
--- a/tests/tests_misc.yml
|
|
+++ b/tests/tests_misc.yml
|
|
@@ -197,7 +197,7 @@
|
|
block:
|
|
- name: Try to mount swap filesystem to "{{ mount_location }}"
|
|
include_role:
|
|
- name: linux-system-roles.storage
|
|
+ name: linux-system-roles.storage
|
|
vars:
|
|
storage_volumes:
|
|
- name: test1
|
|
diff --git a/tests/tests_null_raid_pool.yml b/tests/tests_null_raid_pool.yml
|
|
index 2b7b9f3..5c3c785 100644
|
|
--- a/tests/tests_null_raid_pool.yml
|
|
+++ b/tests/tests_null_raid_pool.yml
|
|
@@ -31,9 +31,9 @@
|
|
raid_level: "null"
|
|
state: present
|
|
volumes:
|
|
- - name: lv1
|
|
- size: "{{ volume1_size }}"
|
|
- mount_point: "{{ mount_location1 }}"
|
|
+ - name: lv1
|
|
+ size: "{{ volume1_size }}"
|
|
+ mount_point: "{{ mount_location1 }}"
|
|
|
|
- name: get existing raids (after run)
|
|
command: "cat /proc/mdstat"
|
|
@@ -52,12 +52,12 @@
|
|
raid_level: "null"
|
|
state: absent
|
|
volumes:
|
|
- - name: lv1
|
|
- size: "{{ volume1_size }}"
|
|
- mount_point: "{{ mount_location1 }}"
|
|
+ - name: lv1
|
|
+ size: "{{ volume1_size }}"
|
|
+ mount_point: "{{ mount_location1 }}"
|
|
|
|
- name: compare mdstat results
|
|
assert:
|
|
that:
|
|
- - storage_test_mdstat1.stdout == storage_test_mdstat2.stdout
|
|
+ - storage_test_mdstat1.stdout == storage_test_mdstat2.stdout
|
|
msg: "Raid created when it should not be"
|
|
diff --git a/tests/tests_resize.yml b/tests/tests_resize.yml
|
|
index 209d129..4fd8583 100644
|
|
--- a/tests/tests_resize.yml
|
|
+++ b/tests/tests_resize.yml
|
|
@@ -29,16 +29,16 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- type: lvm
|
|
- volumes:
|
|
- - name: test1
|
|
- # resizing is currently supported only for ext2/3/4
|
|
- fs_type: 'ext4'
|
|
- size: "{{ volume_size_before }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ type: lvm
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ # resizing is currently supported only for ext2/3/4
|
|
+ fs_type: 'ext4'
|
|
+ size: "{{ volume_size_before }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -46,15 +46,15 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- type: lvm
|
|
- disks: "{{ unused_disks }}"
|
|
- volumes:
|
|
- - name: test1
|
|
- fs_type: 'ext4'
|
|
- size: "{{ volume_size_after }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ type: lvm
|
|
+ disks: "{{ unused_disks }}"
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ fs_type: 'ext4'
|
|
+ size: "{{ volume_size_after }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -194,14 +194,14 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: absent
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size_before }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: absent
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size_before }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -259,14 +259,14 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: absent
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size_before }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: absent
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size_before }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
|
|
@@ -324,13 +324,13 @@
|
|
include_role:
|
|
name: linux-system-roles.storage
|
|
vars:
|
|
- storage_pools:
|
|
- - name: foo
|
|
- disks: "{{ unused_disks }}"
|
|
- state: absent
|
|
- volumes:
|
|
- - name: test1
|
|
- size: "{{ volume_size_before }}"
|
|
- mount_point: "{{ mount_location }}"
|
|
+ storage_pools:
|
|
+ - name: foo
|
|
+ disks: "{{ unused_disks }}"
|
|
+ state: absent
|
|
+ volumes:
|
|
+ - name: test1
|
|
+ size: "{{ volume_size_before }}"
|
|
+ mount_point: "{{ mount_location }}"
|
|
|
|
- include_tasks: verify-role-results.yml
|
|
diff --git a/tests/unit/bsize_test.py b/tests/unit/bsize_test.py
|
|
index f88a9c1..fae0f5f 100644
|
|
--- a/tests/unit/bsize_test.py
|
|
+++ b/tests/unit/bsize_test.py
|
|
@@ -1,7 +1,12 @@
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
import pytest
|
|
|
|
from storage_lsr.size import Size
|
|
|
|
+
|
|
def test_bsize():
|
|
# check failure on incorrect string
|
|
with pytest.raises(ValueError) as e:
|
|
diff --git a/tests/unit/gensym_test.py b/tests/unit/gensym_test.py
|
|
index 6d164dc..fd00ddf 100644
|
|
--- a/tests/unit/gensym_test.py
|
|
+++ b/tests/unit/gensym_test.py
|
|
@@ -1,68 +1,115 @@
|
|
#!/usr/bin/python
|
|
"""This module tests methods defined in the lvm_gensym.py module using the pytest framework"""
|
|
-import pytest
|
|
-
|
|
+from __future__ import absolute_import, division, print_function
|
|
|
|
-import lvm_gensym
|
|
+__metaclass__ = type
|
|
|
|
+import pytest
|
|
|
|
-used_lv_names = ['root', 'root_0', 'root_1', 'root_2', 'root_3', 'swap_0', 'swap', 'swap_1']
|
|
|
|
-test_lv_names = [{'fs_type': 'ext', 'mount': '/'},
|
|
- {'fs_type': 'zfs', 'mount': '/home/user'},
|
|
- {'fs_type': 'swap', 'mount': ''}
|
|
- ]
|
|
+import lvm_gensym
|
|
|
|
-used_vg_names = ['linux_host', 'rhel_user0', 'rhel_0_user']
|
|
|
|
-test_vg_names = ['rhel_user', 'rhel_user_0', 'rhel_user_1',
|
|
- 'rhel_user_2', 'rhel_user_3', 'linux_user',
|
|
- 'fedora_user', 'fedora_user_0', 'fedora_user_1'
|
|
- ]
|
|
+used_lv_names = [
|
|
+ "root",
|
|
+ "root_0",
|
|
+ "root_1",
|
|
+ "root_2",
|
|
+ "root_3",
|
|
+ "swap_0",
|
|
+ "swap",
|
|
+ "swap_1",
|
|
+]
|
|
+
|
|
+test_lv_names = [
|
|
+ {"fs_type": "ext", "mount": "/"},
|
|
+ {"fs_type": "zfs", "mount": "/home/user"},
|
|
+ {"fs_type": "swap", "mount": ""},
|
|
+]
|
|
+
|
|
+used_vg_names = ["linux_host", "rhel_user0", "rhel_0_user"]
|
|
+
|
|
+test_vg_names = [
|
|
+ "rhel_user",
|
|
+ "rhel_user_0",
|
|
+ "rhel_user_1",
|
|
+ "rhel_user_2",
|
|
+ "rhel_user_3",
|
|
+ "linux_user",
|
|
+ "fedora_user",
|
|
+ "fedora_user_0",
|
|
+ "fedora_user_1",
|
|
+]
|
|
+
|
|
+lvm_facts = {
|
|
+ "lvs": {
|
|
+ "Home": "",
|
|
+ "Swap": "",
|
|
+ "Root": "",
|
|
+ "Root_0": "",
|
|
+ "root": "",
|
|
+ "root_0": "",
|
|
+ "swap": "",
|
|
+ "swap_0": "",
|
|
+ "swap_1": "",
|
|
+ },
|
|
+ "vgs": {"rhel_user": "", "rhel_user_0": "", "rhel_user_1": ""},
|
|
+}
|
|
|
|
-lvm_facts = {'lvs': {'Home': '', 'Swap': '', 'Root': '',
|
|
- 'Root_0': '', 'root': '', 'root_0': '',
|
|
- 'swap': '', 'swap_0': '', 'swap_1': '',
|
|
- },
|
|
- 'vgs': {'rhel_user': '', 'rhel_user_0': '', 'rhel_user_1': ''}
|
|
- }
|
|
|
|
def test_unique_base_name():
|
|
"""Test whether the returned name is unique using a supplied list of test names"""
|
|
- assert lvm_gensym.get_unique_name_from_base('root', used_lv_names) == 'root_4'
|
|
- assert lvm_gensym.get_unique_name_from_base('rhel_user', test_vg_names) == 'rhel_user_4'
|
|
+ assert lvm_gensym.get_unique_name_from_base("root", used_lv_names) == "root_4"
|
|
+ assert (
|
|
+ lvm_gensym.get_unique_name_from_base("rhel_user", test_vg_names)
|
|
+ == "rhel_user_4"
|
|
+ )
|
|
+
|
|
|
|
def test_return_val():
|
|
"""Verify that a supplied unique name and a list of used names returns True"""
|
|
for (index, name) in enumerate(test_vg_names):
|
|
assert lvm_gensym.name_is_unique(name[index], used_vg_names)
|
|
|
|
+
|
|
def test_get_base_vg_name():
|
|
"""Check generated base volume group name against the expected base name"""
|
|
- assert lvm_gensym.get_vg_name_base('hostname', 'rhel') == 'rhel_hostname'
|
|
+ assert lvm_gensym.get_vg_name_base("hostname", "rhel") == "rhel_hostname"
|
|
+
|
|
|
|
@pytest.mark.parametrize("os_name", ["foo", "bar", "baz"])
|
|
def test_vg_eval(monkeypatch, os_name):
|
|
"""Check generated unique volume group name against the expected name"""
|
|
+
|
|
def get_os_name():
|
|
return os_name
|
|
|
|
vg_names = [os_name + "_user", os_name + "_user_0", os_name + "_user_1"]
|
|
_lvm_facts = dict(vgs=dict.fromkeys(vg_names), lvs=dict())
|
|
monkeypatch.setattr(lvm_gensym, "get_os_name", get_os_name)
|
|
- assert lvm_gensym.get_vg_name('user', _lvm_facts) == os_name + '_user_2'
|
|
- assert lvm_gensym.get_vg_name('', _lvm_facts) == os_name
|
|
+ assert lvm_gensym.get_vg_name("user", _lvm_facts) == os_name + "_user_2"
|
|
+ assert lvm_gensym.get_vg_name("", _lvm_facts) == os_name
|
|
+
|
|
|
|
def test_lv_eval():
|
|
"""Test the generated unique logical volume name against the expected name"""
|
|
- expected = ['root_1', 'home_user', 'swap_2']
|
|
+ expected = ["root_1", "home_user", "swap_2"]
|
|
|
|
for (ctr, name_inputs) in enumerate(test_lv_names):
|
|
- assert lvm_gensym.get_lv_name(name_inputs['fs_type'], name_inputs['mount'], lvm_facts) == expected[ctr]
|
|
+ assert (
|
|
+ lvm_gensym.get_lv_name(
|
|
+ name_inputs["fs_type"], name_inputs["mount"], lvm_facts
|
|
+ )
|
|
+ == expected[ctr]
|
|
+ )
|
|
+
|
|
|
|
def test_get_base_lv_name():
|
|
"""Test the generated base logical volume name against the expected name"""
|
|
- expected = ['root', 'home_user', 'swap']
|
|
+ expected = ["root", "home_user", "swap"]
|
|
|
|
for (ctr, names_input) in enumerate(test_lv_names):
|
|
- assert lvm_gensym.get_lv_name_base(names_input['fs_type'], names_input['mount']) == expected[ctr]
|
|
+ assert (
|
|
+ lvm_gensym.get_lv_name_base(names_input["fs_type"], names_input["mount"])
|
|
+ == expected[ctr]
|
|
+ )
|
|
diff --git a/tests/unit/resolve_blockdev_test.py b/tests/unit/resolve_blockdev_test.py
|
|
index 0eafe7b..ad50628 100644
|
|
--- a/tests/unit/resolve_blockdev_test.py
|
|
+++ b/tests/unit/resolve_blockdev_test.py
|
|
@@ -1,3 +1,6 @@
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
|
|
import os
|
|
import pytest
|
|
@@ -5,73 +8,80 @@ import pytest
|
|
import resolve_blockdev
|
|
|
|
|
|
-blkid_data = [('LABEL=target', '/dev/sdx3'),
|
|
- ('UUID=6c75fa75-e5ab-4a12-a567-c8aa0b4b60a5', '/dev/sdaz'),
|
|
- ('LABEL=missing', '')]
|
|
+blkid_data = [
|
|
+ ("LABEL=target", "/dev/sdx3"),
|
|
+ ("UUID=6c75fa75-e5ab-4a12-a567-c8aa0b4b60a5", "/dev/sdaz"),
|
|
+ ("LABEL=missing", ""),
|
|
+]
|
|
|
|
-path_data = ['/dev/md/unreal',
|
|
- '/dev/mapper/fakevg-fakelv',
|
|
- '/dev/adisk',
|
|
- '/dev/disk/by-id/wwn-0x123456789abc']
|
|
+path_data = [
|
|
+ "/dev/md/unreal",
|
|
+ "/dev/mapper/fakevg-fakelv",
|
|
+ "/dev/adisk",
|
|
+ "/dev/disk/by-id/wwn-0x123456789abc",
|
|
+]
|
|
|
|
-canonical_paths = {"/dev/sda": "/dev/sda",
|
|
- "/dev/dm-3": "/dev/mapper/vg_system-lv_data",
|
|
- "/dev/md127": "/dev/md/userdb",
|
|
- "/dev/notfound": ""}
|
|
+canonical_paths = {
|
|
+ "/dev/sda": "/dev/sda",
|
|
+ "/dev/dm-3": "/dev/mapper/vg_system-lv_data",
|
|
+ "/dev/md127": "/dev/md/userdb",
|
|
+ "/dev/notfound": "",
|
|
+}
|
|
|
|
|
|
-@pytest.mark.parametrize('spec,device', blkid_data)
|
|
+@pytest.mark.parametrize("spec,device", blkid_data)
|
|
def test_key_value_pair(spec, device, monkeypatch):
|
|
def run_cmd(args):
|
|
for _spec, _dev in blkid_data:
|
|
if _spec in args:
|
|
break
|
|
else:
|
|
- _dev = ''
|
|
- return (0, _dev, '')
|
|
+ _dev = ""
|
|
+ return (0, _dev, "")
|
|
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: True)
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: True)
|
|
assert resolve_blockdev.resolve_blockdev(spec, run_cmd) == device
|
|
|
|
|
|
-@pytest.mark.parametrize('name', [os.path.basename(p) for p in path_data])
|
|
+@pytest.mark.parametrize("name", [os.path.basename(p) for p in path_data])
|
|
def test_device_names(name, monkeypatch):
|
|
""" Test return values for basename specs, assuming all paths are real. """
|
|
+
|
|
def path_exists(path):
|
|
return next((data for data in path_data if data == path), False)
|
|
|
|
- expected = next((data for data in path_data if os.path.basename(data) == name), '')
|
|
- monkeypatch.setattr(os.path, 'exists', path_exists)
|
|
+ expected = next((data for data in path_data if os.path.basename(data) == name), "")
|
|
+ monkeypatch.setattr(os.path, "exists", path_exists)
|
|
assert resolve_blockdev.resolve_blockdev(name, None) == expected
|
|
|
|
|
|
def test_device_name(monkeypatch):
|
|
- assert os.path.exists('/dev/xxx') is False
|
|
+ assert os.path.exists("/dev/xxx") is False
|
|
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: True)
|
|
- assert resolve_blockdev.resolve_blockdev('xxx', None) == '/dev/xxx'
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: True)
|
|
+ assert resolve_blockdev.resolve_blockdev("xxx", None) == "/dev/xxx"
|
|
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: False)
|
|
- assert resolve_blockdev.resolve_blockdev('xxx', None) == ''
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: False)
|
|
+ assert resolve_blockdev.resolve_blockdev("xxx", None) == ""
|
|
|
|
|
|
def test_full_path(monkeypatch):
|
|
path = "/dev/idonotexist"
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: True)
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: True)
|
|
assert resolve_blockdev.resolve_blockdev(path, None) == path
|
|
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: False)
|
|
- assert resolve_blockdev.resolve_blockdev(path, None) == ''
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: False)
|
|
+ assert resolve_blockdev.resolve_blockdev(path, None) == ""
|
|
|
|
path = "/dev/disk/by-label/alabel"
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: True)
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: True)
|
|
assert resolve_blockdev.resolve_blockdev(path, None) == path
|
|
|
|
- monkeypatch.setattr(os.path, 'exists', lambda p: False)
|
|
- assert resolve_blockdev.resolve_blockdev(path, None) == ''
|
|
+ monkeypatch.setattr(os.path, "exists", lambda p: False)
|
|
+ assert resolve_blockdev.resolve_blockdev(path, None) == ""
|
|
|
|
|
|
-@pytest.mark.parametrize('device', list(canonical_paths.keys()))
|
|
+@pytest.mark.parametrize("device", list(canonical_paths.keys()))
|
|
def test_canonical_path(device, monkeypatch):
|
|
def _get_name(device):
|
|
name = os.path.basename(canonical_paths[device])
|
|
@@ -79,8 +89,8 @@ def test_canonical_path(device, monkeypatch):
|
|
raise Exception("failed to find name")
|
|
return name
|
|
|
|
- monkeypatch.setattr(resolve_blockdev, '_get_dm_name_from_kernel_dev', _get_name)
|
|
- monkeypatch.setattr(resolve_blockdev, '_get_md_name_from_kernel_dev', _get_name)
|
|
+ monkeypatch.setattr(resolve_blockdev, "_get_dm_name_from_kernel_dev", _get_name)
|
|
+ monkeypatch.setattr(resolve_blockdev, "_get_md_name_from_kernel_dev", _get_name)
|
|
|
|
canonical = canonical_paths[device]
|
|
if canonical:
|
|
diff --git a/tests/unit/test_unused_disk.py b/tests/unit/test_unused_disk.py
|
|
index a4339c4..493b4b0 100644
|
|
--- a/tests/unit/test_unused_disk.py
|
|
+++ b/tests/unit/test_unused_disk.py
|
|
@@ -1,72 +1,91 @@
|
|
+from __future__ import absolute_import, division, print_function
|
|
+
|
|
+__metaclass__ = type
|
|
+
|
|
import pytest
|
|
import find_unused_disk
|
|
import os
|
|
|
|
|
|
-blkid_data_pttype = [('/dev/sdx', '/dev/sdx: PTTYPE=\"dos\"'),
|
|
- ('/dev/sdy', '/dev/sdy: PTTYPE=\"test\"')]
|
|
+blkid_data_pttype = [
|
|
+ ("/dev/sdx", '/dev/sdx: PTTYPE="dos"'),
|
|
+ ("/dev/sdy", '/dev/sdy: PTTYPE="test"'),
|
|
+]
|
|
|
|
-blkid_data = [('/dev/sdx', 'UUID=\"hello-1234-56789\" TYPE=\"crypto_LUKS\"'),
|
|
- ('/dev/sdy', 'UUID=\"this-1s-a-t3st-f0r-ansible\" VERSION=\"LVM2 001\" TYPE=\"LVM2_member\" USAGE=\"raid\"'),
|
|
- ('/dev/sdz', 'LABEL=\"/data\" UUID=\"a12bcdef-345g-67h8-90i1-234j56789k10\" VERSION=\"1.0\" TYPE=\"ext4\" USAGE=\"filesystem\"')]
|
|
+blkid_data = [
|
|
+ ("/dev/sdx", 'UUID="hello-1234-56789" TYPE="crypto_LUKS"'),
|
|
+ (
|
|
+ "/dev/sdy",
|
|
+ 'UUID="this-1s-a-t3st-f0r-ansible" VERSION="LVM2 001" TYPE="LVM2_member" USAGE="raid"',
|
|
+ ),
|
|
+ (
|
|
+ "/dev/sdz",
|
|
+ 'LABEL="/data" UUID="a12bcdef-345g-67h8-90i1-234j56789k10" VERSION="1.0" TYPE="ext4" USAGE="filesystem"',
|
|
+ ),
|
|
+]
|
|
|
|
-holders_data_none = [('/dev/sdx', ''),
|
|
- ('/dev/dm-99', '')]
|
|
+holders_data_none = [("/dev/sdx", ""), ("/dev/dm-99", "")]
|
|
|
|
-holders_data = [('/dev/sdx', 'dm-0'),
|
|
- ('/dev/dm-99', 'dm-2 dm-3 dm-4')]
|
|
+holders_data = [("/dev/sdx", "dm-0"), ("/dev/dm-99", "dm-2 dm-3 dm-4")]
|
|
|
|
|
|
-@pytest.mark.parametrize('disk, blkid', blkid_data_pttype)
|
|
+@pytest.mark.parametrize("disk, blkid", blkid_data_pttype)
|
|
def test_no_signature_true(disk, blkid):
|
|
def run_command(args):
|
|
- return [0, blkid, '']
|
|
+ return [0, blkid, ""]
|
|
+
|
|
assert find_unused_disk.no_signature(run_command, disk) is True
|
|
|
|
|
|
-@pytest.mark.parametrize('disk, blkid', blkid_data)
|
|
+@pytest.mark.parametrize("disk, blkid", blkid_data)
|
|
def test_no_signature_false(disk, blkid):
|
|
def run_command(args):
|
|
- return [0, blkid, '']
|
|
+ return [0, blkid, ""]
|
|
+
|
|
assert find_unused_disk.no_signature(run_command, disk) is False
|
|
|
|
|
|
-@pytest.mark.parametrize('disk, holders', holders_data_none)
|
|
+@pytest.mark.parametrize("disk, holders", holders_data_none)
|
|
def test_no_holders_true(disk, holders, monkeypatch):
|
|
def mock_return(args):
|
|
return holders
|
|
- monkeypatch.setattr(os, 'listdir', mock_return)
|
|
+
|
|
+ monkeypatch.setattr(os, "listdir", mock_return)
|
|
assert find_unused_disk.no_holders(disk) is True
|
|
|
|
|
|
-@pytest.mark.parametrize('disk, holders', holders_data)
|
|
+@pytest.mark.parametrize("disk, holders", holders_data)
|
|
def test_no_holders_false(disk, holders, monkeypatch):
|
|
def mock_return(args):
|
|
return holders
|
|
- monkeypatch.setattr(os, 'listdir', mock_return)
|
|
+
|
|
+ monkeypatch.setattr(os, "listdir", mock_return)
|
|
assert find_unused_disk.no_holders(disk) is False
|
|
|
|
|
|
def test_can_open_true(monkeypatch):
|
|
def mock_return(args, flag):
|
|
return True
|
|
- monkeypatch.setattr(os, 'open', mock_return)
|
|
- assert find_unused_disk.can_open('/hello') is True
|
|
+
|
|
+ monkeypatch.setattr(os, "open", mock_return)
|
|
+ assert find_unused_disk.can_open("/hello") is True
|
|
|
|
|
|
def test_can_open_false(monkeypatch):
|
|
def mock_return(args, flag):
|
|
raise OSError
|
|
- monkeypatch.setattr(os, 'open', mock_return)
|
|
- assert find_unused_disk.can_open('/hello') is False
|
|
+
|
|
+ monkeypatch.setattr(os, "open", mock_return)
|
|
+ assert find_unused_disk.can_open("/hello") is False
|
|
|
|
|
|
def test_is_ignored(monkeypatch):
|
|
def mock_realpath(path):
|
|
return path
|
|
- monkeypatch.setattr(os.path, 'realpath', mock_realpath)
|
|
- assert find_unused_disk.is_ignored('/dev/sda') is False
|
|
- assert find_unused_disk.is_ignored('/dev/vda') is False
|
|
- assert find_unused_disk.is_ignored('/dev/mapper/mpatha') is False
|
|
- assert find_unused_disk.is_ignored('/dev/md/Volume0') is False
|
|
- assert find_unused_disk.is_ignored('/dev/nullb0') is True
|
|
+
|
|
+ monkeypatch.setattr(os.path, "realpath", mock_realpath)
|
|
+ assert find_unused_disk.is_ignored("/dev/sda") is False
|
|
+ assert find_unused_disk.is_ignored("/dev/vda") is False
|
|
+ assert find_unused_disk.is_ignored("/dev/mapper/mpatha") is False
|
|
+ assert find_unused_disk.is_ignored("/dev/md/Volume0") is False
|
|
+ assert find_unused_disk.is_ignored("/dev/nullb0") is True
|
|
diff --git a/tox.ini b/tox.ini
|
|
index 92482d5..91c22a8 100644
|
|
--- a/tox.ini
|
|
+++ b/tox.ini
|
|
@@ -13,9 +13,3 @@ configfile = .ansible-lint
|
|
setenv =
|
|
RUN_PYTEST_SETUP_MODULE_UTILS = true
|
|
RUN_PYLINT_SETUP_MODULE_UTILS = true
|
|
-
|
|
-[testenv:black]
|
|
-commands = bash -c 'echo black is currently not enabled - please fix this'
|
|
-
|
|
-[testenv:flake8]
|
|
-commands = bash -c 'echo flake8 is currently not enabled - please fix this'
|
|
--
|
|
2.30.2
|
|
|