|
Packit |
5acf3f |
# Copyright (C) 2017 Red Hat, Inc., Bryn M. Reeves <bmr@redhat.com>
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# hostprofile.py - Boom host profiles
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# This file is part of the boom project.
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit |
5acf3f |
# modify, copy, or redistribute it subject to the terms and conditions
|
|
Packit |
5acf3f |
# of the GNU General Public License v.2.
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
5acf3f |
# along with this program; if not, write to the Free Software Foundation,
|
|
Packit |
5acf3f |
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
5acf3f |
"""The ``boom.hostprofile`` module defines the `HostProfile` class that
|
|
Packit |
5acf3f |
represents a host system profile. A `HostProfile` defines the identity
|
|
Packit |
5acf3f |
of a host and includes template values that override the corresponding
|
|
Packit |
5acf3f |
``OsProfile`` defaults for the respective host.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Functions are provided to read and write host system profiles from
|
|
Packit |
5acf3f |
an on-disk store, and to retrieve ``HostProfile`` instances using
|
|
Packit |
5acf3f |
various selection criteria.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
The ``HostProfile`` class includes named properties for each profile
|
|
Packit |
5acf3f |
attribute ("profile key"). In addition, the class serves as a container
|
|
Packit |
5acf3f |
type, allowing attributes to be accessed via dictionary-style indexing.
|
|
Packit |
5acf3f |
This simplifies iteration over a profile's key / value pairs and allows
|
|
Packit |
5acf3f |
straightforward access to all members in scripts and the Python shell.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
The keys used to access ``HostProfile`` members (and their corresponding
|
|
Packit |
5acf3f |
property names) are identical to those used by the ``OsProfile`` class.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
from __future__ import print_function
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
from boom import *
|
|
Packit |
5acf3f |
from boom.osprofile import *
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
from hashlib import sha1
|
|
Packit |
5acf3f |
from os.path import join as path_join
|
|
Packit |
5acf3f |
import logging
|
|
Packit |
5acf3f |
import string
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Module logging configuration
|
|
Packit |
5acf3f |
_log = logging.getLogger(__name__)
|
|
Packit |
5acf3f |
_log.set_debug_mask(BOOM_DEBUG_PROFILE)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_log_debug = _log.debug
|
|
Packit |
5acf3f |
_log_debug_profile = _log.debug_masked
|
|
Packit |
5acf3f |
_log_info = _log.info
|
|
Packit |
5acf3f |
_log_warn = _log.warning
|
|
Packit |
5acf3f |
_log_error = _log.error
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Global host profile list
|
|
Packit |
5acf3f |
_host_profiles = []
|
|
Packit |
5acf3f |
_host_profiles_by_id = {}
|
|
Packit |
5acf3f |
_host_profiles_by_host_id = {}
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Whether profiles have been read from disk
|
|
Packit |
5acf3f |
_host_profiles_loaded = False
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Boom profiles directory name.
|
|
Packit |
5acf3f |
BOOM_HOST_PROFILES = "hosts"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: File name format for Boom profiles.
|
|
Packit |
5acf3f |
BOOM_HOST_PROFILE_FORMAT = "%s-%s.host"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: The file mode with which to create Boom profiles.
|
|
Packit |
5acf3f |
BOOM_HOST_PROFILE_MODE = 0o644
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Constants for Boom profile keys
|
|
Packit |
5acf3f |
#: Constant for the Boom host identifier profile key.
|
|
Packit |
5acf3f |
BOOM_HOST_ID = "BOOM_HOST_ID"
|
|
Packit |
5acf3f |
#: Constant for the Boom host name profile key.
|
|
Packit |
5acf3f |
BOOM_HOST_NAME = "BOOM_HOST_NAME"
|
|
Packit |
5acf3f |
#: Constant for the Boom host add options key.
|
|
Packit |
5acf3f |
BOOM_HOST_ADD_OPTS = "BOOM_HOST_ADD_OPTS"
|
|
Packit |
5acf3f |
#: Constant for the Boom host del options key.
|
|
Packit |
5acf3f |
BOOM_HOST_DEL_OPTS = "BOOM_HOST_DEL_OPTS"
|
|
Packit |
5acf3f |
#: Constant for the Boom host label key.
|
|
Packit |
5acf3f |
BOOM_HOST_LABEL = "BOOM_HOST_LABEL"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Constant for shared machine_id key
|
|
Packit |
5acf3f |
BOOM_ENTRY_MACHINE_ID = "BOOM_ENTRY_MACHINE_ID"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Ordered list of possible host profile keys, partitioned into
|
|
Packit |
5acf3f |
#: mandatory keys, optional host profile keys, keys mapping to
|
|
Packit |
5acf3f |
#: embedded ``OsProfile`` identity data, and ``OsProfile`` pattern
|
|
Packit |
5acf3f |
#: keys that may be overridden in the ``HostProfile``.
|
|
Packit |
5acf3f |
HOST_PROFILE_KEYS = [
|
|
Packit |
5acf3f |
# HostProfile identifier
|
|
Packit |
5acf3f |
BOOM_HOST_ID,
|
|
Packit |
5acf3f |
# Machine hostname
|
|
Packit |
5acf3f |
BOOM_HOST_NAME,
|
|
Packit |
5acf3f |
# Binding to label, machine_id and OsProfile
|
|
Packit |
5acf3f |
BOOM_ENTRY_MACHINE_ID, BOOM_OS_ID,
|
|
Packit |
5acf3f |
# Optional host profile keys
|
|
Packit |
5acf3f |
BOOM_HOST_LABEL, BOOM_HOST_ADD_OPTS, BOOM_HOST_DEL_OPTS,
|
|
Packit |
5acf3f |
# Keys 7-10 OS identity keys mapped to the embedded OsProfile.
|
|
Packit |
5acf3f |
BOOM_OS_NAME, BOOM_OS_SHORT_NAME, BOOM_OS_VERSION, BOOM_OS_VERSION_ID,
|
|
Packit |
5acf3f |
# Keys 11-15 (OsProfile patterns) may be overridden in the host profile.
|
|
Packit |
5acf3f |
BOOM_OS_UNAME_PATTERN, BOOM_OS_KERNEL_PATTERN, BOOM_OS_INITRAMFS_PATTERN,
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_LVM2, BOOM_OS_ROOT_OPTS_BTRFS,
|
|
Packit |
5acf3f |
BOOM_OS_OPTIONS
|
|
Packit |
5acf3f |
]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: A map of Boom host profile keys to human readable key names suitable
|
|
Packit |
5acf3f |
#: for use in formatted output. These key names are used to format a
|
|
Packit |
5acf3f |
#: ``HostProfile`` object as a human readable string.
|
|
Packit |
5acf3f |
HOST_KEY_NAMES = {
|
|
Packit |
5acf3f |
# Keys unique to HostProfile
|
|
Packit |
5acf3f |
BOOM_HOST_ID: "Host ID",
|
|
Packit |
5acf3f |
BOOM_HOST_NAME: "Host name",
|
|
Packit |
5acf3f |
BOOM_HOST_LABEL: "Host label",
|
|
Packit |
5acf3f |
BOOM_HOST_ADD_OPTS: "Add options",
|
|
Packit |
5acf3f |
BOOM_HOST_DEL_OPTS: "Del options",
|
|
Packit |
5acf3f |
# Keys shared with BootEntry
|
|
Packit |
5acf3f |
BOOM_ENTRY_MACHINE_ID: "Machine ID",
|
|
Packit |
5acf3f |
# Keys incorporated from OsProfile
|
|
Packit |
5acf3f |
BOOM_OS_ID: OS_KEY_NAMES[BOOM_OS_ID],
|
|
Packit |
5acf3f |
BOOM_OS_NAME: OS_KEY_NAMES[BOOM_OS_NAME],
|
|
Packit |
5acf3f |
BOOM_OS_SHORT_NAME: OS_KEY_NAMES[BOOM_OS_SHORT_NAME],
|
|
Packit |
5acf3f |
BOOM_OS_VERSION: OS_KEY_NAMES[BOOM_OS_VERSION],
|
|
Packit |
5acf3f |
BOOM_OS_VERSION_ID: OS_KEY_NAMES[BOOM_OS_VERSION_ID],
|
|
Packit |
5acf3f |
BOOM_OS_UNAME_PATTERN: OS_KEY_NAMES[BOOM_OS_UNAME_PATTERN],
|
|
Packit |
5acf3f |
BOOM_OS_KERNEL_PATTERN: OS_KEY_NAMES[BOOM_OS_KERNEL_PATTERN],
|
|
Packit |
5acf3f |
BOOM_OS_INITRAMFS_PATTERN: OS_KEY_NAMES[BOOM_OS_INITRAMFS_PATTERN],
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_LVM2: OS_KEY_NAMES[BOOM_OS_ROOT_OPTS_LVM2],
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_BTRFS: OS_KEY_NAMES[BOOM_OS_ROOT_OPTS_BTRFS],
|
|
Packit |
5acf3f |
BOOM_OS_OPTIONS: OS_KEY_NAMES[BOOM_OS_OPTIONS]
|
|
Packit |
5acf3f |
}
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Boom host profile keys that must exist in a valid profile.
|
|
Packit |
5acf3f |
HOST_REQUIRED_KEYS = HOST_PROFILE_KEYS[0:4]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#: Boom optional host profile configuration keys.
|
|
Packit |
5acf3f |
HOST_OPTIONAL_KEYS = HOST_PROFILE_KEYS[4:]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _host_exists(host_id):
|
|
Packit |
5acf3f |
"""Test whether the specified ``host_id`` already exists.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Used during ``HostProfile`` initialisation to test if the new
|
|
Packit |
5acf3f |
``host_id`` is already known (and to avoid passing through
|
|
Packit |
5acf3f |
find_profiles(), which may trigger recursive profile loading).
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param host_id: the host identifier to check for
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: ``True`` if the identifier is known or ``False``
|
|
Packit |
5acf3f |
otherwise.
|
|
Packit |
5acf3f |
:rtype: bool
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles_by_host_id
|
|
Packit |
5acf3f |
if not _host_profiles_by_host_id:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if host_id in _host_profiles_by_host_id:
|
|
Packit |
5acf3f |
return True
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def boom_host_profiles_path():
|
|
Packit |
5acf3f |
"""Return the path to the boom host profiles directory.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: The boom host profiles path.
|
|
Packit |
5acf3f |
:rtype: str
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return path_join(get_boom_path(), BOOM_HOST_PROFILES)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def host_profiles_loaded():
|
|
Packit |
5acf3f |
"""Test whether profiles have been loaded from disk.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: bool
|
|
Packit |
5acf3f |
:returns: ``True`` if profiles are loaded in memory or ``False``
|
|
Packit |
5acf3f |
otherwise
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return _host_profiles_loaded
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def drop_host_profiles():
|
|
Packit |
5acf3f |
"""Drop all in-memory host profiles.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles, _host_profiles_by_id, _host_profiles_by_host_id
|
|
Packit |
5acf3f |
global _host_profiles_loaded
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_host_profiles = []
|
|
Packit |
5acf3f |
_host_profiles_by_id = {}
|
|
Packit |
5acf3f |
_host_profiles_by_host_id = {}
|
|
Packit |
5acf3f |
_host_profiles_loaded = False
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def load_host_profiles():
|
|
Packit |
5acf3f |
"""Load HostProfile data from disk.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Load the set of host profiles found at the path
|
|
Packit |
5acf3f |
``boom.hostprofile.boom_profiles_path()`` into the global host
|
|
Packit |
5acf3f |
profile list.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
This function may be called to explicitly load, or reload the
|
|
Packit |
5acf3f |
set of profiles on-disk. Profiles are also loaded implicitly
|
|
Packit |
5acf3f |
if an API function or method that requires access to profiles
|
|
Packit |
5acf3f |
is invoked (for example, ``boom.bootloader.load_entries()``.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: None
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles_loaded
|
|
Packit |
5acf3f |
drop_host_profiles()
|
|
Packit |
5acf3f |
profiles_path = boom_host_profiles_path()
|
|
Packit |
5acf3f |
load_profiles_for_class(HostProfile, "Host", profiles_path, "host")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_host_profiles_loaded = True
|
|
Packit |
5acf3f |
_log_info("Loaded %d host profiles" % len(_host_profiles))
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def write_host_profiles(force=False):
|
|
Packit |
5acf3f |
"""Write all HostProfile data to disk.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Write the current list of host profiles to the directory located
|
|
Packit |
5acf3f |
at ``boom.osprofile.boom_profiles_path()``.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: None
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles
|
|
Packit |
5acf3f |
_log_debug("Writing host profiles to %s" % boom_host_profiles_path())
|
|
Packit |
5acf3f |
for hp in _host_profiles:
|
|
Packit |
5acf3f |
try:
|
|
Packit |
5acf3f |
hp.write_profile(force)
|
|
Packit |
5acf3f |
except Exception as e:
|
|
Packit |
5acf3f |
_log_warn("Failed to write HostProfile(machine_id='%s'): %s" %
|
|
Packit |
5acf3f |
(hp.disp_machine_id, e))
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def min_host_id_width():
|
|
Packit |
5acf3f |
"""Calculate the minimum unique width for host_id values.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Calculate the minimum width to ensure uniqueness when displaying
|
|
Packit |
5acf3f |
host_id values.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: the minimum host_id width.
|
|
Packit |
5acf3f |
:rtype: int
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return min_id_width(7, _host_profiles, "host_id")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def min_machine_id_width():
|
|
Packit |
5acf3f |
"""Calculate the minimum unique width for host_id values.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Calculate the minimum width to ensure uniqueness when displaying
|
|
Packit |
5acf3f |
host_id values.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: the minimum host_id width.
|
|
Packit |
5acf3f |
:rtype: int
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return min_id_width(7, _host_profiles, "machine_id")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def select_host_profile(s, hp):
|
|
Packit |
5acf3f |
"""Test the supplied host profile against selection criteria.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Test the supplied ``HostProfile`` against the selection criteria
|
|
Packit |
5acf3f |
in ``s`` and return ``True`` if it passes, or ``False``
|
|
Packit |
5acf3f |
otherwise.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param s: The selection criteria
|
|
Packit |
5acf3f |
:param hp: The ``HostProfile`` to test
|
|
Packit |
5acf3f |
:rtype: bool
|
|
Packit |
5acf3f |
:returns: True if ``hp`` passes selection or ``False`` otherwise.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if s.host_id and not hp.host_id.startswith(s.host_id):
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.machine_id and hp.machine_id != s.machine_id:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.host_name and hp.host_name != s.host_name:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.host_label and hp.label != s.host_label:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.host_short_name and hp.short_name != s.host_short_name:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.host_add_opts and hp.add_opts != s.host_add_opts:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.host_del_opts and hp.del_opts != s.host_del_opts:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_id and not hp.os_id.startswith(s.os_id):
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_name and hp.os_name != s.os_name:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_short_name and hp.os_short_name != s.os_short_name:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_version and hp.os_version != s.os_version:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_version_id and hp.os_version_id != s.os_version_id:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_uname_pattern and hp.uname_pattern != s.os_uname_pattern:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_kernel_pattern and hp.kernel_pattern != s.os_kernel_pattern:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if (s.os_initramfs_pattern and
|
|
Packit |
5acf3f |
hp.initramfs_pattern != s.os_initramfs_pattern):
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
if s.os_options and hp.options != s.os_options:
|
|
Packit |
5acf3f |
return False
|
|
Packit |
5acf3f |
return True
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def find_host_profiles(selection=None, match_fn=select_host_profile):
|
|
Packit |
5acf3f |
"""Find host profiles matching selection criteria.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return a list of ``HostProfile`` objects matching the specified
|
|
Packit |
5acf3f |
criteria. Matching proceeds as the logical 'and' of all criteria.
|
|
Packit |
5acf3f |
Criteria that are unset (``None``) are ignored.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
If the optional ``match_fn`` parameter is specified, the match
|
|
Packit |
5acf3f |
criteria parameters are ignored and each ``HostProfile`` is
|
|
Packit |
5acf3f |
tested in turn by calling ``match_fn``. If the matching function
|
|
Packit |
5acf3f |
returns ``True`` the ``HostProfile`` will be included in the
|
|
Packit |
5acf3f |
results.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
If no ``HostProfile`` matches the specified criteria the empty
|
|
Packit |
5acf3f |
list is returned.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Host profiles will be automatically loaded from disk if they are
|
|
Packit |
5acf3f |
not already in memory.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param selection: A ``Selection`` object specifying the match
|
|
Packit |
5acf3f |
criteria for the operation.
|
|
Packit |
5acf3f |
:param match_fn: An optional match function to test profiles.
|
|
Packit |
5acf3f |
:returns: a list of ``HostProfile`` objects.
|
|
Packit |
5acf3f |
:rtype: list
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
# Use null search criteria if unspecified
|
|
Packit |
5acf3f |
selection = selection if selection else Selection()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
selection.check_valid_selection(host=True)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if not host_profiles_loaded():
|
|
Packit |
5acf3f |
load_host_profiles()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
matches = []
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_log_debug_profile("Finding host profiles for %s" % repr(selection))
|
|
Packit |
5acf3f |
for hp in _host_profiles:
|
|
Packit |
5acf3f |
if match_fn(selection, hp):
|
|
Packit |
5acf3f |
matches.append(hp)
|
|
Packit |
5acf3f |
_log_debug_profile("Found %d host profiles" % len(matches))
|
|
Packit |
5acf3f |
matches.sort(key=lambda h: h.host_name)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
return matches
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def get_host_profile_by_id(machine_id, label=""):
|
|
Packit |
5acf3f |
"""Find a HostProfile by its machine_id.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return the HostProfile object corresponding to ``machine_id``,
|
|
Packit |
5acf3f |
or ``None`` if it is not found.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: HostProfile
|
|
Packit |
5acf3f |
:returns: An HostProfile matching machine_id or None if no match
|
|
Packit |
5acf3f |
was found.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles, _host_profiles_by_id, _host_profiles_by_host_id
|
|
Packit |
5acf3f |
if not host_profiles_loaded():
|
|
Packit |
5acf3f |
load_host_profiles()
|
|
Packit |
5acf3f |
if machine_id in _host_profiles_by_id:
|
|
Packit |
5acf3f |
if label in _host_profiles_by_id[machine_id]:
|
|
Packit |
5acf3f |
return _host_profiles_by_id[machine_id][label]
|
|
Packit |
5acf3f |
return None
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def match_host_profile(entry):
|
|
Packit |
5acf3f |
"""Attempt to match a BootEntry to a corresponding HostProfile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Attempt to find a loaded ``HostProfile`` object with the a
|
|
Packit |
5acf3f |
``machine_id`` that matches the supplied ``BootEntry``.
|
|
Packit |
5acf3f |
Checking terminates on the first matching ``HostProfile``.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param entry: A ``BootEntry`` object with no attached
|
|
Packit |
5acf3f |
``HostProfile``.
|
|
Packit |
5acf3f |
:returns: The corresponding ``HostProfile`` for the supplied
|
|
Packit |
5acf3f |
``BootEntry`` or ``None`` if no match is found.
|
|
Packit |
5acf3f |
:rtype: ``BootEntry`` or ``NoneType``.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles, _host_profiles_loaded
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if not host_profiles_loaded():
|
|
Packit |
5acf3f |
load_host_profiles()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_log_debug("Attempting to match profile for BootEntry(title='%s', "
|
|
Packit |
5acf3f |
"version='%s') with machine_id='%s'" %
|
|
Packit |
5acf3f |
(entry.title, entry.version, entry.machine_id))
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Attempt to match by uname pattern
|
|
Packit |
5acf3f |
for hp in _host_profiles:
|
|
Packit |
5acf3f |
if hp.machine_id == entry.machine_id:
|
|
Packit |
5acf3f |
_log_debug("Matched BootEntry(version='%s', boot_id='%s') "
|
|
Packit |
5acf3f |
"to HostProfile(name='%s', machine_id='%s')" %
|
|
Packit |
5acf3f |
(entry.version, entry.disp_boot_id, hp.host_name,
|
|
Packit |
5acf3f |
hp.machine_id))
|
|
Packit |
5acf3f |
return hp
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
return None
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
class HostProfile(BoomProfile):
|
|
Packit |
5acf3f |
""" Class HostProfile implements Boom host system profiles.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Objects of type HostProfile define a host identiry, and optional
|
|
Packit |
5acf3f |
fields or ``BootParams`` modifications to be applied to the
|
|
Packit |
5acf3f |
specified host.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Host profiles may modify any non-identity ``OsProfile`` key,
|
|
Packit |
5acf3f |
either adding to or replacing the value defined by an embedded
|
|
Packit |
5acf3f |
``OsProfile`` instance.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
_profile_data = None
|
|
Packit |
5acf3f |
_unwritten = False
|
|
Packit |
5acf3f |
_comments = None
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_profile_keys = HOST_PROFILE_KEYS
|
|
Packit |
5acf3f |
_required_keys = HOST_REQUIRED_KEYS
|
|
Packit |
5acf3f |
_identity_key = BOOM_HOST_ID
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_osp = None
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _key_data(self, key):
|
|
Packit |
5acf3f |
if key in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[key]
|
|
Packit |
5acf3f |
if key in self.osp._profile_data:
|
|
Packit |
5acf3f |
return self.osp._profile_data[key]
|
|
Packit |
5acf3f |
return None
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _have_key(self, key):
|
|
Packit |
5acf3f |
"""Test for presence of a Host or Os profile key.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return key in self._profile_data or key in self.osp._profile_data
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def __str__(self):
|
|
Packit |
5acf3f |
"""Format this HostProfile as a human readable string.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Profile attributes are printed as "Name: value, " pairs,
|
|
Packit |
5acf3f |
with like attributes grouped together onto lines.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: A human readable string representation of this
|
|
Packit |
5acf3f |
HostProfile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
# FIXME HostProfile breaks
|
|
Packit |
5acf3f |
breaks = [
|
|
Packit |
5acf3f |
BOOM_HOST_ID, BOOM_HOST_NAME, BOOM_OS_ID, BOOM_ENTRY_MACHINE_ID,
|
|
Packit |
5acf3f |
BOOM_HOST_LABEL, BOOM_OS_VERSION, BOOM_OS_UNAME_PATTERN,
|
|
Packit |
5acf3f |
BOOM_HOST_DEL_OPTS, BOOM_OS_INITRAMFS_PATTERN,
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_LVM2, BOOM_OS_ROOT_OPTS_BTRFS, BOOM_OS_OPTIONS
|
|
Packit |
5acf3f |
]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
fields = [f for f in HOST_PROFILE_KEYS if self._have_key(f)]
|
|
Packit |
5acf3f |
hp_str = ""
|
|
Packit |
5acf3f |
tail = ""
|
|
Packit |
5acf3f |
for f in fields:
|
|
Packit |
5acf3f |
hp_str += '%s: "%s"' % (HOST_KEY_NAMES[f], self._key_data(f))
|
|
Packit |
5acf3f |
tail = ",\n" if f in breaks else ", "
|
|
Packit |
5acf3f |
hp_str += tail
|
|
Packit |
5acf3f |
hp_str = hp_str.rstrip(tail)
|
|
Packit |
5acf3f |
return hp_str
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def __repr__(self):
|
|
Packit |
5acf3f |
"""Format this HostProfile as a machine readable string.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return a machine-readable representation of this ``HostProfile``
|
|
Packit |
5acf3f |
object. The string is formatted as a call to the ``HostProfile``
|
|
Packit |
5acf3f |
constructor, with values passed as a dictionary to the
|
|
Packit |
5acf3f |
``profile_data`` keyword argument.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: a string representation of this ``HostProfile``.
|
|
Packit |
5acf3f |
:rtype: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
hp_str = "HostProfile(profile_data={"
|
|
Packit |
5acf3f |
fields = [f for f in HOST_PROFILE_KEYS if self._have_key(f)]
|
|
Packit |
5acf3f |
for f in fields:
|
|
Packit |
5acf3f |
hp_str += '%s:"%s", ' % (f, self._key_data(f))
|
|
Packit |
5acf3f |
hp_str = hp_str.rstrip(", ")
|
|
Packit |
5acf3f |
return hp_str + "})"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def __setitem__(self, key, value):
|
|
Packit |
5acf3f |
"""Set the specified ``HostProfile`` key to the given value.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param key: the ``HostProfile`` key to be set.
|
|
Packit |
5acf3f |
:param value: the value to set for the specified key.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# FIXME: duplicated from OsProfile.__setitem__ -> factor
|
|
Packit |
5acf3f |
# osprofile.check_format_key_value(key, value)
|
|
Packit |
5acf3f |
# and include isstr() key name validation etc.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Map hp key names to a list of format keys which must not
|
|
Packit |
5acf3f |
# appear in that key's value: e.g. %{kernel} in the kernel
|
|
Packit |
5acf3f |
# pattern profile key.
|
|
Packit |
5acf3f |
bad_key_map = {
|
|
Packit |
5acf3f |
BOOM_OS_KERNEL_PATTERN: [FMT_KERNEL],
|
|
Packit |
5acf3f |
BOOM_OS_INITRAMFS_PATTERN: [FMT_INITRAMFS],
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_LVM2: [FMT_ROOT_OPTS],
|
|
Packit |
5acf3f |
BOOM_OS_ROOT_OPTS_BTRFS: [FMT_ROOT_OPTS],
|
|
Packit |
5acf3f |
}
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _check_format_key_value(key, value, bad_keys):
|
|
Packit |
5acf3f |
for bad_key in bad_keys:
|
|
Packit |
5acf3f |
if bad_key in value:
|
|
Packit |
5acf3f |
raise ValueError("HostProfile.%s cannot contain %s"
|
|
Packit |
5acf3f |
% (key, key_from_key_name(bad_key)))
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if not isinstance(key, str):
|
|
Packit |
5acf3f |
raise TypeError("HostProfile key must be a string.")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if key not in HOST_PROFILE_KEYS:
|
|
Packit |
5acf3f |
raise ValueError("Invalid HostProfile key: %s" % key)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if key in bad_key_map:
|
|
Packit |
5acf3f |
_check_format_key_value(key, value, bad_key_map[key])
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._profile_data[key] = value
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _generate_id(self):
|
|
Packit |
5acf3f |
"""Generate a new host identifier.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Generate a new sha1 profile identifier for this profile,
|
|
Packit |
5acf3f |
using the name, machine_id, and os_id and store it in
|
|
Packit |
5acf3f |
_profile_data.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: None
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
hashdata = (self.machine_id + self.label)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
digest = sha1(hashdata.encode('utf-8')).hexdigest()
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_ID] = digest
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def __set_os_profile(self):
|
|
Packit |
5acf3f |
"""Set this ``HostProfile``'s ``osp`` member to the
|
|
Packit |
5acf3f |
corresponding profile for the set ``os_id``.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
os_id = self._profile_data[BOOM_OS_ID]
|
|
Packit |
5acf3f |
osps = find_profiles(Selection(os_id=os_id))
|
|
Packit |
5acf3f |
if not osps:
|
|
Packit |
5acf3f |
raise ValueError("OsProfile not found: %s" % os_id)
|
|
Packit |
5acf3f |
if len(osps) > 1:
|
|
Packit |
5acf3f |
raise ValueError("OsProfile identifier '%s' is ambiguous" % os_id)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self.osp = osps[0]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _append_profile(self):
|
|
Packit |
5acf3f |
"""Append a HostProfile to the global profile list
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles, _host_profiles_by_id, _host_profiles_by_host_id
|
|
Packit |
5acf3f |
if _host_exists(self.host_id):
|
|
Packit |
5acf3f |
raise ValueError("Profile already exists (host_id=%s)" %
|
|
Packit |
5acf3f |
self.disp_host_id)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
_host_profiles.append(self)
|
|
Packit |
5acf3f |
machine_id = self.machine_id
|
|
Packit |
5acf3f |
if machine_id not in _host_profiles_by_id:
|
|
Packit |
5acf3f |
_host_profiles_by_id[machine_id] = {}
|
|
Packit |
5acf3f |
_host_profiles_by_id[machine_id][self.label] = self
|
|
Packit |
5acf3f |
_host_profiles_by_host_id[self.host_id] = self
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _from_data(self, host_data, dirty=True):
|
|
Packit |
5acf3f |
"""Initialise a ``HostProfile`` from in-memory data.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Initialise a new ``HostProfile`` object using the profile
|
|
Packit |
5acf3f |
data in the `host_data` dictionary.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
This method should not be called directly: to build a new
|
|
Packit |
5acf3f |
`Hostprofile`` object from in-memory data, use the class
|
|
Packit |
5acf3f |
initialiser with the ``host_data`` argument.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:returns: None
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
err_str = "Invalid profile data (missing %s)"
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
for key in HOST_REQUIRED_KEYS:
|
|
Packit |
5acf3f |
if key == BOOM_HOST_ID:
|
|
Packit |
5acf3f |
continue
|
|
Packit |
5acf3f |
if key not in host_data:
|
|
Packit |
5acf3f |
raise ValueError(err_str % key)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._profile_data = dict(host_data)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if BOOM_HOST_ID not in self._profile_data:
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self.__set_os_profile()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if dirty:
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._append_profile()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def __init__(self, machine_id=None, host_name=None, label=None, os_id=None,
|
|
Packit |
5acf3f |
kernel_pattern=None, initramfs_pattern=None,
|
|
Packit |
5acf3f |
root_opts_lvm2=None, root_opts_btrfs=None,
|
|
Packit |
5acf3f |
add_opts="", del_opts="",
|
|
Packit |
5acf3f |
options=None, profile_file=None, profile_data=None):
|
|
Packit |
5acf3f |
"""Initialise a new ``HostProfile`` object.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
If neither ``profile_file`` nor ``profile_data`` is given,
|
|
Packit |
5acf3f |
all of ``machine_id``, ``name``, and ``os_id`` must be given.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
These values form the host profile identity and are used to
|
|
Packit |
5acf3f |
generate the profile unique identifier.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param host_name: The hostname of this system
|
|
Packit |
5acf3f |
:param os_id: An OS identifier specifying the ``OsProfile``
|
|
Packit |
5acf3f |
to use with this host profile.
|
|
Packit |
5acf3f |
:param profile_data: An optional dictionary mapping from
|
|
Packit |
5acf3f |
``BOOM_*`` keys to profile values.
|
|
Packit |
5acf3f |
:param profile_file: An optional path to a file from which
|
|
Packit |
5acf3f |
profile data should be loaded. The file
|
|
Packit |
5acf3f |
should be in Boom host profile format,
|
|
Packit |
5acf3f |
with ``BOOM_*`` key=value pairs.
|
|
Packit |
5acf3f |
:returns: A new ``HostProfile`` object.
|
|
Packit |
5acf3f |
:rtype: class HostProfile
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles
|
|
Packit |
5acf3f |
self._profile_data = {}
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Initialise BoomProfile base class
|
|
Packit |
5acf3f |
super(HostProfile, self).__init__(HOST_PROFILE_KEYS,
|
|
Packit |
5acf3f |
HOST_REQUIRED_KEYS, BOOM_HOST_ID)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if profile_data and profile_file:
|
|
Packit |
5acf3f |
raise ValueError("Only one of 'profile_data' or 'profile_file' "
|
|
Packit |
5acf3f |
"may be specified.")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if profile_data:
|
|
Packit |
5acf3f |
self._from_data(profile_data)
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
if profile_file:
|
|
Packit |
5acf3f |
self._from_file(profile_file)
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
required_args = [machine_id, host_name, os_id]
|
|
Packit |
5acf3f |
if any([not val for val in required_args]):
|
|
Packit |
5acf3f |
raise ValueError("Invalid host profile arguments: machine_id, "
|
|
Packit |
5acf3f |
"host_name, and os_id are mandatory.")
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
osps = find_profiles(Selection(os_id=os_id))
|
|
Packit |
5acf3f |
if not osps:
|
|
Packit |
5acf3f |
raise ValueError("No matching profile found for os_id=%s" % os_id)
|
|
Packit |
5acf3f |
if len(osps) > 1:
|
|
Packit |
5acf3f |
raise ValueError("OsProfile ID is ambiguous: %s" % os_id)
|
|
Packit |
5acf3f |
os_id = osps[0].os_id
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._profile_data[BOOM_ENTRY_MACHINE_ID] = machine_id
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_NAME] = host_name
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ID] = os_id
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_LABEL] = label
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Only set keys that have a value in the host profile data dict
|
|
Packit |
5acf3f |
if kernel_pattern:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_KERNEL_PATTERN] = kernel_pattern
|
|
Packit |
5acf3f |
if initramfs_pattern:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_INITRAMFS_PATTERN] = initramfs_pattern
|
|
Packit |
5acf3f |
if root_opts_lvm2:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ROOT_OPTS_LVM2] = root_opts_lvm2
|
|
Packit |
5acf3f |
if root_opts_btrfs:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ROOT_OPTS_BTRFS] = root_opts_btrfs
|
|
Packit |
5acf3f |
if add_opts:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_ADD_OPTS] = add_opts
|
|
Packit |
5acf3f |
if del_opts:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_DEL_OPTS] = del_opts
|
|
Packit |
5acf3f |
if options:
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_OPTIONS] = options
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self.__set_os_profile()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
_host_profiles.append(self)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# We use properties for the HostProfile attributes: this is to
|
|
Packit |
5acf3f |
# allow the values to be stored in a dictionary. Although
|
|
Packit |
5acf3f |
# properties are quite verbose this reduces the code volume
|
|
Packit |
5acf3f |
# and complexity needed to marshal and unmarshal the various
|
|
Packit |
5acf3f |
# file formats used, as well as conversion to and from string
|
|
Packit |
5acf3f |
# representations of HostProfile objects.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Keys obtained from os-release data form the profile's identity:
|
|
Packit |
5acf3f |
# the corresponding attributes are read-only.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# HostProfile properties:
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Profile identity properties (ro):
|
|
Packit |
5acf3f |
# host_id
|
|
Packit |
5acf3f |
# disp_os_id
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Profile identity properties (rw):
|
|
Packit |
5acf3f |
# host_name
|
|
Packit |
5acf3f |
# machine_id
|
|
Packit |
5acf3f |
# os_id
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Properties mapped to OsProfile (ro)
|
|
Packit |
5acf3f |
# os_name
|
|
Packit |
5acf3f |
# os_short_name
|
|
Packit |
5acf3f |
# os_version
|
|
Packit |
5acf3f |
# os_version_id
|
|
Packit |
5acf3f |
# uname_pattern
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Properties overridden or mapped to OsProfile (rw)
|
|
Packit |
5acf3f |
# kernel_pattern
|
|
Packit |
5acf3f |
# initramfs_pattern
|
|
Packit |
5acf3f |
# root_opts_lvm2
|
|
Packit |
5acf3f |
# root_opts_btrfs
|
|
Packit |
5acf3f |
# options
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# HostProfile specific properties (rw)
|
|
Packit |
5acf3f |
# label
|
|
Packit |
5acf3f |
# add_opts
|
|
Packit |
5acf3f |
# del_opts
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def disp_os_id(self):
|
|
Packit |
5acf3f |
"""The display os_id of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return the shortest prefix of this OsProfile's os_id that
|
|
Packit |
5acf3f |
is unique within the current set of loaded profiles.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: return this OsProfile's os_id.
|
|
Packit |
5acf3f |
:type: str
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.disp_os_id
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def host_id(self):
|
|
Packit |
5acf3f |
if BOOM_HOST_ID not in self._profile_data:
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_HOST_ID]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def disp_host_id(self):
|
|
Packit |
5acf3f |
"""The display host_id of this profile
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return the shortest prefix of this HostProfile's os_id that
|
|
Packit |
5acf3f |
is unique within the current set of loaded profiles.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: return this HostProfile's display host_id.
|
|
Packit |
5acf3f |
:type: str
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.host_id[:min_host_id_width()]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def disp_machine_id(self):
|
|
Packit |
5acf3f |
"""The machine_id of this host profile.
|
|
Packit |
5acf3f |
Return the shortest prefix of this HostProfile's os_id that
|
|
Packit |
5acf3f |
is unique within the current set of loaded profiles.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: return this HostProfile's display host_id.
|
|
Packit |
5acf3f |
:type: str
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.machine_id[:min_machine_id_width()]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def machine_id(self):
|
|
Packit |
5acf3f |
"""The machine_id of this host profile.
|
|
Packit |
5acf3f |
Return the shortest prefix of this HostProfile's os_id that
|
|
Packit |
5acf3f |
is unique within the current set of loaded profiles.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: return this ``HostProfile``'s display host_id.
|
|
Packit |
5acf3f |
:setter: change this ``HostProfile``'s ``machine_id``. This
|
|
Packit |
5acf3f |
will change the ``host_id``.
|
|
Packit |
5acf3f |
:type: str
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_ENTRY_MACHINE_ID]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@machine_id.setter
|
|
Packit |
5acf3f |
def machine_id(self, value):
|
|
Packit |
5acf3f |
if value == self._profile_data[BOOM_ENTRY_MACHINE_ID]:
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
self._profile_data[BOOM_ENTRY_MACHINE_ID] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def os_id(self):
|
|
Packit |
5acf3f |
"""The ``os_id`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``os_id`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.os_id
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@os_id.setter
|
|
Packit |
5acf3f |
def os_id(self, value):
|
|
Packit |
5acf3f |
if value == self._profile_data[BOOM_OS_ID]:
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ID] = value
|
|
Packit |
5acf3f |
self.__set_os_profile()
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def osp(self):
|
|
Packit |
5acf3f |
"""The ``OsProfile`` used by this ``HostProfile``.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``OsProfile`` object used by this
|
|
Packit |
5acf3f |
``HostProfile``.
|
|
Packit |
5acf3f |
:setter: stores a new ``OsProfile`` for use by this
|
|
Packit |
5acf3f |
``HostProfile`` and updates the stored ``os_id``
|
|
Packit |
5acf3f |
value in the host profile.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self._osp
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@osp.setter
|
|
Packit |
5acf3f |
def osp(self, osp):
|
|
Packit |
5acf3f |
if self._osp and osp.os_id == self._osp.os_id:
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
self._osp = osp
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ID] = osp.os_id
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def host_name(self):
|
|
Packit |
5acf3f |
"""The ``host_name`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Normally set to the hostname of the system corresponding to
|
|
Packit |
5acf3f |
this ``HostProfile``.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``host_name`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_HOST_NAME]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@host_name.setter
|
|
Packit |
5acf3f |
def host_name(self, value):
|
|
Packit |
5acf3f |
if value == self._profile_data[BOOM_HOST_NAME]:
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_NAME] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def short_name(self):
|
|
Packit |
5acf3f |
"""The ``short_name`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
If ``HostProfile.host_name`` appears to contain a DNS-style name,
|
|
Packit |
5acf3f |
return only the host portion.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``short_name`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
host_name = self._profile_data[BOOM_HOST_NAME]
|
|
Packit |
5acf3f |
return host_name.split(".")[0] if "." in host_name else host_name
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Properties mapped to OsProfile
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def os_name(self):
|
|
Packit |
5acf3f |
"""The ``os_name`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``os_name`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.os_name
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def os_short_name(self):
|
|
Packit |
5acf3f |
"""The ``os_short_name`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``os_short_name`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.os_short_name
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def os_version(self):
|
|
Packit |
5acf3f |
"""The ``os_version`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``os_version`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.os_version
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def os_version_id(self):
|
|
Packit |
5acf3f |
"""The ``os_version_id`` of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``os_version_id`` as a string.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
return self.osp.os_version_id
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def uname_pattern(self):
|
|
Packit |
5acf3f |
"""The current ``uname_pattern`` setting of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``uname_pattern`` as a string.
|
|
Packit |
5acf3f |
:setter: stores a new ``uname_pattern`` setting.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_UNAME_PATTERN in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_UNAME_PATTERN]
|
|
Packit |
5acf3f |
return self.osp.uname_pattern
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# Properties overridden or mapped to OsProfile
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def kernel_pattern(self):
|
|
Packit |
5acf3f |
"""The current ``kernel_pattern`` setting of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``kernel_pattern`` as a string.
|
|
Packit |
5acf3f |
:setter: stores a new ``kernel_pattern`` setting.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_KERNEL_PATTERN in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_KERNEL_PATTERN]
|
|
Packit |
5acf3f |
return self.osp.kernel_pattern
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@kernel_pattern.setter
|
|
Packit |
5acf3f |
def kernel_pattern(self, value):
|
|
Packit |
5acf3f |
kernel_key = key_from_key_name(FMT_KERNEL)
|
|
Packit |
5acf3f |
if kernel_key in value:
|
|
Packit |
5acf3f |
raise ValueError("HostProfile.kernel cannot contain %s" %
|
|
Packit |
5acf3f |
kernel_key)
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_KERNEL_PATTERN] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def initramfs_pattern(self):
|
|
Packit |
5acf3f |
"""The current ``initramfs_pattern`` setting of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``initramfs_pattern`` as a string.
|
|
Packit |
5acf3f |
:setter: store a new ``initramfs_pattern`` setting.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_INITRAMFS_PATTERN in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_INITRAMFS_PATTERN]
|
|
Packit |
5acf3f |
return self.osp.initramfs_pattern
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@initramfs_pattern.setter
|
|
Packit |
5acf3f |
def initramfs_pattern(self, value):
|
|
Packit |
5acf3f |
initramfs_key = key_from_key_name(FMT_INITRAMFS)
|
|
Packit |
5acf3f |
if initramfs_key in value:
|
|
Packit |
5acf3f |
raise ValueError("HostProfile.initramfs cannot contain %s" %
|
|
Packit |
5acf3f |
initramfs_key)
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_INITRAMFS_PATTERN] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def root_opts_lvm2(self):
|
|
Packit |
5acf3f |
"""The current LVM2 root options setting of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``root_opts_lvm2`` value as a string.
|
|
Packit |
5acf3f |
:setter: store a new ``root_opts_lvm2`` value.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_ROOT_OPTS_LVM2 in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_ROOT_OPTS_LVM2]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
return self.osp.root_opts_lvm2
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@root_opts_lvm2.setter
|
|
Packit |
5acf3f |
def root_opts_lvm2(self, value):
|
|
Packit |
5acf3f |
root_opts_key = key_from_key_name(FMT_ROOT_OPTS)
|
|
Packit |
5acf3f |
if root_opts_key in value:
|
|
Packit |
5acf3f |
raise ValueError("HostProfile.root_opts_lvm2 cannot contain ""%s" %
|
|
Packit |
5acf3f |
root_opts_key)
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ROOT_OPTS_LVM2] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def root_opts_btrfs(self):
|
|
Packit |
5acf3f |
"""The current BTRFS root options setting of this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``root_opts_btrfs`` value as a string.
|
|
Packit |
5acf3f |
:setter: store a new ``root_opts_btrfs`` value.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_ROOT_OPTS_BTRFS in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_ROOT_OPTS_BTRFS]
|
|
Packit |
5acf3f |
return self.osp.root_opts_btrfs
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@root_opts_btrfs.setter
|
|
Packit |
5acf3f |
def root_opts_btrfs(self, value):
|
|
Packit |
5acf3f |
root_opts_key = key_from_key_name(FMT_ROOT_OPTS)
|
|
Packit |
5acf3f |
if root_opts_key in value:
|
|
Packit |
5acf3f |
raise ValueError("HostProfile.root_opts_btrfs cannot contain %s" %
|
|
Packit |
5acf3f |
root_opts_key)
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_ROOT_OPTS_BTRFS] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def options(self):
|
|
Packit |
5acf3f |
"""The current kernel command line options setting for this
|
|
Packit |
5acf3f |
profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``options`` value as a string.
|
|
Packit |
5acf3f |
:setter: store a new ``options`` value.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_OPTIONS in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_OPTIONS]
|
|
Packit |
5acf3f |
return self.osp.options
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@options.setter
|
|
Packit |
5acf3f |
def options(self, value):
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_OPTIONS] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def title(self):
|
|
Packit |
5acf3f |
"""The current title template for this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:getter: returns the ``title`` value as a string.
|
|
Packit |
5acf3f |
:setter: store a new ``title`` value.
|
|
Packit |
5acf3f |
:type: string
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if BOOM_OS_TITLE not in self._profile_data:
|
|
Packit |
5acf3f |
return None
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_OS_TITLE]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@title.setter
|
|
Packit |
5acf3f |
def title(self, value):
|
|
Packit |
5acf3f |
if not value:
|
|
Packit |
5acf3f |
# It is valid to set an empty title in a HostProfile as long
|
|
Packit |
5acf3f |
# as the OsProfile defines one.
|
|
Packit |
5acf3f |
if not self.osp or not self.osp.title:
|
|
Packit |
5acf3f |
raise ValueError("Entry title cannot be empty")
|
|
Packit |
5acf3f |
self._profile_data[BOOM_OS_TITLE] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def optional_keys(self):
|
|
Packit |
5acf3f |
if not self.osp or not self.osp.optional_keys:
|
|
Packit |
5acf3f |
return ""
|
|
Packit |
5acf3f |
return self.osp.optional_keys
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
# HostProfile specific properties
|
|
Packit |
5acf3f |
#
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def add_opts(self):
|
|
Packit |
5acf3f |
if BOOM_HOST_ADD_OPTS in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_HOST_ADD_OPTS]
|
|
Packit |
5acf3f |
return ""
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@add_opts.setter
|
|
Packit |
5acf3f |
def add_opts(self, opts):
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_ADD_OPTS] = opts
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def del_opts(self):
|
|
Packit |
5acf3f |
if BOOM_HOST_DEL_OPTS in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_HOST_DEL_OPTS]
|
|
Packit |
5acf3f |
return ""
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@del_opts.setter
|
|
Packit |
5acf3f |
def del_opts(self, opts):
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_DEL_OPTS] = opts
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@property
|
|
Packit |
5acf3f |
def label(self):
|
|
Packit |
5acf3f |
if BOOM_HOST_LABEL in self._profile_data:
|
|
Packit |
5acf3f |
return self._profile_data[BOOM_HOST_LABEL]
|
|
Packit |
5acf3f |
return ""
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
@label.setter
|
|
Packit |
5acf3f |
def label(self, value):
|
|
Packit |
5acf3f |
valid_chars = string.ascii_letters + string.digits + "_- "
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
if BOOM_HOST_LABEL in self._profile_data:
|
|
Packit |
5acf3f |
if self._profile_data[BOOM_HOST_LABEL] == value:
|
|
Packit |
5acf3f |
return
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
for c in value:
|
|
Packit |
5acf3f |
if c not in valid_chars:
|
|
Packit |
5acf3f |
raise ValueError("Invalid host label character: '%s'" % c)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
self._profile_data[BOOM_HOST_LABEL] = value
|
|
Packit |
5acf3f |
self._dirty()
|
|
Packit |
5acf3f |
self._generate_id()
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def _profile_path(self):
|
|
Packit |
5acf3f |
"""Return the path to this profile's on-disk data.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Return the full path to this HostProfile in the Boom profiles
|
|
Packit |
5acf3f |
directory (or the location to which it will be written, if
|
|
Packit |
5acf3f |
it has not yet been written).
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: str
|
|
Packit |
5acf3f |
:returns: The absolute path for this HostProfile's file
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
if self.label:
|
|
Packit |
5acf3f |
label = self.label
|
|
Packit |
5acf3f |
if " " in label:
|
|
Packit |
5acf3f |
label = label.replace(" ", "_")
|
|
Packit |
5acf3f |
names = (self.short_name, label)
|
|
Packit |
5acf3f |
name_fmt = "%s-%s"
|
|
Packit |
5acf3f |
else:
|
|
Packit |
5acf3f |
names = (self.short_name)
|
|
Packit |
5acf3f |
name_fmt = "%s"
|
|
Packit |
5acf3f |
profile_name = name_fmt % names
|
|
Packit |
5acf3f |
profile_id = (self.host_id, profile_name)
|
|
Packit |
5acf3f |
profile_path_name = BOOM_HOST_PROFILE_FORMAT % profile_id
|
|
Packit |
5acf3f |
return path_join(boom_host_profiles_path(), profile_path_name)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def write_profile(self, force=False):
|
|
Packit |
5acf3f |
"""Write out profile data to disk.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Write out this ``HostProfile``'s data to a file in Boom
|
|
Packit |
5acf3f |
format to the paths specified by the current configuration.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Currently the ``machine_id`` and ``name`` keys are used to
|
|
Packit |
5acf3f |
construct the file name.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
If the value of ``force`` is ``False`` and the ``HostProfile``
|
|
Packit |
5acf3f |
is not currently marked as dirty (either new, or modified
|
|
Packit |
5acf3f |
since the last load operation) the write will be skipped.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:param force: Force this profile to be written to disk even
|
|
Packit |
5acf3f |
if the entry is unmodified.
|
|
Packit |
5acf3f |
:raises: ``OsError`` if the temporary entry file cannot be
|
|
Packit |
5acf3f |
renamed, or if setting file permissions on the
|
|
Packit |
5acf3f |
new entry file fails.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
path = boom_host_profiles_path()
|
|
Packit |
5acf3f |
mode = BOOM_HOST_PROFILE_MODE
|
|
Packit |
5acf3f |
self._write_profile(self.host_id, path, mode, force=force)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
def delete_profile(self):
|
|
Packit |
5acf3f |
"""Delete on-disk data for this profile.
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
Remove the on-disk profile corresponding to this
|
|
Packit |
5acf3f |
``HostProfile`` object. This will permanently erase the
|
|
Packit |
5acf3f |
current file (although the current data may be re-written at
|
|
Packit |
5acf3f |
any time by calling ``write_profile()`` before the object is
|
|
Packit |
5acf3f |
disposed of).
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
:rtype: ``NoneType``
|
|
Packit |
5acf3f |
:raises: ``OsError`` if an error occurs removing the file or
|
|
Packit |
5acf3f |
``ValueError`` if the profile does not exist.
|
|
Packit |
5acf3f |
"""
|
|
Packit |
5acf3f |
global _host_profiles, _host_profiles_by_id, _host_profiles_by_host_id
|
|
Packit |
5acf3f |
self._delete_profile(self.host_id)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
machine_id = self.machine_id
|
|
Packit |
5acf3f |
host_id = self.host_id
|
|
Packit |
5acf3f |
if _host_profiles and self in _host_profiles:
|
|
Packit |
5acf3f |
_host_profiles.remove(self)
|
|
Packit |
5acf3f |
if _host_profiles_by_id and machine_id in _host_profiles_by_id:
|
|
Packit |
5acf3f |
_host_profiles_by_id.pop(machine_id)
|
|
Packit |
5acf3f |
if _host_profiles_by_host_id and host_id in _host_profiles_by_host_id:
|
|
Packit |
5acf3f |
_host_profiles_by_host_id.pop(host_id)
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
__all__ = [
|
|
Packit |
5acf3f |
# Host profiles
|
|
Packit |
5acf3f |
'HostProfile',
|
|
Packit |
5acf3f |
'drop_host_profiles', 'load_host_profiles', 'write_host_profiles',
|
|
Packit |
5acf3f |
'host_profiles_loaded', 'find_host_profiles', 'select_host_profile',
|
|
Packit |
5acf3f |
'get_host_profile_by_id', 'match_host_profile', 'select_host_profile',
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Host profile keys
|
|
Packit |
5acf3f |
'BOOM_HOST_ID', 'BOOM_HOST_NAME',
|
|
Packit |
5acf3f |
'BOOM_HOST_ADD_OPTS', 'BOOM_HOST_DEL_OPTS', 'BOOM_HOST_LABEL',
|
|
Packit |
5acf3f |
'HOST_PROFILE_KEYS', 'HOST_REQUIRED_KEYS', 'HOST_OPTIONAL_KEYS',
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# Path configuration
|
|
Packit |
5acf3f |
'boom_host_profiles_path',
|
|
Packit |
5acf3f |
]
|
|
Packit |
5acf3f |
|
|
Packit |
5acf3f |
# vim: set et ts=4 sw=4 :
|