aif-ng/aif/disk/filesystem_fallback.py
2019-11-01 03:43:14 -04:00

85 lines
3.0 KiB
Python

import os
import re
import subprocess
##
import psutil
##
import aif.disk.block_fallback as block
import aif.disk.luks_fallback as luks
import aif.disk.lvm_fallback as lvm
import aif.disk.mdadm_fallback as mdadm
# I wish there was a better way of doing this.
# https://unix.stackexchange.com/a/98680
FS_FSTYPES = []
with open('/proc/filesystems', 'r') as fh:
for line in fh.readlines():
l = [i.strip() for i in line.split()]
if not l:
continue
if len(l) == 1:
FS_FSTYPES.append(l[0])
else:
FS_FSTYPES.append(l[1])
_mod_dir = os.path.join('/lib/modules',
os.uname().release,
'kernel/fs')
_strip_mod_suffix = re.compile(r'(?P<fsname>)\.ko(\.(x|g)?z)?$', re.IGNORECASE)
try:
for i in os.listdir(_mod_dir):
path = os.path.join(_mod_dir, i)
fs_name = None
if os.path.isdir(path):
fs_name = i
elif os.path.isfile(path):
mod_name = _strip_mod_suffix.search(i)
fs_name = mod_name.group('fsname')
if fs_name:
# The kernel *probably* has autoloading enabled, but in case it doesn't...
# TODO: logging!
if os.getuid() == 0:
subprocess.run(['modprobe', fs_name])
FS_FSTYPES.append(fs_name)
except FileNotFoundError:
# We're running on a kernel that doesn't have modules
pass
class FS(object):
def __init__(self, fs_xml, sourceobj):
self.xml = fs_xml
if not isinstance(sourceobj, (aif.disk.block_fallback.Disk,
aif.disk.block_fallback.Partition,
aif.disk.luks_fallback.LUKS,
aif.disk.lvm_fallback.LV,
aif.disk.mdadm_fallback.Array)):
raise ValueError(('sourceobj must be of type '
'aif.disk.block.Partition, '
'aif.disk.luks.LUKS, '
'aif.disk.lvm.LV, or'
'aif.disk.mdadm.Array'))
self.source = sourceobj
self.devpath = sourceobj.devpath
self.formatted = False
self.fstype = self.xml.attrib.get('type')
def format(self):
if self.formatted:
return ()
# This is a safeguard. We do *not* want to high-format a disk that is mounted.
for p in psutil.disk_partitions(all = True):
if self.devpath in p:
raise RuntimeError(('{0} is mounted;'
'we are cowardly refusing to apply a filesystem to it').format(self.devpath))
# TODO! Logging
cmd = ['mkfs',
'-t', self.fstype]
for o in self.xml.findall('opt'):
cmd.append(o.attrib['name'])
if o.text:
cmd.append(o.text)
cmd.append(self.devpath)
subprocess.run(cmd)
self.is_hiformatted = True
return()