# Copyright (C) 2017 Red Hat, Inc., Bryn M. Reeves <bmr@redhat.com>
#
# boom/__init__.py - Boom package initialisation
#
# This file is part of the boom project.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from os.path import join, abspath
from os import geteuid, getegid, makedirs
from subprocess import Popen, PIPE
import shutil
import errno
import boom
# Root of the testing directory
BOOT_ROOT_TEST = abspath("./tests")
# Location of the temporary sandbox for test data
SANDBOX_PATH = join(BOOT_ROOT_TEST, "sandbox")
# Test sandbox functions
def rm_sandbox():
"""Remove the test sandbox at SANDBOX_PATH.
"""
try:
shutil.rmtree(SANDBOX_PATH)
except OSError as e:
if e.errno != errno.ENOENT:
raise
def mk_sandbox():
"""Create a new test sandbox at SANDBOX_PATH.
"""
makedirs(SANDBOX_PATH)
def reset_sandbox():
"""Reset the test sandbox at SANDBOX_PATH by removing it and
re-creating the directory.
"""
rm_sandbox()
mk_sandbox()
def reset_boom_paths():
"""Reset configurable boom module paths to the default test values.
"""
boom.set_boot_path(BOOT_ROOT_TEST)
# Mock objects
class MockArgs(object):
"""Mock arguments class for testing boom command line infrastructure.
"""
add_opts = ""
architecture = None
boot_id = "12345678"
btrfs_opts = ""
btrfs_subvolume = "23"
command = ""
config = ""
debug = ""
del_opts = ""
efi = ""
efi = ""
expand_variables = False
from_host = ""
grub_arg = ""
grub_class = ""
grub_users = ""
host_id = None
host_name = ""
host_profile = ""
host_profile = ""
id = ""
identifier = ""
initramfs_pattern = ""
initrd = ""
kernel_pattern = ""
label = ""
linux = ""
lvm_opts = ""
machine_id = ""
name = ""
name_prefixes = False
no_dev = False
no_headings = False
options = ""
optional_keys = ""
os_id = ""
os_options = ""
os_release = ""
os_version = ""
os_version_id = ""
profile = ""
root_device = ""
root_lv = ""
rows = False
separator = ""
short_name = ""
sort = ""
title = ""
type = ""
uname_pattern = ""
verbose = 0
version = ""
# Cached logical volume to use for tests
_lv_cache = None
def _root_lv_from_cmdline():
"""Return the root logical volume according to the kernel command
line, or the empty string if no rd.lvm.lv argument is found.
"""
with open("/proc/cmdline", "r") as f:
for line in f.read().splitlines():
if isinstance(line, bytes):
line = line.decode('utf8', 'ignore')
args = line.split()
for arg in args:
if "rd.lvm.lv" in arg:
(rd, vglv) = arg.split("=")
return "/dev/%s" % vglv
return None
def get_logical_volume():
"""Return an extant logical volume path suitable for use for
device presence checks.
The actual volume returned is unimportant.
The device is not modified or written to in any way by the
the test suite.
"""
global _lv_cache
if _lv_cache:
return _lv_cache
if not have_root() or not have_lvm():
"""The LVM2 binary is not present or not usable. Attempt to
guess a usable device name based on the content of the
system kernel command line.
"""
return _root_lv_from_cmdline()
p = Popen(["lvs", "--noheadings", "-ovgname,name"], stdin=None,
stdout=PIPE, stderr=None, close_fds=True)
out = p.communicate()[0]
lvs = []
for line in out.splitlines():
if isinstance(line, bytes):
line = line.decode('utf8', 'ignore')
(vg, lv) = line.strip().split()
if "swap" in lv:
continue
if "root" in lv:
_lv_cache = "/dev/%s/%s" % (vg, lv)
return _lv_cache
lvs.append("/dev/%s/%s" % (vg, lv))
_lv_cache = lvs[0]
return _lv_cache
def get_root_lv():
"""Return the logical volume found by ``get_logical_volume()``
in LVM VG/LV notation.
"""
lv = get_logical_volume()
return lv[5:] if lv else None
def have_root_lv():
"""Return ``True`` if a usable root logical volume is present,
or ``False`` otherwise.
"""
return bool(get_root_lv())
# Test predicates
def have_root():
"""Return ``True`` if the test suite is running as the root user,
and ``False`` otherwise.
"""
return geteuid() == 0 and getegid() == 0
def have_lvm():
"""Return ``True`` if the test suite is running on a system with
at least one logical volume, or ``False`` otherwise.
"""
p = Popen(["lvs", "--noheadings", "-oname"], stdin=None, stdout=PIPE,
stderr=None, close_fds=True)
out = p.communicate()[0]
if len(out.splitlines()):
return True
return False
def have_grub1():
"""Return ``True`` if the grub1 bootloader commands are present,
or ``False`` otherwise.
"""
try:
p = Popen(["grub", "--help"], stdin=None, stdout=PIPE, stderr=PIPE,
close_fds=True)
out = p.communicate(input="\n")[0]
return True
except OSError:
return False
__all__ = [
'BOOT_ROOT_TEST', 'SANDBOX_PATH',
'rm_sandbox', 'mk_sandbox', 'reset_sandbox', 'reset_boom_paths',
'get_logical_volume', 'get_root_lv', 'have_root_lv',
'MockArgs',
'have_root', 'have_lvm', 'have_grub1'
]
# vim: set et ts=4 sw=4 :