diff --git a/aif.xsd b/aif.xsd
index 2a01ea0..2b2327c 100644
--- a/aif.xsd
+++ b/aif.xsd
@@ -408,39 +408,102 @@
+
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
-
+
@@ -474,6 +537,14 @@
+
+
+
+
+
+
+
+
diff --git a/aif/disk/block.py b/aif/disk/block.py
index 7e46303..15357e7 100644
--- a/aif/disk/block.py
+++ b/aif/disk/block.py
@@ -20,6 +20,8 @@ import psutil
##
from aif.utils import xmlBool, size
+# TODO: https://serverfault.com/questions/356534/ssd-erase-block-size-lvm-pv-on-raw-device-alignment
+
PARTED_FSTYPES = sorted(list(dict(vars(parted.filesystem))['fileSystemType'].keys()))
PARTED_FLAGS = sorted(list(parted.partition.partitionFlag.values()))
diff --git a/aif/disk/filesystem.py b/aif/disk/filesystem.py
index 91c8298..0e58c19 100644
--- a/aif/disk/filesystem.py
+++ b/aif/disk/filesystem.py
@@ -6,7 +6,7 @@ import psutil
##
from aif.disk.block import Partition
from aif.disk.luks import LUKS
-from aif.disk.lvm import Group as LVMGroup
+from aif.disk.lvm import LV as LVMVolume
from aif.disk.mdadm import Array as MDArray
# I wish there was a better way of doing this.
@@ -44,11 +44,11 @@ for i in os.listdir(_mod_dir):
class FS(object):
def __init__(self, fs_xml, sourceobj):
self.xml = fs_xml
- if not isinstance(sourceobj, (Partition, LUKS, LVMGroup, MDArray)):
+ if not isinstance(sourceobj, (Partition, LUKS, LVMVolume, MDArray)):
raise ValueError(('sourceobj must be of type '
'aif.disk.block.Partition, '
'aif.disk.luks.LUKS, '
- 'aif.disk.lvm.Group, or'
+ 'aif.disk.lvm.LV, or'
'aif.disk.mdadm.Array'))
self.source = sourceobj
self.devpath = sourceobj.devpath
diff --git a/aif/disk/luks.py b/aif/disk/luks.py
index e3d6d06..946ea73 100644
--- a/aif/disk/luks.py
+++ b/aif/disk/luks.py
@@ -1,4 +1,8 @@
+from aif.disk.block import Disk, Partition
+from aif.disk.lvm import LV
+from aif.disk.mdadm import Array
+
class LUKS(object):
- def __init__(self):
+ def __init__(self, partobj):
self.devpath = None
pass
diff --git a/aif/disk/lvm.py b/aif/disk/lvm.py
index 6f03d1a..fac8f74 100644
--- a/aif/disk/lvm.py
+++ b/aif/disk/lvm.py
@@ -1,13 +1,29 @@
+try:
+ import dbus
+ has_mod = True
+except ImportError:
+ # This is ineffecient; the native dbus module is preferred.
+ # In Arch, this can be installed via the 'extra' repository package "python-dbus".
+ import subprocess
+ has_mod = False
+##
+from aif.disk.block import Disk, Partition
+from aif.disk.luks import LUKS
+from aif.disk.mdadm import Array
+
+
class PV(object):
def __init__(self, partobj):
self.devpath = None
pass
-class LV(object):
- def __init__(self, lv_xml, pv_objs):
- pass
-class Group(object):
+class VG(object):
def __init__(self, vg_xml, lv_objs):
self.devpath = None
pass
+
+
+class LV(object):
+ def __init__(self, lv_xml, pv_objs):
+ pass
diff --git a/aif/disk/mdadm.py b/aif/disk/mdadm.py
index 72a76d8..3623e9f 100644
--- a/aif/disk/mdadm.py
+++ b/aif/disk/mdadm.py
@@ -7,8 +7,9 @@ import uuid
##
import mdstat
##
-from aif.disk.block import Disk
-from aif.disk.block import Partition
+from aif.disk.block import Disk, Partition
+from aif.disk.luks import LUKS
+from aif.disk.lvm import LV
SUPPORTED_LEVELS = (0, 1, 4, 5, 6, 10)
@@ -173,8 +174,10 @@ class Array(object):
self.devname = self.xml.attrib['name']
self.devpath = devpath
self.updateStatus()
+ self.homehost = homehost
self.members = []
self.state = None
+ self.info = None
def addMember(self, memberobj):
if not isinstance(memberobj, Member):
@@ -183,20 +186,18 @@ class Array(object):
self.members.append(memberobj)
return()
- def assemble(self, scan = False):
+ def start(self, scan = False):
if not any((self.members, self.devpath)):
raise RuntimeError('Cannot assemble an array with no members (for hints) or device path')
-
cmd = ['mdadm', '--assemble', self.devpath]
if not scan:
for m in self.members:
cmd.append(m.devpath)
else:
- cmd.extend([''])
+ cmd.append('--scan')
# TODO: logging!
subprocess.run(cmd)
-
- pass
+ self.state = 'assembled'
return()
def create(self):
@@ -206,6 +207,7 @@ class Array(object):
'--level={0}'.format(self.level),
'--metadata={0}'.format(self.metadata),
'--chunk={0}'.format(self.chunksize),
+ '--homehost={0}'.format(self.homehost),
'--raid-devices={0}'.format(len(self.members))]
if self.layout:
cmd.append('--layout={0}'.format(self.layout))
@@ -214,13 +216,14 @@ class Array(object):
cmd.append(m.devpath)
# TODO: logging!
subprocess.run(cmd)
-
- pass
+ self.writeConf()
+ self.state = 'new'
return()
def stop(self):
# TODO: logging
subprocess.run(['mdadm', '--stop', self.devpath])
+ self.state = 'disassembled'
return()
def updateStatus(self):
@@ -232,4 +235,22 @@ class Array(object):
return()
def writeConf(self, conf = '/etc/mdadm.conf'):
- pass
+ with open(conf, 'r') as fh:
+ conflines = fh.read().splitlines()
+ # TODO: logging
+ arrayinfo = subprocess.run(['mdadm', '--detail', '--brief', self.devpath],
+ stdout = subprocess.PIPE).stdout.decode('utf-8').strip()
+ if arrayinfo not in conflines:
+ r = re.compile(r'^ARRAY\s+{0}'.format(self.devpath))
+ nodev = True
+ for l in conflines:
+ if r.search(l):
+ nodev = False
+ # TODO: logging?
+ # and/or Raise an exception here;
+ # an array already exists with that name but not with the same opts/GUID/etc.
+ break
+ if nodev:
+ with open(conf, 'a') as fh:
+ fh.write('{0}\n'.format(arrayinfo))
+ return()
diff --git a/examples/aif.xml b/examples/aif.xml
index 43f25fc..920859d 100644
--- a/examples/aif.xml
+++ b/examples/aif.xml
@@ -55,9 +55,20 @@
-
-
-
+
+
+
+
+
+
+
+ data
+
+
+
+
+
+