mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Convert param docs into parseable format.
This commit is contained in:
parent
ee6df57f3f
commit
ee3fe0bf42
24 changed files with 168 additions and 240 deletions
|
@ -7,10 +7,9 @@ from main import main
|
||||||
def validate_manifest(data, validator, error):
|
def validate_manifest(data, validator, error):
|
||||||
"""Validates the manifest using the base manifest
|
"""Validates the manifest using the base manifest
|
||||||
|
|
||||||
Args:
|
:param dict data: The data of the manifest
|
||||||
data (dict): The data of the manifest
|
:param function validator: The function that validates the manifest given the data and a path
|
||||||
validator (function): The function that validates the manifest given the data and a path
|
:param function error: The function tha raises an error when the validation fails
|
||||||
error (function): The function tha raises an error when the validation fails
|
|
||||||
"""
|
"""
|
||||||
import os.path
|
import os.path
|
||||||
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.json'))
|
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.json'))
|
||||||
|
|
|
@ -9,9 +9,8 @@ class BootstrapInformation(object):
|
||||||
def __init__(self, manifest=None, debug=False):
|
def __init__(self, manifest=None, debug=False):
|
||||||
"""Instantiates a new bootstrap info object.
|
"""Instantiates a new bootstrap info object.
|
||||||
|
|
||||||
Args:
|
:param Manifest manifest: The manifest
|
||||||
manifest (Manifest): The manifest
|
:param bool debug: Whether debugging is turned on
|
||||||
debug (bool): Whether debugging is turned on
|
|
||||||
"""
|
"""
|
||||||
# Set the manifest attribute.
|
# Set the manifest attribute.
|
||||||
self.manifest = manifest
|
self.manifest = manifest
|
||||||
|
@ -74,6 +73,14 @@ class BootstrapInformation(object):
|
||||||
setattr(self, '_' + pluginname, {})
|
setattr(self, '_' + pluginname, {})
|
||||||
|
|
||||||
def __create_manifest_vars(self, manifest, additional_vars={}):
|
def __create_manifest_vars(self, manifest, additional_vars={}):
|
||||||
|
"""Creates the manifest variables dictionary, based on the manifest contents
|
||||||
|
and additional data.
|
||||||
|
|
||||||
|
:param Manifest manifest: The Manifest
|
||||||
|
:param dict additional_vars: Additional values (they will take precedence and overwrite anything else)
|
||||||
|
:return: The manifest_vars dictionary
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
class DictClass(dict):
|
class DictClass(dict):
|
||||||
"""Tiny extension of dict to allow setting and getting keys via attributes
|
"""Tiny extension of dict to allow setting and getting keys via attributes
|
||||||
"""
|
"""
|
||||||
|
@ -89,9 +96,8 @@ class BootstrapInformation(object):
|
||||||
def set_manifest_vars(obj, data):
|
def set_manifest_vars(obj, data):
|
||||||
"""Runs through the manifest and creates DictClasses for every key
|
"""Runs through the manifest and creates DictClasses for every key
|
||||||
|
|
||||||
Args:
|
:param dict obj: dictionary to set the values on
|
||||||
obj (dict): dictionary to set the values on
|
:param dict data: dictionary of values to set on the obj
|
||||||
data (dict): dictionary of values to set on the obj
|
|
||||||
"""
|
"""
|
||||||
for key, value in data.iteritems():
|
for key, value in data.iteritems():
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
def load_volume(data, bootloader):
|
def load_volume(data, bootloader):
|
||||||
"""Instantiates a volume that corresponds to the data in the manifest
|
"""Instantiates a volume that corresponds to the data in the manifest
|
||||||
Args:
|
|
||||||
data (dict): The 'volume' section from the manifest
|
|
||||||
bootloader (str): Name of the bootloader the system will boot with
|
|
||||||
|
|
||||||
Returns:
|
:param dict data: The 'volume' section from the manifest
|
||||||
Volume. The volume that represents all information pertaining to the volume we bootstrap on
|
:param str bootloader: Name of the bootloader the system will boot with
|
||||||
|
|
||||||
|
:return: The volume that represents all information pertaining to the volume we bootstrap on.
|
||||||
|
:rtype: Volume
|
||||||
"""
|
"""
|
||||||
# Create a mapping between valid partition maps in the manifest and their corresponding classes
|
# Create a mapping between valid partition maps in the manifest and their corresponding classes
|
||||||
from partitionmaps.gpt import GPTPartitionMap
|
from partitionmaps.gpt import GPTPartitionMap
|
||||||
|
|
|
@ -20,8 +20,7 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
|
|
||||||
def __init__(self, bootloader):
|
def __init__(self, bootloader):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param str bootloader: Name of the bootloader we will use for bootstrapping
|
||||||
bootloader (str): Name of the bootloader we will use for bootstrapping
|
|
||||||
"""
|
"""
|
||||||
# Create the configuration for the state machine
|
# Create the configuration for the state machine
|
||||||
cfg = {'initial': 'nonexistent', 'events': self.events, 'callbacks': {}}
|
cfg = {'initial': 'nonexistent', 'events': self.events, 'callbacks': {}}
|
||||||
|
@ -30,16 +29,15 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
def is_blocking(self):
|
def is_blocking(self):
|
||||||
"""Returns whether the partition map is blocking volume detach operations
|
"""Returns whether the partition map is blocking volume detach operations
|
||||||
|
|
||||||
Returns:
|
:rtype: bool
|
||||||
bool.
|
|
||||||
"""
|
"""
|
||||||
return self.fsm.current == 'mapped'
|
return self.fsm.current == 'mapped'
|
||||||
|
|
||||||
def get_total_size(self):
|
def get_total_size(self):
|
||||||
"""Returns the total size the partitions occupy
|
"""Returns the total size the partitions occupy
|
||||||
|
|
||||||
Returns:
|
:return: The size of all partitions
|
||||||
Bytes. The size of all the partitions
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
# We just need the endpoint of the last partition
|
# We just need the endpoint of the last partition
|
||||||
return self.partitions[-1].get_end()
|
return self.partitions[-1].get_end()
|
||||||
|
@ -47,8 +45,7 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
def create(self, volume):
|
def create(self, volume):
|
||||||
"""Creates the partition map
|
"""Creates the partition map
|
||||||
|
|
||||||
Args:
|
:param Volume volume: The volume to create the partition map on
|
||||||
volume (Volume): The volume to create the partition map on
|
|
||||||
"""
|
"""
|
||||||
self.fsm.create(volume=volume)
|
self.fsm.create(volume=volume)
|
||||||
|
|
||||||
|
@ -59,15 +56,13 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
def map(self, volume):
|
def map(self, volume):
|
||||||
"""Maps the partition map to device nodes
|
"""Maps the partition map to device nodes
|
||||||
|
|
||||||
Args:
|
:param Volume volume: The volume the partition map resides on
|
||||||
volume (Volume): The volume the partition map resides on
|
|
||||||
"""
|
"""
|
||||||
self.fsm.map(volume=volume)
|
self.fsm.map(volume=volume)
|
||||||
|
|
||||||
def _before_map(self, event):
|
def _before_map(self, event):
|
||||||
"""
|
"""
|
||||||
Raises:
|
:raises PartitionError: In case a partition could not be mapped.
|
||||||
PartitionError
|
|
||||||
"""
|
"""
|
||||||
volume = event.volume
|
volume = event.volume
|
||||||
try:
|
try:
|
||||||
|
@ -105,15 +100,13 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
def unmap(self, volume):
|
def unmap(self, volume):
|
||||||
"""Unmaps the partition
|
"""Unmaps the partition
|
||||||
|
|
||||||
Args:
|
:param Volume volume: The volume to unmap the partition map from
|
||||||
volume (Volume): The volume to unmap the partition map from
|
|
||||||
"""
|
"""
|
||||||
self.fsm.unmap(volume=volume)
|
self.fsm.unmap(volume=volume)
|
||||||
|
|
||||||
def _before_unmap(self, event):
|
def _before_unmap(self, event):
|
||||||
"""
|
"""
|
||||||
Raises:
|
:raises PartitionError: If the a partition cannot be unmapped
|
||||||
PartitionError
|
|
||||||
"""
|
"""
|
||||||
volume = event.volume
|
volume = event.volume
|
||||||
# Run through all partitions before unmapping and make sure they can all be unmapped
|
# Run through all partitions before unmapping and make sure they can all be unmapped
|
||||||
|
|
|
@ -10,9 +10,8 @@ class GPTPartitionMap(AbstractPartitionMap):
|
||||||
|
|
||||||
def __init__(self, data, bootloader):
|
def __init__(self, data, bootloader):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict data: volume.partitions part of the manifest
|
||||||
data (dict): volume.partitions part of the manifest
|
:param str bootloader: Name of the bootloader we will use for bootstrapping
|
||||||
bootloader (str): Name of the bootloader we will use for bootstrapping
|
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.bytes import Bytes
|
from bootstrapvz.common.bytes import Bytes
|
||||||
# List of partitions
|
# List of partitions
|
||||||
|
|
|
@ -11,9 +11,8 @@ class MSDOSPartitionMap(AbstractPartitionMap):
|
||||||
|
|
||||||
def __init__(self, data, bootloader):
|
def __init__(self, data, bootloader):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict data: volume.partitions part of the manifest
|
||||||
data (dict): volume.partitions part of the manifest
|
:param str bootloader: Name of the bootloader we will use for bootstrapping
|
||||||
bootloader (str): Name of the bootloader we will use for bootstrapping
|
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.bytes import Bytes
|
from bootstrapvz.common.bytes import Bytes
|
||||||
# List of partitions
|
# List of partitions
|
||||||
|
|
|
@ -9,9 +9,8 @@ class NoPartitions(object):
|
||||||
|
|
||||||
def __init__(self, data, bootloader):
|
def __init__(self, data, bootloader):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict data: volume.partitions part of the manifest
|
||||||
data (dict): volume.partitions part of the manifest
|
:param str bootloader: Name of the bootloader we will use for bootstrapping
|
||||||
bootloader (str): Name of the bootloader we will use for bootstrapping
|
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.bytes import Bytes
|
from bootstrapvz.common.bytes import Bytes
|
||||||
# In the NoPartitions partitions map we only have a single 'partition'
|
# In the NoPartitions partitions map we only have a single 'partition'
|
||||||
|
@ -22,15 +21,14 @@ class NoPartitions(object):
|
||||||
def is_blocking(self):
|
def is_blocking(self):
|
||||||
"""Returns whether the partition map is blocking volume detach operations
|
"""Returns whether the partition map is blocking volume detach operations
|
||||||
|
|
||||||
Returns:
|
:rtype: bool
|
||||||
bool.
|
|
||||||
"""
|
"""
|
||||||
return self.root.fsm.current == 'mounted'
|
return self.root.fsm.current == 'mounted'
|
||||||
|
|
||||||
def get_total_size(self):
|
def get_total_size(self):
|
||||||
"""Returns the total size the partitions occupy
|
"""Returns the total size the partitions occupy
|
||||||
|
|
||||||
Returns:
|
:return: The size of all the partitions
|
||||||
Bytes. The size of all the partitions
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
return self.root.get_end()
|
return self.root.get_end()
|
||||||
|
|
|
@ -24,10 +24,9 @@ class AbstractPartition(FSMProxy):
|
||||||
"""
|
"""
|
||||||
def __init__(self, source, destination, opts):
|
def __init__(self, source, destination, opts):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param str,AbstractPartition source: The path from where we mount or a partition
|
||||||
source (str,AbstractPartition): The path from where we mount or a partition
|
:param str destination: The path of the mountpoint
|
||||||
destination (str): The path of the mountpoint
|
:param list opts: List of options to pass to the mount command
|
||||||
opts (list): List of options to pass to the mount command
|
|
||||||
"""
|
"""
|
||||||
self.source = source
|
self.source = source
|
||||||
self.destination = destination
|
self.destination = destination
|
||||||
|
@ -36,8 +35,7 @@ class AbstractPartition(FSMProxy):
|
||||||
def mount(self, prefix):
|
def mount(self, prefix):
|
||||||
"""Performs the mount operation or forwards it to another partition
|
"""Performs the mount operation or forwards it to another partition
|
||||||
|
|
||||||
Args:
|
:param str prefix: Path prefix of the mountpoint
|
||||||
prefix (str): Path prefix of the mountpoint
|
|
||||||
"""
|
"""
|
||||||
mount_dir = os.path.join(prefix, self.destination)
|
mount_dir = os.path.join(prefix, self.destination)
|
||||||
# If the source is another partition, we tell that partition to mount itself
|
# If the source is another partition, we tell that partition to mount itself
|
||||||
|
@ -59,10 +57,9 @@ class AbstractPartition(FSMProxy):
|
||||||
|
|
||||||
def __init__(self, size, filesystem, format_command):
|
def __init__(self, size, filesystem, format_command):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param str filesystem: Filesystem the partition should be formatted with
|
||||||
filesystem (str): Filesystem the partition should be formatted with
|
:param list format_command: Optional format command, valid variables are fs, device_path and size
|
||||||
format_command (list): Optional format command, valid variables are fs, device_path and size
|
|
||||||
"""
|
"""
|
||||||
self.size = size
|
self.size = size
|
||||||
self.filesystem = filesystem
|
self.filesystem = filesystem
|
||||||
|
@ -79,8 +76,8 @@ class AbstractPartition(FSMProxy):
|
||||||
def get_uuid(self):
|
def get_uuid(self):
|
||||||
"""Gets the UUID of the partition
|
"""Gets the UUID of the partition
|
||||||
|
|
||||||
Returns:
|
:return: The UUID of the partition
|
||||||
str. The UUID of the partition
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
[uuid] = log_check_call(['blkid', '-s', 'UUID', '-o', 'value', self.device_path])
|
[uuid] = log_check_call(['blkid', '-s', 'UUID', '-o', 'value', self.device_path])
|
||||||
return uuid
|
return uuid
|
||||||
|
@ -92,8 +89,8 @@ class AbstractPartition(FSMProxy):
|
||||||
def get_end(self):
|
def get_end(self):
|
||||||
"""Gets the end of the partition
|
"""Gets the end of the partition
|
||||||
|
|
||||||
Returns:
|
:return: The end of the partition
|
||||||
Bytes. The end of the partition
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
return self.get_start() + self.size
|
return self.get_start() + self.size
|
||||||
|
|
||||||
|
@ -141,10 +138,9 @@ class AbstractPartition(FSMProxy):
|
||||||
"""Associate a mount with this partition
|
"""Associate a mount with this partition
|
||||||
Automatically mounts it
|
Automatically mounts it
|
||||||
|
|
||||||
Args:
|
:param str,AbstractPartition source: The source of the mount
|
||||||
source (str,AbstractPartition): The source of the mount
|
:param str destination: The path to the mountpoint
|
||||||
destination (str): The path to the mountpoint
|
:param list opts: Any options that should be passed to the mount command
|
||||||
opts (list): Any options that should be passed to the mount command
|
|
||||||
"""
|
"""
|
||||||
# Create a new mount object, mount it if the partition is mounted and put it in the mounts dict
|
# Create a new mount object, mount it if the partition is mounted and put it in the mounts dict
|
||||||
mount = self.Mount(source, destination, opts)
|
mount = self.Mount(source, destination, opts)
|
||||||
|
@ -156,8 +152,7 @@ class AbstractPartition(FSMProxy):
|
||||||
"""Remove a mount from this partition
|
"""Remove a mount from this partition
|
||||||
Automatically unmounts it
|
Automatically unmounts it
|
||||||
|
|
||||||
Args:
|
:param str destination: The mountpoint path of the mount that should be removed
|
||||||
destination (str): The mountpoint path of the mount that should be removed
|
|
||||||
"""
|
"""
|
||||||
# Unmount the mount if the partition is mounted and delete it from the mounts dict
|
# Unmount the mount if the partition is mounted and delete it from the mounts dict
|
||||||
# If the mount is already unmounted and the source is a partition, this will raise an exception
|
# If the mount is already unmounted and the source is a partition, this will raise an exception
|
||||||
|
|
|
@ -20,11 +20,10 @@ class BasePartition(AbstractPartition):
|
||||||
|
|
||||||
def __init__(self, size, filesystem, format_command, previous):
|
def __init__(self, size, filesystem, format_command, previous):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param str filesystem: Filesystem the partition should be formatted with
|
||||||
filesystem (str): Filesystem the partition should be formatted with
|
:param list format_command: Optional format command, valid variables are fs, device_path and size
|
||||||
format_command (list): Optional format command, valid variables are fs, device_path and size
|
:param BasePartition previous: The partition that preceeds this one
|
||||||
previous (BasePartition): The partition that preceeds this one
|
|
||||||
"""
|
"""
|
||||||
# By saving the previous partition we have
|
# By saving the previous partition we have
|
||||||
# a linked list that partitions can go backwards in to find the first partition.
|
# a linked list that partitions can go backwards in to find the first partition.
|
||||||
|
@ -39,16 +38,15 @@ class BasePartition(AbstractPartition):
|
||||||
def create(self, volume):
|
def create(self, volume):
|
||||||
"""Creates the partition
|
"""Creates the partition
|
||||||
|
|
||||||
Args:
|
:param Volume volume: The volume to create the partition on
|
||||||
volume (Volume): The volume to create the partition on
|
|
||||||
"""
|
"""
|
||||||
self.fsm.create(volume=volume)
|
self.fsm.create(volume=volume)
|
||||||
|
|
||||||
def get_index(self):
|
def get_index(self):
|
||||||
"""Gets the index of this partition in the partition map
|
"""Gets the index of this partition in the partition map
|
||||||
|
|
||||||
Returns:
|
:return: The index of the partition in the partition map
|
||||||
int. The index of the partition in the partition map
|
:rtype: int
|
||||||
"""
|
"""
|
||||||
if self.previous is None:
|
if self.previous is None:
|
||||||
# Partitions are 1 indexed
|
# Partitions are 1 indexed
|
||||||
|
@ -60,8 +58,8 @@ class BasePartition(AbstractPartition):
|
||||||
def get_start(self):
|
def get_start(self):
|
||||||
"""Gets the starting byte of this partition
|
"""Gets the starting byte of this partition
|
||||||
|
|
||||||
Returns:
|
:return: The starting byte of this partition
|
||||||
Bytes. The starting byte of this partition
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
if self.previous is None:
|
if self.previous is None:
|
||||||
# If there is no previous partition, this partition begins at the offset
|
# If there is no previous partition, this partition begins at the offset
|
||||||
|
@ -73,8 +71,7 @@ class BasePartition(AbstractPartition):
|
||||||
def map(self, device_path):
|
def map(self, device_path):
|
||||||
"""Maps the partition to a device_path
|
"""Maps the partition to a device_path
|
||||||
|
|
||||||
Args:
|
:param str device_path: The device patht his partition should be mapped to
|
||||||
device_path (str): The device patht his partition should be mapped to
|
|
||||||
"""
|
"""
|
||||||
self.fsm.map(device_path=device_path)
|
self.fsm.map(device_path=device_path)
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,11 @@ class GPTPartition(BasePartition):
|
||||||
|
|
||||||
def __init__(self, size, filesystem, format_command, name, previous):
|
def __init__(self, size, filesystem, format_command, name, previous):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param str filesystem: Filesystem the partition should be formatted with
|
||||||
filesystem (str): Filesystem the partition should be formatted with
|
:param list format_command: Optional format command, valid variables are fs, device_path and size
|
||||||
format_command (list): Optional format command, valid variables are fs, device_path and size
|
:param str name: The name of the partition
|
||||||
name (str): The name of the partition
|
:param BasePartition previous: The partition that preceeds this one
|
||||||
previous (BasePartition): The partition that preceeds this one
|
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
super(GPTPartition, self).__init__(size, filesystem, format_command, previous)
|
super(GPTPartition, self).__init__(size, filesystem, format_command, previous)
|
||||||
|
|
|
@ -8,9 +8,8 @@ class GPTSwapPartition(GPTPartition):
|
||||||
|
|
||||||
def __init__(self, size, previous):
|
def __init__(self, size, previous):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param BasePartition previous: The partition that preceeds this one
|
||||||
previous (BasePartition): The partition that preceeds this one
|
|
||||||
"""
|
"""
|
||||||
super(GPTSwapPartition, self).__init__(size, 'swap', None, 'swap', previous)
|
super(GPTSwapPartition, self).__init__(size, 'swap', None, 'swap', previous)
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,8 @@ class MSDOSSwapPartition(MSDOSPartition):
|
||||||
|
|
||||||
def __init__(self, size, previous):
|
def __init__(self, size, previous):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param BasePartition previous: The partition that preceeds this one
|
||||||
previous (BasePartition): The partition that preceeds this one
|
|
||||||
"""
|
"""
|
||||||
super(MSDOSSwapPartition, self).__init__(size, 'swap', None, previous)
|
super(MSDOSSwapPartition, self).__init__(size, 'swap', None, previous)
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ class SinglePartition(AbstractPartition):
|
||||||
def get_start(self):
|
def get_start(self):
|
||||||
"""Gets the starting byte of this partition
|
"""Gets the starting byte of this partition
|
||||||
|
|
||||||
Returns:
|
:return: The starting byte of this partition
|
||||||
Bytes. The starting byte of this partition
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.bytes import Bytes
|
from bootstrapvz.common.bytes import Bytes
|
||||||
# On an unpartitioned volume there is no offset and no previous partition
|
# On an unpartitioned volume there is no offset and no previous partition
|
||||||
|
|
|
@ -14,8 +14,7 @@ class UnformattedPartition(BasePartition):
|
||||||
|
|
||||||
def __init__(self, size, previous):
|
def __init__(self, size, previous):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param Bytes size: Size of the partition
|
||||||
size (Bytes): Size of the partition
|
:param BasePartition previous: The partition that preceeds this one
|
||||||
previous (BasePartition): The partition that preceeds this one
|
|
||||||
"""
|
"""
|
||||||
super(UnformattedPartition, self).__init__(size, None, None, previous)
|
super(UnformattedPartition, self).__init__(size, None, None, previous)
|
||||||
|
|
|
@ -23,8 +23,7 @@ class Volume(FSMProxy):
|
||||||
|
|
||||||
def __init__(self, partition_map):
|
def __init__(self, partition_map):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param PartitionMap partition_map: The partition map for the volume
|
||||||
partition_map (PartitionMap): The partition map for the volume
|
|
||||||
"""
|
"""
|
||||||
# Path to the volume
|
# Path to the volume
|
||||||
self.device_path = None
|
self.device_path = None
|
||||||
|
@ -50,10 +49,6 @@ class Volume(FSMProxy):
|
||||||
super(Volume, self).__init__(cfg)
|
super(Volume, self).__init__(cfg)
|
||||||
|
|
||||||
def _after_create(self, e):
|
def _after_create(self, e):
|
||||||
"""
|
|
||||||
Args:
|
|
||||||
e (_e_obj): Event object containing arguments to create()
|
|
||||||
"""
|
|
||||||
if isinstance(self.partition_map, NoPartitions):
|
if isinstance(self.partition_map, NoPartitions):
|
||||||
# When the volume has no partitions, the virtual root partition
|
# When the volume has no partitions, the virtual root partition
|
||||||
# is essentially created when the volume is created, forward that creation event.
|
# is essentially created when the volume is created, forward that creation event.
|
||||||
|
@ -62,11 +57,7 @@ class Volume(FSMProxy):
|
||||||
def _check_blocking(self, e):
|
def _check_blocking(self, e):
|
||||||
"""Checks whether the volume is blocked
|
"""Checks whether the volume is blocked
|
||||||
|
|
||||||
Args:
|
:raises VolumeError: When the volume is blocked from being detached
|
||||||
e (_e_obj): Event object containing arguments to create()
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
VolumeError
|
|
||||||
"""
|
"""
|
||||||
# Only the partition map can block the volume
|
# Only the partition map can block the volume
|
||||||
if self.partition_map.is_blocking():
|
if self.partition_map.is_blocking():
|
||||||
|
@ -78,16 +69,16 @@ class Volume(FSMProxy):
|
||||||
Mainly it is used to fool grub into thinking that it is working with a real volume,
|
Mainly it is used to fool grub into thinking that it is working with a real volume,
|
||||||
rather than a loopback device or a network block device.
|
rather than a loopback device or a network block device.
|
||||||
|
|
||||||
Args:
|
:param _e_obj e: Event object containing arguments to create()
|
||||||
e (_e_obj): Event object containing arguments to create()
|
Keyword arguments to link_dm_node() are:
|
||||||
Arguments are:
|
|
||||||
logical_start_sector (int): The sector the volume should start at in the new volume
|
:param int logical_start_sector: The sector the volume should start at in the new volume
|
||||||
start_sector (int): The offset at which the volume should begin to be mapped in the new volume
|
:param int start_sector: The offset at which the volume should begin to be mapped in the new volume
|
||||||
sectors (int): The number of sectors that should be mapped
|
:param int sectors: The number of sectors that should be mapped
|
||||||
|
|
||||||
Read more at: http://manpages.debian.org/cgi-bin/man.cgi?query=dmsetup&apropos=0&sektion=0&manpath=Debian+7.0+wheezy&format=html&locale=en
|
Read more at: http://manpages.debian.org/cgi-bin/man.cgi?query=dmsetup&apropos=0&sektion=0&manpath=Debian+7.0+wheezy&format=html&locale=en
|
||||||
|
|
||||||
Raises:
|
:raises VolumeError: When a free block device cannot be found.
|
||||||
VolumeError
|
|
||||||
"""
|
"""
|
||||||
import os.path
|
import os.path
|
||||||
from bootstrapvz.common.fs import get_partitions
|
from bootstrapvz.common.fs import get_partitions
|
||||||
|
@ -134,9 +125,6 @@ class Volume(FSMProxy):
|
||||||
|
|
||||||
def _before_unlink_dm_node(self, e):
|
def _before_unlink_dm_node(self, e):
|
||||||
"""Unlinks the device mapping
|
"""Unlinks the device mapping
|
||||||
|
|
||||||
Args:
|
|
||||||
e (_e_obj): Event object containing arguments to create()
|
|
||||||
"""
|
"""
|
||||||
log_check_call(['dmsetup', 'remove', self.dm_node_name])
|
log_check_call(['dmsetup', 'remove', self.dm_node_name])
|
||||||
# Reset the device_path
|
# Reset the device_path
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
"""This module holds functions and classes responsible for formatting the log output
|
"""This module holds functions and classes responsible for formatting the log output
|
||||||
both to a file and to the console.
|
both to a file and to the console.
|
||||||
.. module:: log
|
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -9,11 +8,9 @@ def get_log_filename(manifest_path):
|
||||||
"""Returns the path to a logfile given a manifest
|
"""Returns the path to a logfile given a manifest
|
||||||
The logfile name is constructed from the current timestamp and the basename of the manifest
|
The logfile name is constructed from the current timestamp and the basename of the manifest
|
||||||
|
|
||||||
Args:
|
:param str manifest_path: The path to the manifest
|
||||||
manifest_path (str): The path to the manifest
|
:return: The path to the logfile
|
||||||
|
:rtype: str
|
||||||
Returns:
|
|
||||||
str. The path to the logfile
|
|
||||||
"""
|
"""
|
||||||
import os.path
|
import os.path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -28,9 +25,8 @@ def get_log_filename(manifest_path):
|
||||||
def setup_logger(logfile=None, debug=False):
|
def setup_logger(logfile=None, debug=False):
|
||||||
"""Sets up the python logger to log to both a file and the console
|
"""Sets up the python logger to log to both a file and the console
|
||||||
|
|
||||||
Args:
|
:param str logfile: Path to a logfile
|
||||||
logfile (str): Path to a logfile
|
:param bool debug: Whether to log debug output to the console
|
||||||
debug (bool): Whether to log debug output to the console
|
|
||||||
"""
|
"""
|
||||||
root = logging.getLogger()
|
root = logging.getLogger()
|
||||||
# Make sure all logging statements are processed by our handlers, they decide the log level
|
# Make sure all logging statements are processed by our handlers, they decide the log level
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Main module containing all the setup necessary for running the bootstrapping process
|
"""Main module containing all the setup necessary for running the bootstrapping process
|
||||||
.. module:: main
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
@ -9,8 +8,7 @@ log = logging.getLogger(__name__)
|
||||||
def main():
|
def main():
|
||||||
"""Main function for invoking the bootstrap process
|
"""Main function for invoking the bootstrap process
|
||||||
|
|
||||||
Raises:
|
:raises Exception: When the invoking user is not root and --dry-run isn't specified
|
||||||
Exception
|
|
||||||
"""
|
"""
|
||||||
# Get the commandline arguments
|
# Get the commandline arguments
|
||||||
opts = get_opts()
|
opts = get_opts()
|
||||||
|
@ -58,8 +56,7 @@ Options:
|
||||||
def run(opts):
|
def run(opts):
|
||||||
"""Runs the bootstrapping process
|
"""Runs the bootstrapping process
|
||||||
|
|
||||||
Args:
|
:params dict opts: Dictionary of options from the commandline
|
||||||
opts (dict): Dictionary of options from the commandline
|
|
||||||
"""
|
"""
|
||||||
# Load the manifest
|
# Load the manifest
|
||||||
from manifest import Manifest
|
from manifest import Manifest
|
||||||
|
@ -97,9 +94,8 @@ def run(opts):
|
||||||
"""counter_task() adds the second argument to the rollback tasklist
|
"""counter_task() adds the second argument to the rollback tasklist
|
||||||
if the first argument is present in the list of completed tasks
|
if the first argument is present in the list of completed tasks
|
||||||
|
|
||||||
Args:
|
:param Task task: The task to look for in the completed tasks list
|
||||||
task (Task): The task to look for in the completed tasks list
|
:param Task counter: The task to add to the rollback tasklist
|
||||||
counter (Task): The task to add to the rollback tasklist
|
|
||||||
"""
|
"""
|
||||||
if task in tasklist.tasks_completed and counter not in tasklist.tasks_completed:
|
if task in tasklist.tasks_completed and counter not in tasklist.tasks_completed:
|
||||||
rollback_tasklist.tasks.add(counter)
|
rollback_tasklist.tasks.add(counter)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
"""The Manifest module contains the manifest that providers and plugins use
|
"""The Manifest module contains the manifest that providers and plugins use
|
||||||
to determine which tasks should be added to the tasklist, what arguments various
|
to determine which tasks should be added to the tasklist, what arguments various
|
||||||
invocations should have etc..
|
invocations should have etc..
|
||||||
.. module:: manifest
|
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.tools import load_json
|
from bootstrapvz.common.tools import load_json
|
||||||
from bootstrapvz.common.tools import load_yaml
|
from bootstrapvz.common.tools import load_yaml
|
||||||
|
@ -19,8 +18,7 @@ class Manifest(object):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
"""Initializer: Given a path we load, validate and parse the manifest.
|
"""Initializer: Given a path we load, validate and parse the manifest.
|
||||||
|
|
||||||
Args:
|
:param str path: The path to the manifest
|
||||||
path (str): The path to the manifest
|
|
||||||
"""
|
"""
|
||||||
self.path = path
|
self.path = path
|
||||||
self.load()
|
self.load()
|
||||||
|
@ -100,9 +98,8 @@ class Manifest(object):
|
||||||
"""This convenience function is passed around to all the validation functions
|
"""This convenience function is passed around to all the validation functions
|
||||||
so that they may run a json-schema validation by giving it the data and a path to the schema.
|
so that they may run a json-schema validation by giving it the data and a path to the schema.
|
||||||
|
|
||||||
Args:
|
:param dict data: Data to validate (normally the manifest data)
|
||||||
data (dict): Data to validate (normally the manifest data)
|
:param str schema_path: Path to the json-schema to use for validation
|
||||||
schema_path (str): Path to the json-schema to use for validation
|
|
||||||
"""
|
"""
|
||||||
import jsonschema
|
import jsonschema
|
||||||
schema = load_json(schema_path)
|
schema = load_json(schema_path)
|
||||||
|
@ -115,9 +112,9 @@ class Manifest(object):
|
||||||
"""This function is passed to all validation functions so that they may
|
"""This function is passed to all validation functions so that they may
|
||||||
raise a validation error because a custom validation of the manifest failed.
|
raise a validation error because a custom validation of the manifest failed.
|
||||||
|
|
||||||
Args:
|
:param str message: Message to user about the error
|
||||||
message (str): Message to user about the error
|
:param list json_path: A path to the location in the manifest where the error occurred
|
||||||
json_path (list): A path to the location in the manifest where the error occurred
|
:raises ManifestError: With absolute certainty
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.exceptions import ManifestError
|
from bootstrapvz.common.exceptions import ManifestError
|
||||||
raise ManifestError(message, self.path, json_path)
|
raise ManifestError(message, self.path, json_path)
|
||||||
|
|
|
@ -15,21 +15,21 @@ class Phase(object):
|
||||||
def pos(self):
|
def pos(self):
|
||||||
"""Gets the position of the phase
|
"""Gets the position of the phase
|
||||||
|
|
||||||
Returns:
|
:return: The positional index of the phase in relation to the other phases
|
||||||
int. The positional index of the phase in relation to the other phases
|
:rtype: int
|
||||||
"""
|
"""
|
||||||
from bootstrapvz.common.phases import order
|
from bootstrapvz.common.phases import order
|
||||||
return next(i for i, phase in enumerate(order) if phase is self)
|
return next(i for i, phase in enumerate(order) if phase is self)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
"""Compares the phase order in relation to the other phases
|
"""Compares the phase order in relation to the other phases
|
||||||
|
:return int:
|
||||||
"""
|
"""
|
||||||
return self.pos() - other.pos()
|
return self.pos() - other.pos()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""String representation of the phase, the name suffices
|
"""
|
||||||
|
:return: String representation of the phase
|
||||||
Returns:
|
:rtype: str
|
||||||
string.
|
|
||||||
"""
|
"""
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -9,17 +9,16 @@ class PackageList(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, target):
|
def __init__(self, name, target):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param str name: The name of the package
|
||||||
name (str): The name of the package
|
:param str target: The name of the target release
|
||||||
target (str): The name of the target release
|
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.target = target
|
self.target = target
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Converts the package into somehting that apt-get install can parse
|
"""Converts the package into somehting that apt-get install can parse
|
||||||
Returns:
|
|
||||||
string.
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
if self.target is None:
|
if self.target is None:
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -31,23 +30,21 @@ class PackageList(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param str path: The path to the local package
|
||||||
path (str): The path to the local package
|
|
||||||
"""
|
"""
|
||||||
self.path = path
|
self.path = path
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
Returns:
|
:return: The path to the local package
|
||||||
string. The path to the local package
|
:rtype: string
|
||||||
"""
|
"""
|
||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
def __init__(self, manifest_vars, source_lists):
|
def __init__(self, manifest_vars, source_lists):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict manifest_vars: The manifest variables
|
||||||
manifest_vars (dict): The manifest variables
|
:param SourceLists source_lists: The sourcelists for apt
|
||||||
source_lists (SourceLists): The sourcelists for apt
|
|
||||||
"""
|
"""
|
||||||
self.manifest_vars = manifest_vars
|
self.manifest_vars = manifest_vars
|
||||||
self.source_lists = source_lists
|
self.source_lists = source_lists
|
||||||
|
@ -63,12 +60,11 @@ class PackageList(object):
|
||||||
def add(self, name, target=None):
|
def add(self, name, target=None):
|
||||||
"""Adds a package to the install list
|
"""Adds a package to the install list
|
||||||
|
|
||||||
Args:
|
:param str name: The name of the package to install, may contain manifest vars references
|
||||||
name (str): The name of the package to install, may contain manifest vars references
|
:param str target: The name of the target release for the package, may contain manifest vars references
|
||||||
target (str): The name of the target release for the package, may contain manifest vars references
|
|
||||||
|
|
||||||
Raises:
|
:raises PackageError: When a package of the same name but with a different target has already been added.
|
||||||
PackageError
|
:raises PackageError: When the specified target release could not be found.
|
||||||
"""
|
"""
|
||||||
from exceptions import PackageError
|
from exceptions import PackageError
|
||||||
name = name.format(**self.manifest_vars)
|
name = name.format(**self.manifest_vars)
|
||||||
|
@ -108,8 +104,7 @@ class PackageList(object):
|
||||||
def add_local(self, package_path):
|
def add_local(self, package_path):
|
||||||
"""Adds a local package to the installation list
|
"""Adds a local package to the installation list
|
||||||
|
|
||||||
Args:
|
:param str package_path: Path to the local package, may contain manifest vars references
|
||||||
package_path (str): Path to the local package, may contain manifest vars references
|
|
||||||
"""
|
"""
|
||||||
package_path = package_path.format(**self.manifest_vars)
|
package_path = package_path.format(**self.manifest_vars)
|
||||||
self.install.append(self.Local(package_path))
|
self.install.append(self.Local(package_path))
|
||||||
|
|
|
@ -6,8 +6,7 @@ class PreferenceLists(object):
|
||||||
|
|
||||||
def __init__(self, manifest_vars):
|
def __init__(self, manifest_vars):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict manifest_vars: The manifest variables
|
||||||
manifest_vars (dict): The manifest variables
|
|
||||||
"""
|
"""
|
||||||
# A dictionary with the name of the file in preferences.d as the key
|
# A dictionary with the name of the file in preferences.d as the key
|
||||||
# That values are lists of Preference objects
|
# That values are lists of Preference objects
|
||||||
|
@ -18,9 +17,8 @@ class PreferenceLists(object):
|
||||||
def add(self, name, preferences):
|
def add(self, name, preferences):
|
||||||
"""Adds a preference to the apt preferences list
|
"""Adds a preference to the apt preferences list
|
||||||
|
|
||||||
Args:
|
:param str name: Name of the file in preferences.list.d, may contain manifest vars references
|
||||||
name (str): Name of the file in preferences.list.d, may contain manifest vars references
|
:param object preferences: The preferences
|
||||||
preferences (object): The preferences
|
|
||||||
"""
|
"""
|
||||||
name = name.format(**self.manifest_vars)
|
name = name.format(**self.manifest_vars)
|
||||||
self.preferences[name] = [Preference(p) for p in preferences]
|
self.preferences[name] = [Preference(p) for p in preferences]
|
||||||
|
@ -32,18 +30,13 @@ class Preference(object):
|
||||||
|
|
||||||
def __init__(self, preference):
|
def __init__(self, preference):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict preference: A apt preference dictionary
|
||||||
preference (dict): A apt preference dictionary
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
PreferenceError
|
|
||||||
"""
|
"""
|
||||||
self.preference = preference
|
self.preference = preference
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Convert the object into a preference block
|
"""Convert the object into a preference block
|
||||||
|
|
||||||
Returns:
|
:rtype: str
|
||||||
string.
|
|
||||||
"""
|
"""
|
||||||
return "Package: {package}\nPin: {pin}\nPin-Priority: {pin-priority}\n".format(**self.preference)
|
return "Package: {package}\nPin: {pin}\nPin-Priority: {pin-priority}\n".format(**self.preference)
|
||||||
|
|
|
@ -6,8 +6,7 @@ class SourceLists(object):
|
||||||
|
|
||||||
def __init__(self, manifest_vars):
|
def __init__(self, manifest_vars):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param dict manifest_vars: The manifest variables
|
||||||
manifest_vars (dict): The manifest variables
|
|
||||||
"""
|
"""
|
||||||
# A dictionary with the name of the file in sources.list.d as the key
|
# A dictionary with the name of the file in sources.list.d as the key
|
||||||
# That values are lists of Source objects
|
# That values are lists of Source objects
|
||||||
|
@ -18,9 +17,8 @@ class SourceLists(object):
|
||||||
def add(self, name, line):
|
def add(self, name, line):
|
||||||
"""Adds a source to the apt sources list
|
"""Adds a source to the apt sources list
|
||||||
|
|
||||||
Args:
|
:param str name: Name of the file in sources.list.d, may contain manifest vars references
|
||||||
name (str): Name of the file in sources.list.d, may contain manifest vars references
|
:param str line: The line for the source file, may contain manifest vars references
|
||||||
line (str): The line for the source file, may contain manifest vars references
|
|
||||||
"""
|
"""
|
||||||
name = name.format(**self.manifest_vars)
|
name = name.format(**self.manifest_vars)
|
||||||
line = line.format(**self.manifest_vars)
|
line = line.format(**self.manifest_vars)
|
||||||
|
@ -31,11 +29,10 @@ class SourceLists(object):
|
||||||
def target_exists(self, target):
|
def target_exists(self, target):
|
||||||
"""Checks whether the target exists in the sources list
|
"""Checks whether the target exists in the sources list
|
||||||
|
|
||||||
Args:
|
:param str target: Name of the target to check for, may contain manifest vars references
|
||||||
target (str): Name of the target to check for, may contain manifest vars references
|
|
||||||
|
|
||||||
Returns:
|
:return: Whether the target exists
|
||||||
bool. Whether the target exists
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
target = target.format(**self.manifest_vars)
|
target = target.format(**self.manifest_vars)
|
||||||
# Run through all the sources and return True if the target exists
|
# Run through all the sources and return True if the target exists
|
||||||
|
@ -51,11 +48,9 @@ class Source(object):
|
||||||
|
|
||||||
def __init__(self, line):
|
def __init__(self, line):
|
||||||
"""
|
"""
|
||||||
Args:
|
:param str line: A apt source line
|
||||||
line (str): A apt source line
|
|
||||||
|
|
||||||
Raises:
|
:raises SourceError: When the source line cannot be parsed
|
||||||
SourceError
|
|
||||||
"""
|
"""
|
||||||
# Parse the source line and populate the class attributes with it
|
# Parse the source line and populate the class attributes with it
|
||||||
# The format is taken from `man sources.list`
|
# The format is taken from `man sources.list`
|
||||||
|
@ -84,8 +79,7 @@ class Source(object):
|
||||||
"""Convert the object into a source line
|
"""Convert the object into a source line
|
||||||
This is pretty much the reverse of what we're doing in the initialization function.
|
This is pretty much the reverse of what we're doing in the initialization function.
|
||||||
|
|
||||||
Returns:
|
:rtype: str
|
||||||
string.
|
|
||||||
"""
|
"""
|
||||||
options = ''
|
options = ''
|
||||||
if len(self.options) > 0:
|
if len(self.options) > 0:
|
||||||
|
|
|
@ -16,15 +16,14 @@ class Task(object):
|
||||||
"""
|
"""
|
||||||
def __repr__(cls):
|
def __repr__(cls):
|
||||||
"""
|
"""
|
||||||
Returns:
|
:return str: The full module path to the Task
|
||||||
string.
|
|
||||||
"""
|
"""
|
||||||
return cls.__module__ + '.' + cls.__name__
|
return cls.__module__ + '.' + cls.__name__
|
||||||
|
|
||||||
def __str__(cls):
|
def __str__(cls):
|
||||||
"""
|
"""
|
||||||
Returns:
|
:return: The full module path to the Task
|
||||||
string.
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
return repr(cls)
|
return repr(cls)
|
||||||
|
|
||||||
|
@ -32,7 +31,6 @@ class Task(object):
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
"""The run function, all work is done inside this function
|
"""The run function, all work is done inside this function
|
||||||
|
|
||||||
:param info: The bootstrap info object.
|
:param BootstrapInformation info: The bootstrap info object.
|
||||||
:type info: BootstrapInformation
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""The tasklist module contains the TaskList class.
|
"""The tasklist module contains the TaskList class.
|
||||||
.. module:: tasklist
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from bootstrapvz.common.exceptions import TaskListError
|
from bootstrapvz.common.exceptions import TaskListError
|
||||||
|
@ -22,10 +21,9 @@ class TaskList(object):
|
||||||
The function that is called shall accept the taskset as its first argument and the manifest
|
The function that is called shall accept the taskset as its first argument and the manifest
|
||||||
as its second argument.
|
as its second argument.
|
||||||
|
|
||||||
Args:
|
:param str function: Name of the function to call
|
||||||
function (str): Name of the function to call
|
:param Manifest manifest: The manifest
|
||||||
manifest (Manifest): The manifest
|
:param list *args: Additional arguments that should be passed to the function that is called
|
||||||
\*args: Additional arguments that should be passed to the function that is called
|
|
||||||
"""
|
"""
|
||||||
# Call 'function' on the provider
|
# Call 'function' on the provider
|
||||||
getattr(manifest.modules['provider'], function)(self.tasks, manifest, *args)
|
getattr(manifest.modules['provider'], function)(self.tasks, manifest, *args)
|
||||||
|
@ -38,9 +36,8 @@ class TaskList(object):
|
||||||
def run(self, info, dry_run=False):
|
def run(self, info, dry_run=False):
|
||||||
"""Converts the taskgraph into a list and runs all tasks in that list
|
"""Converts the taskgraph into a list and runs all tasks in that list
|
||||||
|
|
||||||
Args:
|
:param dict info: The bootstrap information object
|
||||||
info (dict): The bootstrap information object
|
:param bool dry_run: Whether to actually run the tasks or simply step through them
|
||||||
dry_run (bool): Whether to actually run the tasks or simply step through them
|
|
||||||
"""
|
"""
|
||||||
# Create a list for us to run
|
# Create a list for us to run
|
||||||
task_list = self.create_list()
|
task_list = self.create_list()
|
||||||
|
@ -109,8 +106,8 @@ class TaskList(object):
|
||||||
def get_all_tasks(self):
|
def get_all_tasks(self):
|
||||||
"""Gets a list of all task classes in the package
|
"""Gets a list of all task classes in the package
|
||||||
|
|
||||||
Returns:
|
:return: A list of all tasks in the package
|
||||||
list. A list of all tasks in the package
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
# Get a generator that returns all classes in the package
|
# Get a generator that returns all classes in the package
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -126,15 +123,11 @@ class TaskList(object):
|
||||||
def get_all_classes(self, path=None, prefix=''):
|
def get_all_classes(self, path=None, prefix=''):
|
||||||
""" Given a path to a package, this function retrieves all the classes in it
|
""" Given a path to a package, this function retrieves all the classes in it
|
||||||
|
|
||||||
Args:
|
:param str path: Path to the package
|
||||||
path (str): Path to the package
|
:param str prefix: Name of the package followed by a dot
|
||||||
prefix (str): Name of the package followed by a dot
|
:return: A generator that yields classes
|
||||||
|
:rtype: generator
|
||||||
Returns:
|
:raises Exception: If a module cannot be inspected.
|
||||||
generator. A generator that yields classes
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
Exception
|
|
||||||
"""
|
"""
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import importlib
|
import importlib
|
||||||
|
@ -152,16 +145,14 @@ class TaskList(object):
|
||||||
yield obj
|
yield obj
|
||||||
|
|
||||||
def check_ordering(self, task):
|
def check_ordering(self, task):
|
||||||
"""Checks the ordering of a task in relation to other tasks and their phases
|
"""Checks the ordering of a task in relation to other tasks and their phases.
|
||||||
|
|
||||||
This function checks for a subset of what the strongly connected components algorithm does,
|
This function checks for a subset of what the strongly connected components algorithm does,
|
||||||
but can deliver a more precise error message, namely that there is a conflict between
|
but can deliver a more precise error message, namely that there is a conflict between
|
||||||
what a task has specified as its predecessors or successors and in which phase it is placed.
|
what a task has specified as its predecessors or successors and in which phase it is placed.
|
||||||
|
|
||||||
Args:
|
:param Task task: The task to check the ordering for
|
||||||
task (Task): The task to check the ordering for
|
:raises TaskListError: If there is a conflict between task precedence and phase precedence
|
||||||
|
|
||||||
Raises:
|
|
||||||
TaskListError
|
|
||||||
"""
|
"""
|
||||||
for successor in task.successors:
|
for successor in task.successors:
|
||||||
# Run through all successors and check whether the phase of the task
|
# Run through all successors and check whether the phase of the task
|
||||||
|
@ -182,13 +173,12 @@ class TaskList(object):
|
||||||
|
|
||||||
def strongly_connected_components(self, graph):
|
def strongly_connected_components(self, graph):
|
||||||
"""Find the strongly connected components in a graph using Tarjan's algorithm.
|
"""Find the strongly connected components in a graph using Tarjan's algorithm.
|
||||||
|
|
||||||
Source: http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py
|
Source: http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py
|
||||||
|
|
||||||
Args:
|
:param dict graph: mapping of tasks to lists of successor tasks
|
||||||
graph (dict): mapping of tasks to lists of successor tasks
|
:return: List of tuples that are strongly connected comoponents
|
||||||
|
:rtype: list
|
||||||
Returns:
|
|
||||||
list. List of tuples that are strongly connected comoponents
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
@ -221,14 +211,13 @@ class TaskList(object):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def topological_sort(self, graph):
|
def topological_sort(self, graph):
|
||||||
"""Runs a topological sort on a graph
|
"""Runs a topological sort on a graph.
|
||||||
|
|
||||||
Source: http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py
|
Source: http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py
|
||||||
|
|
||||||
Args:
|
:param dict graph: mapping of tasks to lists of successor tasks
|
||||||
graph (dict): mapping of tasks to lists of successor tasks
|
:return: A list of all tasks in the graph sorted according to ther dependencies
|
||||||
|
:rtype: list
|
||||||
Returns:
|
|
||||||
list. A list of all tasks in the graph sorted according to ther dependencies
|
|
||||||
"""
|
"""
|
||||||
count = {}
|
count = {}
|
||||||
for node in graph:
|
for node in graph:
|
||||||
|
|
Loading…
Add table
Reference in a new issue