Files
DetectionLab/Vagrant/resources/malcolm/shared/bin/fstab.py
2021-08-06 10:35:01 +02:00

123 lines
3.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2021 Battelle Energy Alliance, LLC. All rights reserved.
# fstab interpreter
import os
class Fstab:
"""This class extends file in order to implement a file reader/writer
for file `/etc/fstab`
"""
class Entry(object):
"""Entry class represents a non-comment line on the `/etc/fstab` file
"""
def __init__(self, device, mountpoint, filesystem,
options, fs_freq=0, fs_passno=0):
self.device = device
self.mountpoint = mountpoint
self.filesystem = filesystem
if not options:
options = "defaults"
self.options = options
self.fs_freq = fs_freq
self.fs_passno = fs_passno
def __eq__(self, o):
return str(self) == str(o)
def __str__(self):
return "{} {} {} {} {} {}".format(self.device,
self.mountpoint,
self.filesystem,
self.options,
self.fs_freq,
self.fs_passno)
DEFAULT_PATH = os.path.join(os.path.sep, 'etc', 'fstab')
def __init__(self, path=None):
if path:
self._path = path
else:
self._path = self.DEFAULT_PATH
self.f = open(self._path, 'r+')
def __enter__ (self):
return self.f
def __exit__ (self, exc_type, exc_value, traceback):
self.f.close()
def _hydrate_entry(self, line):
return Fstab.Entry(*[ x for x in line.replace("\t"," ").strip("\n").split(" ")
if x not in ('', None) ])
@property
def entries(self):
self.f.seek(0)
for line in self.f.readlines():
try:
if not line.startswith("#"):
yield self._hydrate_entry(line)
except ValueError:
pass
def get_entry_by_attr(self, attr, value):
for entry in self.entries:
e_attr = getattr(entry, attr)
if e_attr == value:
return entry
return None
def add_entry(self, entry):
if self.get_entry_by_attr('device', entry.device):
return False
self.f.write(str(entry) + '\n')
self.f.truncate()
return entry
def remove_entry(self, entry):
self.f.seek(0)
lines = self.f.readlines()
found = False
for index, line in enumerate(lines):
if not line.startswith("#"):
if self._hydrate_entry(line) == entry:
found = True
break
if not found:
return False
lines.remove(line)
self.f.seek(0)
self.f.write(''.join(lines))
self.f.truncate()
return True
@classmethod
def remove_by_mountpoint(cls, mountpoint, path=None):
fstab = cls(path=path)
entry = fstab.get_entry_by_attr('mountpoint', mountpoint)
if entry:
return fstab.remove_entry(entry)
return False
@classmethod
def add(cls, device, mountpoint, filesystem, options=None, fs_freq=0, fs_passno=0, path=None):
return cls(path=path).add_entry(Fstab.Entry(device,
mountpoint, filesystem,
options=options,
fs_freq=fs_freq,
fs_passno=fs_passno))