2013-12-29 16:09:47 +01:00
|
|
|
|
|
|
|
|
|
|
|
class PackageList(object):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""Represents a list of packages
|
|
|
|
"""
|
2013-12-29 16:09:47 +01:00
|
|
|
|
2014-01-12 12:46:59 +01:00
|
|
|
class Remote(object):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""A remote package with an optional target
|
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
def __init__(self, name, target):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-05-04 19:31:53 +02:00
|
|
|
:param str name: The name of the package
|
|
|
|
:param str target: The name of the target release
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
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
|
2014-05-04 19:31:53 +02:00
|
|
|
|
|
|
|
:rtype: str
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
if self.target is None:
|
|
|
|
return self.name
|
|
|
|
else:
|
2014-05-03 22:24:13 +02:00
|
|
|
return self.name + '/' + self.target
|
2014-01-12 12:46:59 +01:00
|
|
|
|
|
|
|
class Local(object):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""A local package
|
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
def __init__(self, path):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-05-04 19:31:53 +02:00
|
|
|
:param str path: The path to the local package
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
self.path = path
|
|
|
|
|
|
|
|
def __str__(self):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-05-04 19:31:53 +02:00
|
|
|
:return: The path to the local package
|
|
|
|
:rtype: string
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-01-12 12:46:59 +01:00
|
|
|
return self.path
|
|
|
|
|
2014-01-09 17:21:29 +01:00
|
|
|
def __init__(self, manifest_vars, source_lists):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-05-04 19:31:53 +02:00
|
|
|
:param dict manifest_vars: The manifest variables
|
|
|
|
:param SourceLists source_lists: The sourcelists for apt
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2013-12-29 16:48:55 +01:00
|
|
|
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
|
2014-01-12 12:46:59 +01:00
|
|
|
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.
|
2014-01-12 12:46:59 +01:00
|
|
|
self.install = []
|
2014-03-23 16:04:03 +01:00
|
|
|
# A function that filters the install list and only returns remote packages
|
2014-01-12 12:46:59 +01:00
|
|
|
self.remote = lambda: filter(lambda x: isinstance(x, self.Remote), self.install)
|
2013-12-29 16:09:47 +01:00
|
|
|
|
|
|
|
def add(self, name, target=None):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""Adds a package to the install list
|
|
|
|
|
2014-05-04 19:31:53 +02:00
|
|
|
:param str name: 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
|
2014-03-23 16:04:03 +01:00
|
|
|
|
2014-05-04 19:31:53 +02:00
|
|
|
:raises PackageError: When a package of the same name but with a different target has already been added.
|
|
|
|
:raises PackageError: When the specified target release could not be found.
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2014-04-07 21:49:07 +02:00
|
|
|
from exceptions import PackageError
|
2013-12-29 16:48:55 +01:00
|
|
|
name = name.format(**self.manifest_vars)
|
2014-01-12 12:46:59 +01:00
|
|
|
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
|
2014-01-12 12:46:59 +01:00
|
|
|
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.
|
2014-03-06 20:37:07 +01:00
|
|
|
same_target = package.target == target
|
2014-01-12 12:46:59 +01:00
|
|
|
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:
|
2013-12-29 16:09:47 +01:00
|
|
|
msg = ('The package {name} was already added to the package list, '
|
2014-03-06 20:37:07 +01:00
|
|
|
'but with target release `{target}\' instead of `{add_target}\''
|
|
|
|
.format(name=name, target=package.target, add_target=target))
|
2013-12-29 16:09:47 +01:00
|
|
|
raise PackageError(msg)
|
2014-03-23 16:04:03 +01:00
|
|
|
# The package has already been added, skip the checks below
|
2013-12-29 16:09:47 +01:00
|
|
|
return
|
|
|
|
|
2015-04-29 23:39:55 +02:00
|
|
|
# Check if the target exists (unless it's the default target) in the sources list
|
|
|
|
# raise a PackageError if does not
|
|
|
|
if target not in (None, self.default_target) and not self.source_lists.target_exists(target):
|
|
|
|
msg = ('The target release {target} was not found in the sources list').format(target=target)
|
2013-12-29 16:09:47 +01:00
|
|
|
raise PackageError(msg)
|
2014-01-12 12:46:59 +01:00
|
|
|
|
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.
|
2014-01-12 12:46:59 +01:00
|
|
|
self.install.append(self.Remote(name, target))
|
2013-12-29 17:38:29 +01:00
|
|
|
|
|
|
|
def add_local(self, package_path):
|
2014-03-23 16:04:03 +01:00
|
|
|
"""Adds a local package to the installation list
|
|
|
|
|
2014-05-04 19:31:53 +02:00
|
|
|
:param str package_path: Path to the local package, may contain manifest vars references
|
2014-03-23 16:04:03 +01:00
|
|
|
"""
|
2013-12-29 17:38:29 +01:00
|
|
|
package_path = package_path.format(**self.manifest_vars)
|
2014-01-12 12:46:59 +01:00
|
|
|
self.install.append(self.Local(package_path))
|