To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit a6c35cca authored by Bengt Giger's avatar Bengt Giger
Browse files

Merge branch 'disk-management' into 'master'

Disk management

See merge request !3
parents 03c9dc46 9944171d
Pipeline #96770 passed with stages
in 9 minutes and 39 seconds
......@@ -10,6 +10,7 @@ variables:
DOCKER_TLS_CERTDIR: ""
stages:
- unittests
- tests
before_script:
......@@ -18,6 +19,26 @@ before_script:
- ansible --version
- molecule --version
# Test python plugins first
plugin-test:
stage: unittests
tags:
- k8s-runner
variables:
DOCKER_HOST: tcp://localhost:2375
script:
- pip3 install pytest;
cd plugins;
for dir in $(find . -name tests);
do cd $dir;
for test in $(ls test_*);
do python3 $test;
done;
done;
#only:
# changes:
# - plugins/**/*
# Test timeservice on dedicated gitlab-runner server
timeservice-test:
stage: tests
......@@ -121,3 +142,23 @@ base_packages-test:
changes:
- .gitlab-ci.yml
- roles/base_packages/**/*
# Test disk_management on VM's
disk_management-test:
stage: tests
tags:
- vagrant
before_script:
- sudo su root -c 'vagrant box add id-cd-vm-rh7-tmpl-anstest "http://idinstallprd.ethz.ch/img/vagrant/id-cd-vm-rh7-tmpl-anstest.box"'
- sudo su root -c 'vagrant box add id-cd-vm-rh8-tmpl-anstest "http://idinstallprd.ethz.ch/img/vagrant/id-cd-vm-rh8-tmpl-anstest.box"'
script:
- cd roles/disk_management
- sudo su root -c 'molecule test -s default'
- sudo su root -c 'molecule test -s delete_mount'
after_script:
- sudo su root -c 'vagrant box remove id-cd-vm-rh7-tmpl-anstest'
- sudo su root -c 'vagrant box remove id-cd-vm-rh8-tmpl-anstest'
only:
changes:
- .gitlab-ci.yml
- roles/disk_management/**/*
\ No newline at end of file
This diff is collapsed.
../partitioningFilter.py
\ No newline at end of file
import unittest, json, yaml
from partitioningFilter import FilterModule, Partitioning, VolumeGroup, LogicalVolume, PhysicalVolume
current_state = """
{
"lvs": {
"lv_root": {
"size_g": "17.44",
"vg": "VGROOT"
},
"lv_swap": {
"size_g": "2.00",
"vg": "VGROOT"
},
"lv_extra": {
"size_g": "2.3",
"vg": "VGRM"
},
"lv_ch1": {
"size_g": "14.5",
"vg": "VGEXT"
}
},
"pvs": {
"/dev/sda2": {
"free_g": "0",
"size_g": "9.47",
"vg": "VGROOT"
},
"/dev/sda3": {
"free_g": "0",
"size_g": "9.97",
"vg": "VGROOT"
},
"/dev/sda4": {
"free_g": "0",
"size_g": "9.97",
"vg": "VGRM"
},
"/dev/sda8": {
"free_g": "0",
"size_g": "14.5",
"vg": "VGEXT"
}
},
"vgs": {
"VGROOT": {
"free_g": "0",
"num_lvs": "2",
"num_pvs": "2",
"size_g": "19.44"
},
"VGRM": {
"free_g": "12.2",
"num_lvs": "1",
"num_pvs": "1",
"size_g": "14.5"
},
"VGEXT": {
"free_g": "0",
"num_lvs": "1",
"num_pvs": "1",
"size_g": "14.5"
}
}
}
"""
desired_state = """
- vg: VGROOT
lvs:
- lv_root:
fs: xfs
size_g: 17.44
mount: /
- lv_swap:
fs: swap
size_g: 2
pvs:
- /dev/sda2
- /dev/sda3
- vg: VGADD
lvs:
- lv_data:
fs: xfs
size_g: 5
mount: /data
pvs:
- /dev/sda6
- vg: VGEXT
lvs:
- lv_ch1:
fs: xfs
size_g: 14.5
mount: /ch1
- lv_ch2:
fs: xfs
size_g: 10
mount: /ch2
pvs:
- /dev/sda8
- /dev/sda9
- vg: VGUNKNOWN
lvs:
- lv_1:
fs: xfs
size_g: 10
mount: /d1
pvs:
- /dev/unknown
- vg: VGSMALL
lvs:
- lv_ch1:
fs: xfs
size_g: 14.5
mount: /ch1
- lv_ch2:
fs: xfs
size_g: 15.5
mount: /ch2
pvs:
- /dev/sda10
- /dev/sda11
"""
ansible_mounts = """
[
{
"fstype": "xfs",
"mount": "/",
"device": "/dev/mapper/VGROOT-lv_root"
},
{
"fstype": "xfs",
"mount": "/data",
"device": "/dev/mapper/VGRM-lv_extra"
},
{
"fstype": "xfs",
"mount": "/ch1",
"device": "/dev/mapper/VGEXT-lv_ch1"
},
{
"fstype": "xfs",
"mount": "/ch2",
"device": "/dev/mapper/VGEXT-lv_ch2"
},
{
"fstype": "xfs",
"mount": "/d1",
"device": "/dev/mapper/VGEXT-lv_d1"
}
]
"""
ansible_devices = """
{
"dm-0": {
"sectors": "136314880",
"sectorsize": "512",
"size": "65.00 GB"
},
"sda": {
"holders": [],
"partitions": {
"sda2": {
"holders": [],
"sectors": "19860030",
"sectorsize": 512,
"size": "9.47 GB",
"start": "2048"
},
"sda3": {
"holders": [],
"sectors": "20908606",
"sectorsize": 512,
"size": "9.97 GB",
"start": "411648"
},
"sda4": {
"holders": [
"fedora_ruriko-swap",
"fedora_ruriko-home",
"fedora_ruriko-root"
],
"sectors": "20908606",
"sectorsize": 512,
"size": "9.97 GB",
"start": "1435648"
},
"sda6": {
"holders": [],
"sectors": "12582912",
"sectorsize": 512,
"size": "6.0 GB",
"start": "411648"
},
"sda8": {
"holders": [],
"sectors": "30408704",
"sectorsize": 512,
"size": "14.5 GB",
"start": "411648"
},
"sda9": {
"holders": [],
"sectors": "32505856",
"sectorsize": 512,
"size": "15.5 GB",
"start": "411648"
},
"sda10": {
"holders": [],
"sectors": "32505856",
"sectorsize": 512,
"size": "15.5 GB",
"start": "411648"
},
"sda11": {
"holders": [],
"sectors": "12582912",
"sectorsize": 512,
"size": "1 GB",
"start": "411648"
}
},
"sectors": "137174714",
"sectorsize": "512",
"size": "65.41 GB"
}
}
"""
class Test_PhysicalVolume(unittest.TestCase):
def test_init(self):
"""
Test empty initialization of PhysicalVolume
"""
p = PhysicalVolume("PV")
assert p.name == "PV"
assert p.size == -1
assert p.free == -1
def test_init_valid(self):
"""
Test initialisation with valid data
"""
p = PhysicalVolume("PV", size=10, free=0)
assert p.name == "PV"
assert p.size == 10
assert p.free == 0
p = PhysicalVolume("PV", size=10, free=10)
assert p.size == 10
assert p.free == 10
def test_init_invalid(self):
"""
Test initialisation with invalid data
"""
with self.assertRaises(TypeError):
p = PhysicalVolume("PV", size="bad")
with self.assertRaises(TypeError):
p = PhysicalVolume("PV", free="bad")
# size must be at least free
with self.assertRaises(ValueError):
p = PhysicalVolume("PV", free=10, size=5)
class Test_LogicalVolume(unittest.TestCase):
def test_init(self):
"""
Test empty initialization of LogicalVolume
"""
l = LogicalVolume("LV")
assert l.name == "LV"
assert l.size == -1
assert l.mount == ""
def test_init_valid(self):
"""
Test initialisation with valid data
"""
l = LogicalVolume("LV", fs="ext4", size=10, mount="/")
assert l.name == "LV"
assert l.size == 10
assert l.mount == "/"
assert l.fs == "ext4"
def test_init_invalid(self):
"""
Test initialisation with invalid data
"""
with self.assertRaises(TypeError):
l = LogicalVolume("LV", size="bad")
with self.assertRaises(TypeError):
l = LogicalVolume("LV", mount="/boot")
class Test_VolumeGroup(unittest.TestCase):
def test_init(self):
"""
Test empty initialization of VolumeGroup
"""
v = VolumeGroup("VG")
assert v.name == "VG"
assert v.lvs == {}
assert v.pvs == {}
assert v.size == -1
assert v.free == -1
def test_init_valid(self):
"""
Test initialisation with valid data
"""
lvs = {}
pvs = {}
lvs["LV"] = LogicalVolume("LV")
pvs["PV"] = PhysicalVolume("PV")
v = VolumeGroup("VG", lvs, pvs, 10, 5)
assert v.name == "VG"
assert v.size == 10
assert v.free == 5
for l in v.lvs.values():
assert l.name == "LV"
for p in v.pvs.values():
assert p.name == "PV"
def test_init_invald_lists(self):
"""
Test initialisation with invalid data
"""
with self.assertRaises(TypeError):
v = VolumeGroup("VG", lvs="bad")
with self.assertRaises(TypeError):
v = VolumeGroup("VG", pvs="bad")
def test_init_sizes(self):
with self.assertRaises(TypeError):
v = VolumeGroup("VG", size="bad")
with self.assertRaises(TypeError):
v = VolumeGroup("VG", free="bad")
with self.assertRaises(ValueError):
v = VolumeGroup("VG", free=10, size=5)
v = VolumeGroup("VG", size=10, free=10)
assert v.size == 10
assert v.free == 10
v = VolumeGroup("VG", size=10, free=0)
assert v.size == 10
assert v.free == 0
def test_ismissing(self):
vgs = []
v1 = VolumeGroup("VG")
v2 = VolumeGroup("notVG")
vgs.append(v1)
p = Partitioning(vgs)
assert v1.isMissing(p) == False
assert v2.isMissing(p) == True
class Test_Partitioning(unittest.TestCase):
def test_init(self):
"""
Test empty initialization of Partitioning
"""
p = Partitioning()
assert p.vgs == []
def test_init_invalid(self):
"""
Test initialisation with invalid data
"""
with self.assertRaises(TypeError):
p = Partitioning("not_a_list_of_volumegroups")
def test_init_valid(self):
"""
Test initialisation with valid data
"""
vgs = []
vgs.append(VolumeGroup("VG"))
p = Partitioning(vgs)
for v in p.vgs:
assert v.name == "VG"
class Test_PartitioningData(unittest.TestCase):
def setUp(self):
self.f = FilterModule()
self.desired = json.loads(current_state)
self.current = yaml.load(desired_state, Loader=yaml.FullLoader)
self.pv_present = json.loads(ansible_devices)
self.mounts = json.loads(ansible_mounts)
def test_vg_unchanged(self):
"""
Unchanged items must remain unchanged
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
vgroot = diff.find(VolumeGroup("VGROOT"))
assert len(vgroot.lvs) == 2
assert len(vgroot.pvs) == 2
assert vgroot.size == 19.44
assert vgroot.free == 0
assert vgroot.state == "present"
assert vgroot.result == "0"
pvs_checked = 0
for pv in vgroot.pvs.values():
assert pv.state == "present"
if pv.name == "/dev/sda2":
assert pv.size == 9.47
assert pv.free == 0
pvs_checked += 1
if pv.name == "/dev/sda3":
assert pv.size == 9.97
assert pv.free == 0
pvs_checked += 1
assert pvs_checked == 2
lvs_checked = 0
for lv in vgroot.lvs.values():
assert lv.state == "present"
if lv.name == "lv_root":
assert lv.size == 17.44
assert lv.fs == "xfs"
assert lv.mount == "/"
lvs_checked += 1
if lv.name == "lv_swap":
assert lv.size == 2
assert lv.fs == "swap"
assert lv.mount == "swap"
lvs_checked += 1
assert lvs_checked == 2
def test_vg_added(self):
"""
Added items must appear as present
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
newvg = diff.find(VolumeGroup("VGADD"))
assert newvg != None
assert newvg.state == "present"
assert newvg.result == "0"
assert newvg.size == 6
assert newvg.free == 1
for lv in newvg.lvs.values():
assert lv.state == "present"
if lv.name == "lv_data":
assert lv.fs == "xfs"
assert lv.size == 5
assert lv.mount == "/data"
for pv in newvg.pvs.values():
assert pv.state == "resized"
def test_vg_removed(self):
"""
Removed items must appear as absent
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
rmvg = diff.find(VolumeGroup("VGRM"))
assert rmvg != None
assert rmvg.state == "absent"
assert rmvg.result == "0"
for lv in rmvg.lvs.values():
assert lv.state == "absent"
for pv in rmvg.pvs.values():
assert pv.state == "absent"
def test_vg_extended(self):
"""
Changed items must reflect changes
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
extvg = diff.find(VolumeGroup("VGEXT"))
assert extvg != None
assert extvg.state == "resized"
assert extvg.result == "0"
assert extvg.size == 30
assert extvg.free == 5.5
lvs_checked = 0
for lv in extvg.lvs.values():
if lv.name == "lv_ch1":
lvs_checked += 1
assert lv.state == "present"
assert lv.size == 14.5
assert lv.mount == "/ch1"
assert lv.fs == "xfs"
if lv.name == "lv_ch2":
assert lv.state == "present"
assert lv.size == 10
assert lv.mount == "/ch2"
assert lv.fs == "xfs"
lvs_checked += 1
assert lvs_checked == 2
pvs_checked = 0
for pv in extvg.pvs.values():
if pv.name == "/dev/sda8":
pvs_checked += 1
if pv.name == "/dev/sda9":
pvs_checked += 1
assert pvs_checked == 2
def test_vg_unknown(self):
"""
VG with unknown PV must fail
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
vg = diff.find(VolumeGroup("VGUNKNOWN"))
assert vg.result == "1"
def test_vg_small(self):
"""
VG with too little space must fail
"""
diff = self.f.lvmdiff(self.desired, self.current, self.pv_present, self.mounts)
vg = diff.find(VolumeGroup("VGSMALL"))
assert vg.result == "1"
if "__main__" == __name__:
unittest.main()
import unittest, json, yaml
from partitioningFilter import FilterModule, Partitioning, VolumeGroup, LogicalVolume, PhysicalVolume
current_state = """
{
"lvs": {
"lv_root": {
"size_g": "11.00",