bootstrap-vz/bootstrapvz/base/pkg/packagelist.py

116 lines
3.9 KiB
Python
Raw Normal View History

class PackageList(object):
2014-03-23 16:04:03 +01:00
"""Represents a list of packages
"""
class Remote(object):
2014-03-23 16:04:03 +01:00
"""A remote package with an optional target
"""
def __init__(self, name, target):
2014-03-23 16:04:03 +01:00
"""
Args:
name (str): The name of the package
target (str): The name of the target release
"""
self.name = name
self.target = target
def __str__(self):
2014-03-23 16:04:03 +01:00
"""Converts the package into somehting that apt-get install can parse
Returns:
string.
"""
if self.target is None:
return self.name
else:
return self.name + '/' + self.target
class Local(object):
2014-03-23 16:04:03 +01:00
"""A local package
"""
def __init__(self, path):
2014-03-23 16:04:03 +01:00
"""
Args:
path (str): The path to the local package
"""
self.path = path
def __str__(self):
2014-03-23 16:04:03 +01:00
"""
Returns:
string. The path to the local package
"""
return self.path
def __init__(self, manifest_vars, source_lists):
2014-03-23 16:04:03 +01:00
"""
Args:
manifest_vars (dict): The manifest variables
source_lists (SourceLists): The sourcelists for apt
"""
self.manifest_vars = manifest_vars
self.source_lists = source_lists
2014-03-23 16:04:03 +01:00
# The default_target is the release we are bootstrapping
self.default_target = '{system.release}'.format(**self.manifest_vars)
2014-03-23 16:04:03 +01:00
# The list of packages that should be installed, this is not a set.
# We want to preserve the order in which the packages were added so that local
# packages may be installed in the correct order.
self.install = []
2014-03-23 16:04:03 +01:00
# A function that filters the install list and only returns remote packages
self.remote = lambda: filter(lambda x: isinstance(x, self.Remote), self.install)
def add(self, name, target=None):
2014-03-23 16:04:03 +01:00
"""Adds a package to the install list
Args:
name (str): The name of the package to install, may contain manifest vars references
target (str): The name of the target release for the package, may contain manifest vars references
Raises:
PackageError
"""
2014-04-07 21:49:07 +02:00
from exceptions import PackageError
name = name.format(**self.manifest_vars)
if target is not None:
target = target.format(**self.manifest_vars)
2014-03-23 16:04:03 +01:00
# Check if the package has already been added.
# If so, make sure it's the same target and raise a PackageError otherwise
package = next((pkg for pkg in self.remote() if pkg.name == name), None)
if package is not None:
2014-03-23 16:04:03 +01:00
# It's the same target if the target names match or one of the targets is None
# and the other is the default target.
same_target = package.target == target
same_target = same_target or package.target is None and target == self.default_target
same_target = same_target or package.target == self.default_target and target is None
if not same_target:
msg = ('The package {name} was already added to the package list, '
'but with target release `{target}\' instead of `{add_target}\''
.format(name=name, target=package.target, add_target=target))
raise PackageError(msg)
2014-03-23 16:04:03 +01:00
# The package has already been added, skip the checks below
return
2014-03-23 16:04:03 +01:00
# Check if the target exists in the sources list, raise a PackageError if not
check_target = target
if check_target is None:
check_target = self.default_target
if not self.source_lists.target_exists(check_target):
msg = ('The target release {target} was not found in the sources list').format(target=check_target)
raise PackageError(msg)
2014-03-23 16:04:03 +01:00
# Note that we maintain the target value even if it is none.
# This allows us to preserve the semantics of the default target when calling apt-get install
# Why? Try installing nfs-client/wheezy, you can't. It's a virtual package for which you cannot define
# a target release. Only `apt-get install nfs-client` works.
self.install.append(self.Remote(name, target))
def add_local(self, package_path):
2014-03-23 16:04:03 +01:00
"""Adds a local package to the installation list
Args:
package_path (str): Path to the local package, may contain manifest vars references
"""
package_path = package_path.format(**self.manifest_vars)
self.install.append(self.Local(package_path))