ironic-staging-drivers/ironic_staging_drivers/ansible/playbooks/library/parted.py

112 lines
4.2 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
PARTITION_TYPES = ('primary', 'logical', 'extended')
def construct_parted_args(device):
parted_args = [
'-s', device['device'],
]
if device['label']:
parted_args.extend(['mklabel', device['label']])
partitions = device['partitions']
if partitions:
parted_args.extend(['-a', 'optimal', '--', 'unit', 'MiB'])
start = 1
for ind, partition in enumerate(device['partitions']):
parted_args.extend([
'mkpart', partition['type']])
if partition['swap']:
parted_args.append('linux-swap')
end = start + partition['size_mib']
parted_args.extend(["%i" % start, "%i" % end])
start = end
if partition['boot']:
parted_args.extend([
'set', str(ind + 1), 'boot', 'on'])
return parted_args
def validate_partitions(module, partitions):
for ind, partition in enumerate(partitions):
# partition name might be an empty string
partition['name'] = partition.get('name') or str(ind + 1)
size = partition.get('size_mib', None)
if not size:
module.fail_json(msg="Partition size must be provided")
try:
partition['size_mib'] = int(size)
except ValueError:
module.fail_json(msg="Can not cast partition size to INT.")
partition.setdefault('type', 'primary')
if partition['type'] not in PARTITION_TYPES:
module.fail_json(msg="Partition type must be one of "
"%s." % PARTITION_TYPES)
partition['swap'] = module.boolean(partition.get('swap', False))
partition['boot'] = module.boolean(partition.get('boot', False))
if partition['boot'] and partition['swap']:
module.fail_json(msg="Can not set partition to "
"boot and swap simultaneously.")
# TODO(pas-ha) add more validation, e.g.
# - only one boot partition?
# - no more than 4 primary partitions on msdos table
# - no more that one extended partition on msdos table
# - estimate and validate available space
def main():
module = AnsibleModule(
argument_spec=dict(
device=dict(required=True, type='str'),
dryrun=dict(required=False, default=False, type='bool'),
new_label=dict(required=False, default=False, type='bool'),
label=dict(requred=False, default='msdos', choices=[
"bsd", "dvh", "gpt", "loop", "mac", "msdos", "pc98", "sun"]),
partitions=dict(
required=False, type='list')
),
supports_check_mode=True)
device = module.params['device']
dryrun = module.params['dryrun']
new_label = module.params['new_label']
label = module.params['label']
if not new_label:
label = False
partitions = module.params['partitions'] or []
try:
validate_partitions(module, partitions)
except Exception as e:
module.fail_json(msg="Malformed partitions arguments: %s" % e)
parted_args = construct_parted_args(dict(device=device, label=label,
partitions=partitions))
command = [module.get_bin_path('parted', required=True)]
if not (module.check_mode or dryrun):
command.extend(parted_args)
module.run_command(command, check_rc=True)
partitions_created = {p['name']: '%s%i' % (device, i + 1)
for i, p in enumerate(partitions)}
module.exit_json(changed=not dryrun, created=partitions_created)
from ansible.module_utils.basic import * # noqa
if __name__ == '__main__':
main()