mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 07:26:29 +00:00
Use `type' to check if command available. Fixes #11
This commit is contained in:
parent
739e22e929
commit
5cff8f9b1d
6 changed files with 34 additions and 30 deletions
|
@ -55,6 +55,6 @@ class BootstrapInformation(object):
|
||||||
self.include_packages = set()
|
self.include_packages = set()
|
||||||
self.exclude_packages = set()
|
self.exclude_packages = set()
|
||||||
|
|
||||||
self.host_dependencies = set()
|
self.host_dependencies = {}
|
||||||
|
|
||||||
self.initd = {'install': {}, 'disable': []}
|
self.initd = {'install': {}, 'disable': []}
|
||||||
|
|
|
@ -12,8 +12,8 @@ from common.tasks import security
|
||||||
from common.tasks import locale
|
from common.tasks import locale
|
||||||
|
|
||||||
base_set = [workspace.CreateWorkspace,
|
base_set = [workspace.CreateWorkspace,
|
||||||
host.HostDependencies,
|
host.AddExternalCommands,
|
||||||
host.CheckHostDependencies,
|
host.CheckExternalCommands,
|
||||||
bootstrap.Bootstrap,
|
bootstrap.Bootstrap,
|
||||||
workspace.DeleteWorkspace,
|
workspace.DeleteWorkspace,
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,47 +3,49 @@ from common import phases
|
||||||
from common.exceptions import TaskError
|
from common.exceptions import TaskError
|
||||||
|
|
||||||
|
|
||||||
class HostDependencies(Task):
|
class AddExternalCommands(Task):
|
||||||
description = 'Determining required host dependencies'
|
description = 'Determining which external commands are required'
|
||||||
phase = phases.preparation
|
phase = phases.preparation
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
info.host_dependencies.add('debootstrap')
|
info.host_dependencies['debootstrap'] = 'debootstrap'
|
||||||
|
|
||||||
from common.fs.loopbackvolume import LoopbackVolume
|
from common.fs.loopbackvolume import LoopbackVolume
|
||||||
if isinstance(info.volume, 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):
|
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
|
from base.fs.partitionmaps.none import NoPartitions
|
||||||
if not isinstance(info.volume.partition_map, 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):
|
class CheckExternalCommands(Task):
|
||||||
description = 'Checking installed host packages'
|
description = 'Checking availability of external commands'
|
||||||
phase = phases.preparation
|
phase = phases.preparation
|
||||||
predecessors = [HostDependencies]
|
predecessors = [AddExternalCommands]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
from common.tools import log_check_call
|
from common.tools import log_check_call
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
missing_packages = []
|
missing_packages = []
|
||||||
for package in info.host_dependencies:
|
for command, package in info.host_dependencies.items():
|
||||||
try:
|
try:
|
||||||
import os.path
|
log_check_call(['type ' + command], shell=True)
|
||||||
if os.path.isfile('/usr/bin/dpkg-query'):
|
|
||||||
log_check_call(['/usr/bin/dpkg-query', '-s', package])
|
|
||||||
except CalledProcessError:
|
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:
|
if len(missing_packages) > 0:
|
||||||
pkgs = '\', `'.join(missing_packages)
|
msg = '\n'.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)
|
|
||||||
raise TaskError(msg)
|
raise TaskError(msg)
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
|
|
||||||
def log_check_call(command, stdin=None, env=None):
|
def log_check_call(command, stdin=None, env=None, shell=False):
|
||||||
status, stdout, stderr = log_call(command, stdin, env)
|
status, stdout, stderr = log_call(command, stdin, env, shell)
|
||||||
if status != 0:
|
if status != 0:
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
raise CalledProcessError(status, ' '.join(command), '\n'.join(stderr))
|
raise CalledProcessError(status, ' '.join(command), '\n'.join(stderr))
|
||||||
return stdout
|
return stdout
|
||||||
|
|
||||||
|
|
||||||
def log_call(command, stdin=None, env=None):
|
def log_call(command, stdin=None, env=None, shell=False):
|
||||||
import subprocess
|
import subprocess
|
||||||
import select
|
import select
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ def log_call(command, stdin=None, env=None):
|
||||||
|
|
||||||
popen_args = {'args': command,
|
popen_args = {'args': command,
|
||||||
'env': env,
|
'env': env,
|
||||||
|
'shell': shell,
|
||||||
'stdin': subprocess.PIPE,
|
'stdin': subprocess.PIPE,
|
||||||
'stdout': subprocess.PIPE,
|
'stdout': subprocess.PIPE,
|
||||||
'stderr': subprocess.PIPE, }
|
'stderr': subprocess.PIPE, }
|
||||||
|
|
|
@ -61,7 +61,7 @@ def resolve_tasks(taskset, manifest):
|
||||||
if manifest.volume['partitions']['type'] != 'none':
|
if manifest.volume['partitions']['type'] != 'none':
|
||||||
taskset.update(common.task_sets.partitioning_set)
|
taskset.update(common.task_sets.partitioning_set)
|
||||||
|
|
||||||
taskset.update([tasks.host.HostDependencies,
|
taskset.update([tasks.host.AddExternalCommands,
|
||||||
tasks.packages.DefaultPackages,
|
tasks.packages.DefaultPackages,
|
||||||
tasks.connection.GetCredentials,
|
tasks.connection.GetCredentials,
|
||||||
tasks.host.GetInfo,
|
tasks.host.GetInfo,
|
||||||
|
|
|
@ -3,15 +3,16 @@ from common import phases
|
||||||
from common.tasks import host
|
from common.tasks import host
|
||||||
|
|
||||||
|
|
||||||
class HostDependencies(Task):
|
class AddExternalCommands(Task):
|
||||||
description = 'Adding required host packages for EC2 bootstrapping'
|
description = 'Determining required external commands for EC2 bootstrapping'
|
||||||
phase = phases.preparation
|
phase = phases.preparation
|
||||||
successors = [host.CheckHostDependencies]
|
successors = [host.CheckExternalCommands]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
if info.manifest.volume['backing'] == 's3':
|
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):
|
class GetInfo(Task):
|
||||||
|
|
Loading…
Add table
Reference in a new issue