Use `type' to check if command available. Fixes #11

This commit is contained in:
Anders Ingemann 2014-02-23 21:51:28 +01:00
parent 739e22e929
commit 5cff8f9b1d
6 changed files with 34 additions and 30 deletions

View file

@ -55,6 +55,6 @@ class BootstrapInformation(object):
self.include_packages = set()
self.exclude_packages = set()
self.host_dependencies = set()
self.host_dependencies = {}
self.initd = {'install': {}, 'disable': []}

View file

@ -12,8 +12,8 @@ from common.tasks import security
from common.tasks import locale
base_set = [workspace.CreateWorkspace,
host.HostDependencies,
host.CheckHostDependencies,
host.AddExternalCommands,
host.CheckExternalCommands,
bootstrap.Bootstrap,
workspace.DeleteWorkspace,
]

View file

@ -3,47 +3,49 @@ from common import phases
from common.exceptions import TaskError
class HostDependencies(Task):
description = 'Determining required host dependencies'
class AddExternalCommands(Task):
description = 'Determining which external commands are required'
phase = phases.preparation
@classmethod
def run(cls, info):
info.host_dependencies.add('debootstrap')
info.host_dependencies['debootstrap'] = 'debootstrap'
from common.fs.loopbackvolume import LoopbackVolume
if isinstance(info.volume, LoopbackVolume):
info.host_dependencies.add('qemu-utils')
info.host_dependencies['qemu-img'] = 'qemu-utils'
info.host_dependencies['losetup'] = 'mount'
from common.fs.qemuvolume import QEMUVolume
if isinstance(info.volume, QEMUVolume):
info.host_dependencies['losetup'] = 'qemu-nbd'
if 'xfs' in (p.filesystem for p in info.volume.partition_map.partitions):
info.host_dependencies.add('xfsprogs')
info.host_dependencies['mkfs.xfs'] = 'xfsprogs'
from base.fs.partitionmaps.none import NoPartitions
if not isinstance(info.volume.partition_map, NoPartitions):
info.host_dependencies.update(['parted', 'kpartx'])
info.host_dependencies['parted'] = 'parted'
info.host_dependencies['kpartx'] = 'kpartx'
class CheckHostDependencies(Task):
description = 'Checking installed host packages'
class CheckExternalCommands(Task):
description = 'Checking availability of external commands'
phase = phases.preparation
predecessors = [HostDependencies]
predecessors = [AddExternalCommands]
@classmethod
def run(cls, info):
from common.tools import log_check_call
from subprocess import CalledProcessError
missing_packages = []
for package in info.host_dependencies:
for command, package in info.host_dependencies.items():
try:
import os.path
if os.path.isfile('/usr/bin/dpkg-query'):
log_check_call(['/usr/bin/dpkg-query', '-s', package])
log_check_call(['type ' + command], shell=True)
except CalledProcessError:
missing_packages.append(package)
msg = ('The command `{command}\' is not available, '
'it is located in the package `{package}\'.'
.format(command=command, package=package))
missing_packages.append(msg)
if len(missing_packages) > 0:
pkgs = '\', `'.join(missing_packages)
if len(missing_packages) > 1:
msg = "The packages `{packages}\' are not installed".format(packages=pkgs)
else:
msg = "The package `{packages}\' is not installed".format(packages=pkgs)
msg = '\n'.join(missing_packages)
raise TaskError(msg)

View file

@ -1,14 +1,14 @@
def log_check_call(command, stdin=None, env=None):
status, stdout, stderr = log_call(command, stdin, env)
def log_check_call(command, stdin=None, env=None, shell=False):
status, stdout, stderr = log_call(command, stdin, env, shell)
if status != 0:
from subprocess import CalledProcessError
raise CalledProcessError(status, ' '.join(command), '\n'.join(stderr))
return stdout
def log_call(command, stdin=None, env=None):
def log_call(command, stdin=None, env=None, shell=False):
import subprocess
import select
@ -22,6 +22,7 @@ def log_call(command, stdin=None, env=None):
popen_args = {'args': command,
'env': env,
'shell': shell,
'stdin': subprocess.PIPE,
'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE, }

View file

@ -61,7 +61,7 @@ def resolve_tasks(taskset, manifest):
if manifest.volume['partitions']['type'] != 'none':
taskset.update(common.task_sets.partitioning_set)
taskset.update([tasks.host.HostDependencies,
taskset.update([tasks.host.AddExternalCommands,
tasks.packages.DefaultPackages,
tasks.connection.GetCredentials,
tasks.host.GetInfo,

View file

@ -3,15 +3,16 @@ from common import phases
from common.tasks import host
class HostDependencies(Task):
description = 'Adding required host packages for EC2 bootstrapping'
class AddExternalCommands(Task):
description = 'Determining required external commands for EC2 bootstrapping'
phase = phases.preparation
successors = [host.CheckHostDependencies]
successors = [host.CheckExternalCommands]
@classmethod
def run(cls, info):
if info.manifest.volume['backing'] == 's3':
info.host_dependencies.add('euca2ools')
info.host_dependencies['euca-bundle-image'] = 'euca2ools'
info.host_dependencies['euca-upload-bundle'] = 'euca2ools'
class GetInfo(Task):