Add custom layout partitioning
* In case of 'non-clean' partitioning, we may stuck in 400 error from MAAS
The RC of such issue, that we trying to apply totally custom schema, to
any auto-predefined(or not cleaned previosly)
* Add new layout: custom - which means, drop everything befere start part.
* Misc: remove broken and unused func `create_partition_filesystem`
Closes-Bug: PROD-20317 (PROD:20317)
Change-Id: I574c669616b9318b8ecafaf9c8ad4162c01b44e1
diff --git a/_modules/maasng.py b/_modules/maasng.py
index 65ffc84..8e4d1f2 100644
--- a/_modules/maasng.py
+++ b/_modules/maasng.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-'''
+"""
Module for handling maas calls.
:optdepends: pyapi-maas Python adapter
@@ -9,7 +9,7 @@
maas.url: 'https://maas.domain.com/'
maas.token: fdsfdsdsdsfa:fsdfae3fassd:fdsfdsfsafasdfsa
-'''
+"""
from __future__ import absolute_import
@@ -50,10 +50,10 @@
def __virtual__():
- '''
+ """
Only load this module if maas-client
is installed on this minion.
- '''
+ """
if HAS_MASS:
return 'maasng'
return False
@@ -95,6 +95,15 @@
return list_volume_groups(hostname)[device]["id"]
+def _get_volume_id_by_name(hostname, volume_name, volume_group, maas_volname=True):
+
+ if not maas_volname:
+ # MAAS-like name
+ volume_name = str("%s-%s" % (volume_group,volume_name))
+ ##TODO validation
+ return get_volumes(hostname, volume_group)[volume_name]["id"]
+
+
def _get_partition_id_by_name(hostname, device, partition):
# TODO validation
@@ -104,7 +113,7 @@
def get_machine(hostname):
- '''
+ """
Get information aboout specified machine
CLI Example:
@@ -112,7 +121,7 @@
.. code-block:: bash
salt-call maasng.get_machine server_hostname
- '''
+ """
try:
return list_machines()[hostname]
except KeyError:
@@ -120,7 +129,7 @@
def list_machines():
- '''
+ """
Get list of all machines from maas server
CLI Example:
@@ -128,7 +137,7 @@
.. code-block:: bash
salt 'maas-node' maasng.list_machines
- '''
+ """
machines = {}
maas = _create_maas_client()
json_res = json.loads(maas.get(u'api/2.0/machines/').read())
@@ -148,14 +157,12 @@
return False
-# MACHINE OPERATIONS
-# TODO
-
+# END MACHINE SECTION
# RAID SECTION
def create_raid(hostname, name, level, disks=[], partitions=[], **kwargs):
- '''
+ """
Create new raid on machine.
CLI Example:
@@ -163,7 +170,7 @@
.. code-block:: bash
salt-call maasng.create_raid hostname=kvm03 name=md0 level=1 disks=[vdb,vdc] partitions=[vdd-part1,vde-part1]
- '''
+ """
result = {}
@@ -213,7 +220,7 @@
def list_raids(hostname):
- '''
+ """
Get list all raids on machine
CLI Example:
@@ -221,22 +228,21 @@
.. code-block:: bash
salt-call maasng.list_raids server_hostname
- '''
+ """
+ raids = {}
maas = _create_maas_client()
system_id = get_machine(hostname)["system_id"]
- LOG.info(system_id)
- # TODO validation
- json_res = json.loads(
- maas.get(u"api/2.0/nodes/{0}/raids/".format(system_id)).read())
- LOG.info(json_res)
-
- # TODO return list of raid devices
- return True
+ #TODO validation
+ json_res = json.loads(maas.get(u"api/2.0/nodes/{0}/raids/".format(system_id)).read())
+ LOG.debug('list_raids:{} {}'.format(system_id, json_res))
+ for item in json_res:
+ raids[item["name"]] = item
+ return raids
def get_raid(hostname, name):
- '''
+ """
Get information about specific raid on machine
CLI Example:
@@ -244,15 +250,42 @@
.. code-block:: bash
salt-call maasng.get_raids server_hostname md0
- '''
+ """
return list_raids(hostname)[name]
+def _get_raid_id_by_name(hostname, raid_name):
+ return get_raid(hostname, raid_name)['id']
+
+
+def delete_raid(hostname, raid_name):
+ """
+ Delete RAID on a machine.
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'maas-node' maasng.delete_raid server_hostname raid_name
+ salt-call maasng.delete_raid server_hostname raid_name
+ """
+ result = {}
+ maas=_create_maas_client()
+ system_id = get_machine(hostname)["system_id"]
+ raid_id = _get_raid_id_by_name(hostname, raid_name)
+ LOG.debug('delete_raid: {} {}'.format(system_id,raid_id))
+ maas.delete(u"api/2.0/nodes/{0}/raid/{1}/".format(system_id, raid_id)).read()
+
+ result["new"] = "Raid {0} deleted".format(raid_name)
+ return result
+
+# END RAID SECTION
# BLOCKDEVICES SECTION
+
def list_blockdevices(hostname):
- '''
+ """
Get list of all blockdevices (disks) on machine
CLI Example:
@@ -261,7 +294,7 @@
salt 'maas-node' maasng.list_blockdevices server_hostname
salt-call maasng.list_blockdevices server_hostname
- '''
+ """
ret = {}
maas = _create_maas_client()
@@ -280,7 +313,7 @@
def get_blockdevice(hostname, name):
- '''
+ """
Get information about blockdevice (disk) on machine
CLI Example:
@@ -289,15 +322,16 @@
salt 'maas-node' maasng.get_blockdevice server_hostname sda
salt-call maasng.get_blockdevice server_hostname sda
- '''
+ """
return list_blockdevices(hostname)[name]
-
+# END BLOCKDEVICES SECTION
# PARTITIONS
+
def list_partitions(hostname, device):
- '''
+ """
Get list of all partitions on specific device located on specific machine
CLI Example:
@@ -306,7 +340,7 @@
salt 'maas-node' maasng.list_partitions server_hostname sda
salt-call maasng.list_partitions server_hostname sda
- '''
+ """
ret = {}
maas = _create_maas_client()
system_id = get_machine(hostname)["system_id"]
@@ -327,7 +361,7 @@
def get_partition(hostname, device, partition):
- '''
+ """
Get information about specific parition on device located on machine
CLI Example:
@@ -338,13 +372,13 @@
salt-call maasng.get_partition server_hostname disk_name partition
root_size = size in GB
- '''
+ """
return list_partitions(partition)[name]
def create_partition(hostname, disk, size, fs_type=None, mount=None):
- '''
+ """
Create new partition on device.
CLI Example:
@@ -353,7 +387,7 @@
salt 'maas-node' maasng.create_partition server_hostname disk_name 10 ext4 "/"
salt-call maasng.create_partition server_hostname disk_name 10 ext4 "/"
- '''
+ """
# TODO validation
result = {}
maas = _create_maas_client()
@@ -404,7 +438,7 @@
def delete_partition(hostname, disk, partition_name):
- '''
+ """
Delete partition on device.
CLI Example:
@@ -415,7 +449,7 @@
salt-call maasng.delete_partition server_hostname disk_name partition_name
root_size = size in GB
- '''
+ """
result = {}
data = {}
maas = _create_maas_client()
@@ -434,7 +468,7 @@
def delete_partition_by_id(hostname, disk, partition_id):
- '''
+ """
Delete partition on device. Partition spefified by id of parition
CLI Example:
@@ -445,7 +479,7 @@
salt-call maasng.delete_partition_by_id server_hostname disk_name partition_id
root_size = size in GB
- '''
+ """
result = {}
data = {}
maas = _create_maas_client()
@@ -459,13 +493,41 @@
system_id, device_id, partition_id)).read()
result["new"] = "Partition {0} deleted".format(partition_id)
return result
+# END PARTITIONS
+# DISK LAYOUT
-# CREATE DISK LAYOUT
-# TODO
+
+def drop_storage_schema(hostname,disk=None):
+ """
+ #1. Drop lv
+ #2. Drop vg
+ #3. Drop md # need to zero-block?
+ #3. Drop part
+ """
+
+ if __opts__['test']:
+ ret['result'] = None
+ ret['comment'] = 'Storage schema on {0} will be removed'.format(hostname)
+ return ret
+ #TODO validation if exists
+ vgs = list_volume_groups(hostname)
+ for vg in vgs:
+ delete_volume_group(hostname, vg)
+
+ raids = list_raids(hostname)
+ for raid in raids:
+ delete_raid(hostname, raid)
+
+ blocks = list_blockdevices(hostname)
+ for block_d in blocks:
+ partitions = __salt__['maasng.list_partitions'](hostname, block_d)
+ for partition_name, partition in partitions.iteritems():
+ LOG.info('delete partition:\n{}'.format(partition))
+ __salt__['maasng.delete_partition_by_id'](hostname, block_d, partition["id"])
def update_disk_layout(hostname, layout, root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None):
- '''
+ """
Update disk layout. Flat or LVM layout supported.
CLI Example:
@@ -476,7 +538,7 @@
salt-call maasng.update_disk_layout server_hostname lvm root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None
root_size = size in GB
- '''
+ """
result = {}
data = {
"storage_layout": layout,
@@ -486,6 +548,14 @@
system_id = get_machine(hostname)["system_id"]
LOG.info(system_id)
+ if layout == 'custom':
+ drop_storage_schema(hostname)
+ result["new"] = {
+ "storage_layout": layout,
+ }
+
+ return result
+
if root_size != None:
bit_size = str(root_size * 1073741824)
LOG.info(bit_size)
@@ -518,12 +588,11 @@
return result
-
+# END DISK LAYOUT
# LVM
-# TODO
def list_volume_groups(hostname):
- '''
+ """
Get list of all volume group on machine.
CLI Example:
@@ -532,7 +601,7 @@
salt 'maas-node' maasng.list_volume_groups server_hostname
salt-call maasng.list_volume_groups server_hostname
- '''
+ """
volume_groups = {}
maas = _create_maas_client()
@@ -551,7 +620,7 @@
def get_volume_group(hostname, name):
- '''
+ """
Get information about specific volume group on machine.
CLI Example:
@@ -560,13 +629,13 @@
salt 'maas-node' maasng.list_blockdevices server_hostname
salt-call maasng.list_blockdevices server_hostname
- '''
+ """
# TODO validation that exists
return list_volume_groups(hostname)[name]
def create_volume_group(hostname, volume_group_name, disks=[], partitions=[]):
- '''
+ """
Create new volume group on machine. Disks or partitions needs to be provided.
CLI Example:
@@ -575,7 +644,7 @@
salt 'maas-node' maasng.create_volume_group volume_group_name, disks=[sda,sdb], partitions=[]
salt-call maasng.create_volume_group server_hostname
- '''
+ """
result = {}
data = {
@@ -623,7 +692,7 @@
def delete_volume_group(hostname, name):
- '''
+ """
Delete volume group on machine.
CLI Example:
@@ -632,30 +701,25 @@
salt 'maas-node' maasng.delete_volume_group server_hostname vg0
salt-call maasng.delete_volume_group server_hostname vg0
- '''
+ """
maas = _create_maas_client()
system_id = get_machine(hostname)["system_id"]
- LOG.info(system_id)
+ LOG.debug('delete_volume_group:{}'.format(system_id))
- # TODO partitions
- # for partition in partitions:
- # temp = disk.split("-")
- # disk_ids.append(str(_get_blockdevice_id_by_name(hostname, temp[] partition)))
+ vg_id = str(_get_volume_group_id_by_name(hostname, name))
+ for vol in get_volumes(hostname, name):
+ delete_volume(hostname,vol,name)
- # TODO partitions
- vg_id = name
-
- # TODO validation
- json_res = json.loads(maas.delete(
- u"api/2.0/nodes/{0}/volume-group/{1}/".format(system_id, vg_id)).read())
+ #TODO validation
+ json_res = json.loads(maas.delete(u"api/2.0/nodes/{0}/volume-group/{1}/".format(system_id, vg_id)).read() or 'null')
LOG.info(json_res)
return True
def create_volume(hostname, volume_name, volume_group, size, fs_type=None, mount=None):
- '''
+ """
Create volume on volume group.
CLI Example:
@@ -664,7 +728,7 @@
salt 'maas-node' maasng.create_volume server_hostname volume_name, volume_group, size, fs_type=None, mount=None
salt-call maasng.create_volume server_hostname volume_name, volume_group, size, fs_type=None, mount=None
- '''
+ """
data = {
"name": volume_name,
@@ -690,12 +754,59 @@
LOG.info(json_res)
if fs_type != None or mount != None:
- ret = create_volume_filesystem(
- hostname, volume_group + "-" + volume_name, fs_type, mount)
+ ret = create_volume_filesystem(hostname, volume_group + "-" + volume_name, fs_type, mount)
return True
+def delete_volume(hostname, volume_name, volume_group):
+ """
+ Delete volume from volume group.
+ Tips: maas always use 'volume_group-volume_name' name schema.Example: 'vg0-glusterfs'
+ This function expexts same format.
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'maas-node' maasng.delete_volume server_hostname volume_name volume_group
+ salt 'maas-node' maasng.delete_volume server_hostname vg0-vol0 vg0
+ salt-call maasng.delete_volume server_hostname volume_name volume_group
+ """
+
+ maas=_create_maas_client()
+ system_id = get_machine(hostname)["system_id"]
+ LOG.debug('delete_volume:{}'.format(system_id))
+
+ volume_group_id = str(_get_volume_group_id_by_name(hostname, volume_group))
+ volume_id = str(_get_volume_id_by_name(hostname, volume_name, volume_group))
+
+ if None in [volume_group_id, volume_id]:
+ return False
+
+ data = {
+ "id": volume_id,
+ }
+
+ #TODO validation
+ json_res = json.loads(maas.post(u"api/2.0/nodes/{0}/volume-group/{1}/".format(system_id, volume_group_id), "delete_logical_volume", **data).read() or 'null')
+ return True
+
+
+def get_volumes(hostname, vg_name):
+ """
+ Get list of volumes in volume group.
+ """
+ volumes = {}
+ _volumes = list_volume_groups(hostname)[vg_name].get('logical_volumes', False)
+ if _volumes:
+ for item in _volumes:
+ volumes[item["name"]] = item
+ return volumes
+
+# END LVM
+
+
def create_volume_filesystem(hostname, device, fs_type=None, mount=None):
maas = _create_maas_client()
@@ -720,32 +831,8 @@
return True
-def create_partition_filesystem(hostname, partition, fs_type=None, mount=None):
-
- maas = _create_maas_client()
- system_id = get_machine(hostname)["system_id"]
-
- blockdevices_id = _get_blockdevice_id_by_name(hostname, device)
- data = {}
- if fs_type != None:
- data["fstype"] = fs_type
- # TODO validation
- json_res = json.loads(maas.post(u"/api/2.0/nodes/{0}/blockdevices/{1}/".format(
- system_id, blockdevices_id), "format", **data).read())
- LOG.info(json_res)
-
- if mount != None:
- data["mount_point"] = mount
- # TODO validation
- json_res = json.loads(maas.post(u"/api/2.0/nodes/{0}/blockdevices/{1}/".format(
- system_id, blockdevices_id), "mount", **data).read())
- LOG.info(json_res)
-
- return True
-
-
def set_boot_disk(hostname, name):
- '''
+ """
Create volume on volume group.
CLI Example:
@@ -754,7 +841,7 @@
salt 'maas-node' maasng.set_boot_disk server_hostname disk_name
salt-call maasng.set_boot_disk server_hostname disk_name
- '''
+ """
data = {}
result = {}
maas = _create_maas_client()
@@ -768,9 +855,11 @@
return result
+# NETWORKING
+
def list_fabric():
- '''
+ """
Get list of all fabric
CLI Example:
@@ -778,7 +867,7 @@
.. code-block:: bash
salt 'maas-node' maasng.list_fabric
- '''
+ """
fabrics = {}
maas = _create_maas_client()
json_res = json.loads(maas.get(u'api/2.0/fabrics/').read())
@@ -789,7 +878,7 @@
def create_fabric(name):
- '''
+ """
Create new fabric.
CLI Example:
@@ -797,7 +886,7 @@
.. code-block:: bash
salt 'maas-node' maasng.create_fabric
- '''
+ """
result = {}
data = {
"name": name,
@@ -814,7 +903,7 @@
def list_subnet():
- '''
+ """
Get list of all subnets
CLI Example:
@@ -822,7 +911,7 @@
.. code-block:: bash
salt 'maas-node' maasng.list_subnet
- '''
+ """
subnets = {}
maas = _create_maas_client()
json_res = json.loads(maas.get(u'api/2.0/subnets/').read())
@@ -833,7 +922,7 @@
def list_vlans(fabric):
- '''
+ """
Get list of all vlans for specific fabric
CLI Example:
@@ -841,7 +930,7 @@
.. code-block:: bash
salt 'maas-node' maasng.list_vlans
- '''
+ """
vlans = {}
maas = _create_maas_client()
fabric_id = get_fabric(fabric)
@@ -855,7 +944,7 @@
def get_fabric(fabric):
- '''
+ """
Get id for specific fabric
CLI Example:
@@ -863,7 +952,7 @@
.. code-block:: bash
salt-call maasng.get_fabric fabric_name
- '''
+ """
try:
return list_fabric()[fabric]['id']
except KeyError:
@@ -871,7 +960,7 @@
def update_vlan(name, fabric, vid, description, primary_rack, dhcp_on=False):
- '''
+ """
Update vlan
CLI Example:
@@ -879,7 +968,7 @@
.. code-block:: bash
salt 'maas-node' maasng.update_vlan name, fabric, vid, description, dhcp_on
- '''
+ """
result = {}
data = {
@@ -897,3 +986,5 @@
result["new"] = "Vlan {0} was updated".format(json_res["name"])
return result
+
+# END NETWORKING