aif-ng/aif/disk/filesystem_fallback.py
brent s ca1f12f5bd soooo...
turns out ALL of the disk operations can be performed with
gobject-introspection.

BUT it's unlikely that that'll be available everywhere, or that
the Arch Linux releng team would include it, etc.
So we have fallbacks to mimic it.

BUT please try to use gobject-introspection with libblockdev,
because it's going to be a lot faster and a lot less error-prone.
2019-11-01 02:54:51 -04:00

81 lines
2.8 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)
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)
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()