Source code for libioc.errors

# Copyright (c) 2017-2019, Stefan Grönke
# Copyright (c) 2014-2018, iocage
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted providing that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""Collection of iocage errors."""
import typing

# MyPy
import libzfs  # noqa: F401
import libioc.Types  # noqa: F401
import libioc.Logger


[docs]class IocException(Exception): """A well-known exception raised by liblibioc.""" def __init__( self, message: str, level: str="error", silent: bool=False, append_warning: bool=False, warning: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: if (logger is not None) and (silent is False): logger.__getattribute__(level)(message) if (append_warning is True) and (warning is not None): logger.warn(warning) else: super().__init__(message)
# Missing Features
[docs]class MissingFeature(IocException, NotImplementedError): """Raised when an iocage feature is not fully implemented yet.""" def __init__( self, feature_name: str, plural: bool=False, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: message = ( f"Missing Feature: '{feature_name}' " f"{'are' if plural is True else 'is'} not implemented yet" ) IocException.__init__(self, message=message)
# Jails
[docs]class JailException(IocException): """Raised when an exception related to a jail occurs.""" jail: 'libioc.Jail.JailGenerator' def __init__( self, jail: 'libioc.Jail.JailGenerator', message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: self.jail = jail IocException.__init__(self, message=message, logger=logger)
[docs]class JailDoesNotExist(JailException): """Raised when the jail does not exist.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail '{jail.humanreadable_name}' does not exist" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailAlreadyExists(IocException): """Raised when the jail already exists.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail '{jail.humanreadable_name}' already exists" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailNotRunning(IocException): """Raised when the jail is not running.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail '{jail.humanreadable_name}' is not running" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailAlreadyRunning(IocException): """Raised when the jail is already running.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail '{jail.humanreadable_name}' is already running" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailNotFound(IocException): """Raised when the jail was not found.""" def __init__( self, text: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"No jail matching '{text}' was found" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailNotSupplied(IocException): """Raised when no jail was supplied.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Please supply a jail" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailUnknownIdentifier(IocException): """Raised when the jail has an unknown identifier.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The jail has no identifier yet" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailBackendMissing(IocException): """Raised when the jails backend was not found.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The jail backend is unknown" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailIsTemplate(JailException): """Raised when the jail is a template but should not be.""" jail: 'libioc.Jail.JailGenerator' def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The jail '{jail.name}' is a template" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailNotTemplate(JailException): """Raised when the jail is no template but should be one.""" jail: 'libioc.Jail.JailGenerator' def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The jail '{jail.full_name}' is not a template" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailHookFailed(JailException): """Raised when the jail could not be launched.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', hook: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: self.hook = hook msg = f"Jail {jail.full_name} hook {hook} failed" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailLaunchFailed(JailException): """Raised when the jail could not be launched.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Launching jail {jail.full_name} failed" if reason is not None: msg += f": {reason}" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailDestructionFailed(JailException): """Raised when the jail could not be destroyed.""" jail: 'libioc.Jail.JailGenerator' def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Destroying jail {jail.full_name} failed" JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailCommandFailed(IocException): """Raised when a jail command fails with an exit code > 0.""" returncode: int def __init__( self, returncode: int, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: self.returncode = returncode msg = f"Jail command exited with {returncode}" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailExecutionAborted(JailException): """Raised when a jail command fails with an exit code > 0.""" def __init__( self, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail execution of {jail.humanreadable_name} aborted" JailException.__init__(self, message=msg, jail=jail, logger=logger)
# Jail State
[docs]class JailStateUpdateFailed(IocException): """Raised when a JLS query failed.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"JLS query failed" IocException.__init__(self, message=msg, logger=logger)
# Jail Fstab
[docs]class VirtualFstabLineHasNoRealIndex(IocException): """Raised when attempting to access the index of a virtual fstab line.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The virtual fstab line does not have a real list index" IocException.__init__(self, message=msg, logger=logger)
[docs]class FstabDestinationExists(IocException): """Raised when the destination directory does not exist.""" def __init__( self, mountpoint: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The mountpoint {mountpoint} already exists in the fstab file" IocException.__init__(self, message=msg, logger=logger)
# Security
[docs]class SecurityViolation(IocException): """Raised when iocage has security concerns.""" def __init__( self, reason: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Security violation: {reason}" IocException.__init__(self, message=msg, logger=logger)
[docs]class InsecureJailPath(SecurityViolation): """Raised when a a path points outside of a resource.""" def __init__( self, path: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Insecure path {path} jail escape attempt" SecurityViolation.__init__(self, reason=msg)
[docs]class SecurityViolationConfigJailEscape(SecurityViolation): """Raised when a file symlinks to a location outside of the jail.""" def __init__( self, file: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The file {file} references a file outsite of the jail resource" SecurityViolation.__init__(self, reason=msg)
[docs]class IllegalArchiveContent(IocException): """Raised when a release asset archive contains malicious content.""" def __init__( self, asset_name: str, reason: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Asset {asset_name} contains illegal files - {reason}" super().__init__(message=msg, logger=logger)
# JailConfig
[docs]class JailConfigError(IocException): """Raised when a general configuration error occurs.""" pass
[docs]class InvalidJailName(JailConfigError): """Raised when a jail has an invalid name.""" def __init__( self, name: str, invalid_characters: typing.Optional[typing.List[str]]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( f"Invalid jail name '{name}': " "Names may only contain alphanumeric characters and dash" ) if invalid_characters is not None: msg += ", but got " + str("".join(invalid_characters) + "") super().__init__(message=msg, logger=logger)
[docs]class JailConigZFSIsNotAllowed(JailConfigError): """Raised when a jail is not allowed to use ZFS shares.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( "jail_zfs is disabled " "despite jail_zfs_dataset is configured" ) super().__init__(message=msg, logger=logger)
[docs]class InvalidJailConfigValue(JailConfigError, ValueError): """Raised when a jail configuration value is invalid.""" def __init__( self, property_name: str, jail: typing.Optional['libioc.Jail.JailGenerator']=None, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error" ) -> None: msg = f"Invalid value for property '{property_name}'" if jail is not None: msg += f" of jail {jail.humanreadable_name}" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger, level=level)
[docs]class InvalidJailConfigAddress(InvalidJailConfigValue): """Raised when a jail address is invalid.""" def __init__( self, value: str, property_name: str, jail: typing.Optional['libioc.Jail.JailGenerator']=None, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error" ) -> None: reason = f"expected \"<nic>|<address>\" but got \"{value}\"" super().__init__( property_name=property_name, jail=jail, reason=reason, level=level, logger=logger )
[docs]class InvalidMacAddress(IocException, ValueError): """Raised when a jail MAC address is invalid.""" def __init__( self, mac_address: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: reason = f"invalid mac address: \"{mac_address}\"" IocException.__init__( self, message=reason )
[docs]class ResourceLimitUnknown(IocException, KeyError): """Raised when a resource limit has is unknown.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The specified resource limit is unknown" IocException.__init__(self, message=msg, logger=logger)
[docs]class ResourceLimitActionFailed(IocException, KeyError): """Raised when a resource limit has is unknown.""" def __init__( self, action: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Resource Limit failed to {action}" IocException.__init__(self, message=msg, logger=logger)
[docs]class JailHostIdMismatch(JailException): """Raised when attempting to start a jail with mismatching hostid.""" def __init__( self, host_hostid: str, jail: 'libioc.Jail.JailGenerator', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: jail_hostid = jail.config["hostid"] msg = ( f"The jail hostid '{jail_hostid}' " f"does not match the hosts hostid '{host_hostid}'" ) JailException.__init__(self, message=msg, jail=jail, logger=logger)
[docs]class JailConfigNotFound(IocException): """Raised when a jail is not configured.""" def __init__( self, config_type: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Could not read {config_type} config" # This is a silent error internally used IocException.__init__(self, message=msg, logger=logger)
[docs]class DefaultConfigNotFound(IocException, FileNotFoundError): """Raised when no default config was found on the host.""" def __init__( self, config_file_path: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Default configuration not found at {config_file_path}" IocException.__init__(self, message=msg, logger=logger)
[docs]class UnknownConfigProperty(IocException, KeyError): """Raised when a unknown jail config property was used.""" def __init__( self, key: str, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error", jail: typing.Optional['libioc.Jail.JailGenerator']=None ) -> None: if jail is None: msg = f"The config property '{key}' is unknown" else: msg = ( f"The config property '{key}' of jail '{jail.name}' is unknown" ) self.jail = jail IocException.__init__( self, message=msg, logger=logger, level=level )
# Backup
[docs]class BackupInProgress(IocException): """Raised when a backup operation is already in progress.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "A backup operation is already in progress" IocException.__init__(self, message=msg, logger=logger)
[docs]class ExportDestinationExists(IocException): """Raised when a backup operation is already in progress.""" def __init__( self, destination: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The backup destination {destination} already exists" IocException.__init__(self, message=msg, logger=logger)
[docs]class BackupSourceDoesNotExist(IocException): """Raised when a backup source is not available for import.""" def __init__( self, source: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The backup source {source} does not exists" IocException.__init__(self, message=msg, logger=logger)
[docs]class BackupSourceUnknownFormat(IocException): """Raised when a backup source is in unknown format.""" def __init__( self, source: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The backup source {source} has unknown type" IocException.__init__(self, message=msg, logger=logger)
# ListableResource
[docs]class ListableResourceNamespaceUndefined(IocException): """Raised when a ListableResource was not defined with a namespace.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The ListableResource needs a namespace for this operation" IocException.__init__(self, message=msg, logger=logger)
# General
[docs]class IocageNotActivated(IocException): """Raised when iocage is not active on any ZFS pool.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( "iocage is not activated yet - " "please run `ioc activate <POOL>` first and select a pool" ) super().__init__(message=msg, logger=logger)
[docs]class ActivationFailed(IocException): """Raised when ZFS pool activation failed.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "iocage ZFS pool activation failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class ZFSSourceMountpoint(IocException): """Raised when iocage could not determine its mountpoint.""" def __init__( self, dataset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( f"Mountpoint of iocage ZFS source dataset '{dataset_name}'" " is unset and cannot be determined automatically" ) super().__init__(message=msg, logger=logger)
[docs]class InvalidLogLevel(IocException): """Raised when the logger was initialized with an invalid log level.""" def __init__( self, log_level: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: available_log_levels = libioc.Logger.Logger.LOG_LEVELS available_log_levels_string = ", ".join(available_log_levels[:-1]) msg = ( f"Invalid log-level {log_level}. Choose one of " f"{available_log_levels_string} or {available_log_levels[-1]}" ) super().__init__(message=msg, logger=logger)
[docs]class MustBeRoot(IocException): """Raised when iocage is executed without root permission.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: _msg = ( f"Must be root to {message}" ) super().__init__(message=_msg, logger=logger)
[docs]class CommandFailure(IocException): """Raised when iocage fails to execute a command.""" def __init__( self, returncode: int, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Command exited with {returncode}" super().__init__(message=msg, logger=logger)
[docs]class NotAnIocageZFSProperty(IocException): """Raised when iocage attempts to touch a non-iocage ZFS property.""" def __init__( self, property_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The ZFS property '{property_name}' is not managed by iocage" super().__init__(message=msg, logger=logger)
# Host, Distribution
[docs]class DistributionUnknown(IocException): """Raised when the host distribution is unknown or not supported.""" def __init__( self, distribution_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Unknown Distribution: {distribution_name}" super().__init__(message=msg, logger=logger)
[docs]class HostReleaseUnknown(IocException): """Raised when the host release could not be determined.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The host release is unknown" super().__init__(message=msg, logger=logger)
[docs]class HostUserlandVersionUnknown(IocException): """Raised when the hosts userland version could not be detected.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Could not determine the hosts userland version" super().__init__(message=msg, logger=logger)
[docs]class DownloadFailed(IocException): """Raised when downloading EOL warnings failed.""" def __init__( self, url: str, code: int, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error" ) -> None: msg = f"Failed downloading {url}: {code}" super().__init__(message=msg, logger=logger, level=level)
# Storage
[docs]class DatasetExists(IocException): """Raised when a dataset already exists.""" def __init__( self, dataset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Dataset already exists: {dataset_name}" super().__init__(message=msg, logger=logger)
[docs]class UnmountFailed(IocException): """Raised when an unmount operation fails.""" def __init__( self, mountpoint: typing.Any=None, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: if mountpoint is None: msg = "Umount failed" else: msg = f"Unmount of {mountpoint} failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class MountFailed(IocException): """Raised when a mount operation fails.""" def __init__( self, mountpoint: libioc.Types.AbsolutePath, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Failed to mount {mountpoint}" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class InvalidMountpoint(IocException): """Raised when a mountpoint was invalid or not found.""" def __init__( self, mountpoint: libioc.Types.AbsolutePath, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Invalid mountpoint {mountpoint}" super().__init__(message=msg, logger=logger)
[docs]class DatasetNotMounted(IocException): """Raised when a dataset is not mounted but should be.""" def __init__( self, dataset: 'libzfs.ZFSDataset', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Dataset '{dataset.name}' is not mounted" super().__init__(message=msg, logger=logger)
[docs]class DatasetNotAvailable(IocException): """Raised when a dataset is not available.""" def __init__( self, dataset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Dataset '{dataset_name}' is not available" super().__init__(message=msg, logger=logger)
[docs]class DatasetNotJailed(IocException): """Raised when a ZFS share was not flagged as such.""" def __init__( self, dataset: 'libzfs.ZFSDataset', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: name = dataset.name msg = f"Dataset {name} is not jailed." warning = f"Run 'zfs set jailed=on {name}' to allow mounting" super().__init__( msg, warning=warning, append_warning=True )
[docs]class ZFSException(IocException): """Raised when a ZFS pool not available.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: super().__init__(message=message, logger=logger)
[docs]class ZFSPoolInvalid(IocException, TypeError): """Raised when a ZFS pool is invalid.""" def __init__( self, consequence: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Invalid ZFS pool" if consequence is not None: msg += f": {consequence}" IocException.__init__(self, message=msg, logger=logger)
[docs]class ZFSPoolUnavailable(IocException): """Raised when a ZFS pool not available.""" def __init__( self, pool_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"ZFS pool '{pool_name}' is UNAVAIL" super().__init__(message=msg, logger=logger)
[docs]class ResourceUnmanaged(IocException): """Raised when locating a resources dataset on a root dataset fails.""" def __init__( self, dataset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The resource dataset {dataset_name} is not managed by iocage" super().__init__(message=msg, logger=logger)
[docs]class ConflictingResourceSelection(IocException): """Raised when a resource was configured with conflicting sources.""" def __init__( self, source_a: str, source_b: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( "The resource was configured with conflicting root sources: " f"{source_a} != {source_b}" ) super().__init__(message=msg, logger=logger)
# Snapshots
[docs]class SnapshotError(IocException): """Raised on snapshot related errors.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: super().__init__(message=message, logger=logger)
[docs]class SnapshotCreation(SnapshotError): """Raised when creating a snapshot failed.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Snapshot creation failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class SnapshotDeletion(SnapshotError): """Raised when deleting a snapshot failed.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Snapshot deletion failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class SnapshotRollback(SnapshotError): """Raised when rolling back a snapshot failed.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Snapshot rollback failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class SnapshotNotFound(SnapshotError): """Raised when a snapshot was not found.""" def __init__( self, snapshot_name: str, dataset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Snapshot not found: {dataset_name}@{snapshot_name}" super().__init__(message=msg, logger=logger)
[docs]class InvalidSnapshotIdentifier(SnapshotError): """Raised when a snapshot identifier is invalid.""" def __init__( self, identifier: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( f"Invalid snapshot identifier syntax: {identifier}" "(should be <jail>@<snapshot>)" ) super().__init__(message=msg, logger=logger)
# Network
[docs]class InvalidInterfaceName(IocException): """Raised when a NIC name is invalid.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Invalid NIC name" super().__init__(message=msg, logger=logger)
[docs]class VnetBridgeMissing(IocException): """Raised when a vnet bridge is missing.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "VNET is enabled and requires setting a bridge" super().__init__(message=msg, logger=logger)
[docs]class VnetBridgeDoesNotExist(IocException): """Raised when a vnet bridge is missing.""" def __init__( self, bridge_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"VNET bridge {bridge_name} does not exist" super().__init__(message=msg, logger=logger)
[docs]class InvalidNetworkBridge(IocException, ValueError): """Raised when a network bridge is invalid.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Invalid network bridge argument" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class FirewallDisabled(IocException): """Raised when the firewall is required but disabled (Secure VNET).""" def __init__( self, hint: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "IPFW is disabled" if hint is not None: msg += f": {hint}" super().__init__(message=msg, logger=logger)
[docs]class FirewallCommandFailure(IocException): """Raised when a firewall command fails (Secure VNET).""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Firewall Command failed. Is IPFW enabled?" super().__init__(message=msg, logger=logger)
[docs]class InvalidIPAddress(IocException): """Raised when an invalid IP address was assigned to a network.""" def __init__( self, reason: str, ipv6: bool, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error" ) -> None: ip_version = 4 + 2 * (ipv6 is True) msg = f"Invalid IPv{ip_version} address: {reason}" super().__init__(message=msg, logger=logger, level=level)
# Release
[docs]class ReleaseListUnavailable(IocException): """Raised when the list could not be downloaded from the remote.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The releases list is unavailable" super().__init__(message=msg, logger=logger)
[docs]class ReleaseAssetHashesUnavailable(IocException): """Raised when the list could not be downloaded from the remote.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"The releases asset hashes are unavailable" super().__init__(message=msg, logger=logger)
[docs]class UpdateFailure(IocException): """Raised when an update fails.""" def __init__( self, name: str, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None, level: str="error" ) -> None: msg = f"Release update of '{name}' failed" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger, level=level)
[docs]class InvalidReleaseAssetSignature(UpdateFailure): """Raised when a release signature is invalid.""" def __init__( self, name: str, asset_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Asset {asset_name} has an invalid signature" UpdateFailure.__init__( self, name=name, reason=msg )
[docs]class NonReleaseUpdateFetch(UpdateFailure): """Raised when attempting to fetch updates for a custom release.""" def __init__( self, resource: 'libioc.Resource.Resource', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Updates can only be fetched for releases" UpdateFailure.__init__( self, name=resource.name, reason=msg )
[docs]class ReleaseNotFetched(IocException): """Raised when a release was not yet fetched.""" def __init__( self, name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Release '{name}' does not exist or is not fetched locally" super().__init__(message=msg, logger=logger)
[docs]class ReleaseUpdateBranchLookup(IocException): """Raised when failing to lookup the remote update branch.""" def __init__( self, release_name: str, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Update source of release '{release_name}' not found" if reason is not None: msg += ": {reason}" super().__init__(message=msg, logger=logger)
[docs]class UnsupportedRelease(MissingFeature): """Raised when interacting with an unsupported release.""" def __init__( self, version: float, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: feature_name = f"Support for release version {version}" super().__init__( feature_name=feature_name, plural=True )
[docs]class InvalidReleaseName(IocException): """Raised when interacting with an unsupported release.""" def __init__( self, name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Invalid release name: {name}" super().__init__(message=msg, logger=logger)
# Prompts
[docs]class DefaultReleaseNotFound(IocException): """Raised when the default (host) release does not match a remote.""" def __init__( self, host_release_name: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( f"Release '{host_release_name}' not found: " "Could not determine a default source" ) super().__init__(message=msg, logger=logger)
# DevfsRules
[docs]class DevfsRuleException(IocException): """Raised on errors in devfs rules.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: super().__init__(message=message, logger=logger)
[docs]class InvalidDevfsRulesSyntax(DevfsRuleException): """Raised when a devfs rule has invalid syntax.""" def __init__( self, devfs_rules_file: str, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Invalid devfs rules in {devfs_rules_file}" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class DuplicateDevfsRuleset(DevfsRuleException): """Raised when a duplicate devfs rule was found.""" def __init__( self, devfs_rules_file: str, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Cannot add duplicate ruleset" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
[docs]class MissingDevfsRulesetName(DevfsRuleException): """Raised when a duplicate devfs rule was found.""" def __init__( self, devfs_rules_file: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "The devfs ruleset is missing a name" super().__init__(message=msg, logger=logger)
# Logger
[docs]class LogException(IocException): """Raised when logging fails.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: super().__init__(message=message, logger=logger)
[docs]class CannotRedrawLine(LogException): """Raised when manipulating previous log entries fails.""" def __init__( self, reason: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "Logger can't redraw line" if reason is not None: msg += f": {reason}" super().__init__(message=msg, logger=logger)
# Events
[docs]class EventAlreadyFinished(IocException): """Raised when a event is touched that was already finished.""" def __init__( self, event: 'libioc.events.IocEvent', logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = "This {event.type} event is already finished" IocException.__init__(self, message=msg, logger=logger)
# Jail Filter
[docs]class JailFilterException(IocException): """Raised when a jail filter is invalid.""" def __init__( self, message: str, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: IocException.__init__(self, message=message, logger=logger)
[docs]class JailFilterInvalidName(JailFilterException): """Raised when the name of a jail filter is invalid.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: message = ( "Invalid jail selector: " "Cannot select jail with illegal name" ) JailFilterException.__init__(self, message=message, logger=logger)
# pkg
[docs]class PkgNotFound(IocException): """Raised when the pkg package was not found in the local mirror.""" def __init__( self, message: typing.Optional[str]=None, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: if message is None: message = "The pkg package was not found in the local mirror." IocException.__init__(self, message=message, logger=logger)
# Provisioning
[docs]class UndefinedProvisionerSource(IocException): """Raised when a provisioner source is not set.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Missing provisioner source" IocException.__init__(self, message=msg, logger=logger)
[docs]class UndefinedProvisionerMethod(IocException): """Raised when a provisioner method is not set.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Missing provisioner method" IocException.__init__(self, message=msg, logger=logger)
# Sources
[docs]class InvalidSourceName(IocException): """Raised when a source name is invalid.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = ( "Invalid source name: " "A source name may contain letters A-z, dash and lowdash" ) super().__init__(message=msg, logger=logger)
[docs]class SourceNotFound(IocException): """Raised when a source was not found.""" def __init__( self, logger: typing.Optional['libioc.Logger.Logger']=None ) -> None: msg = f"Jail source not found" super().__init__(message=msg, logger=logger)