mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-25 07:46:28 +00:00
commit
24ac85802d
17 changed files with 75 additions and 75 deletions
|
@ -69,9 +69,9 @@ class AbstractPartitionMap(FSMProxy):
|
||||||
# Ask kpartx how the partitions will be mapped before actually attaching them.
|
# Ask kpartx how the partitions will be mapped before actually attaching them.
|
||||||
mappings = log_check_call(['kpartx', '-l', volume.device_path])
|
mappings = log_check_call(['kpartx', '-l', volume.device_path])
|
||||||
import re
|
import re
|
||||||
regexp = re.compile('^(?P<name>.+[^\d](?P<p_idx>\d+)) : '
|
regexp = re.compile(r'^(?P<name>.+[^\d](?P<p_idx>\d+)) : '
|
||||||
'(?P<start_blk>\d) (?P<num_blks>\d+) '
|
r'(?P<start_blk>\d) (?P<num_blks>\d+) '
|
||||||
'{device_path} (?P<blk_offset>\d+)$'
|
r'{device_path} (?P<blk_offset>\d+)$'
|
||||||
.format(device_path=volume.device_path))
|
.format(device_path=volume.device_path))
|
||||||
log_check_call(['kpartx', '-as', volume.device_path])
|
log_check_call(['kpartx', '-as', volume.device_path])
|
||||||
|
|
||||||
|
|
|
@ -56,11 +56,11 @@ class Source(object):
|
||||||
# The format is taken from `man sources.list`
|
# The format is taken from `man sources.list`
|
||||||
# or: http://manpages.debian.org/cgi-bin/man.cgi?sektion=5&query=sources.list&apropos=0&manpath=sid&locale=en
|
# or: http://manpages.debian.org/cgi-bin/man.cgi?sektion=5&query=sources.list&apropos=0&manpath=sid&locale=en
|
||||||
import re
|
import re
|
||||||
regexp = re.compile('^(?P<type>deb|deb-src)\s+'
|
regexp = re.compile(r'^(?P<type>deb|deb-src)\s+'
|
||||||
'(\[\s*(?P<options>.+\S)?\s*\]\s+)?'
|
r'(\[\s*(?P<options>.+\S)?\s*\]\s+)?'
|
||||||
'(?P<uri>\S+)\s+'
|
r'(?P<uri>\S+)\s+'
|
||||||
'(?P<distribution>\S+)'
|
r'(?P<distribution>\S+)'
|
||||||
'(\s+(?P<components>.+\S))?\s*$')
|
r'(\s+(?P<components>.+\S))?\s*$')
|
||||||
match = regexp.match(line).groupdict()
|
match = regexp.match(line).groupdict()
|
||||||
if match is None:
|
if match is None:
|
||||||
from .exceptions import SourceError
|
from .exceptions import SourceError
|
||||||
|
|
|
@ -189,7 +189,7 @@ def get_all_classes(path=None, prefix='', excludes=[]):
|
||||||
for class_name, obj in classes:
|
for class_name, obj in classes:
|
||||||
# We only want classes that are defined in the module, and not imported ones
|
# We only want classes that are defined in the module, and not imported ones
|
||||||
if obj.__module__ == module_name:
|
if obj.__module__ == module_name:
|
||||||
yield obj
|
yield obj
|
||||||
|
|
||||||
|
|
||||||
def check_ordering(task):
|
def check_ordering(task):
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Bytes(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse(qty_str):
|
def parse(qty_str):
|
||||||
import re
|
import re
|
||||||
regex = re.compile('^(?P<qty>\d+)(?P<unit>[KMGT]i?B|B)$')
|
regex = re.compile(r'^(?P<qty>\d+)(?P<unit>[KMGT]i?B|B)$')
|
||||||
parsed = regex.match(qty_str)
|
parsed = regex.match(qty_str)
|
||||||
if parsed is None:
|
if parsed is None:
|
||||||
raise UnitError('Unable to parse ' + qty_str)
|
raise UnitError('Unable to parse ' + qty_str)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from contextlib import contextmanager
|
||||||
|
|
||||||
def get_partitions():
|
def get_partitions():
|
||||||
import re
|
import re
|
||||||
regexp = re.compile('^ *(?P<major>\d+) *(?P<minor>\d+) *(?P<num_blks>\d+) (?P<dev_name>\S+)$')
|
regexp = re.compile(r'^ *(?P<major>\d+) *(?P<minor>\d+) *(?P<num_blks>\d+) (?P<dev_name>\S+)$')
|
||||||
matches = {}
|
matches = {}
|
||||||
path = '/proc/partitions'
|
path = '/proc/partitions'
|
||||||
with open(path) as partitions:
|
with open(path) as partitions:
|
||||||
|
|
|
@ -100,7 +100,7 @@ class AddManifestPreferences(Task):
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
for name, preferences in info.manifest.packages['preferences'].iteritems():
|
for name, preferences in info.manifest.packages['preferences'].iteritems():
|
||||||
info.preference_lists.add(name, preferences)
|
info.preference_lists.add(name, preferences)
|
||||||
|
|
||||||
|
|
||||||
class InstallTrustedKeys(Task):
|
class InstallTrustedKeys(Task):
|
||||||
|
|
|
@ -21,7 +21,7 @@ class CheckExternalCommands(Task):
|
||||||
log.debug('Checking availability of ' + command)
|
log.debug('Checking availability of ' + command)
|
||||||
path = find_executable(command)
|
path = find_executable(command)
|
||||||
if path is None or not os.access(path, os.X_OK):
|
if path is None or not os.access(path, os.X_OK):
|
||||||
if re.match('^https?:\/\/', package):
|
if re.match(r'^https?:\/\/', package):
|
||||||
msg = ('The command `{command}\' is not available, '
|
msg = ('The command `{command}\' is not available, '
|
||||||
'you can download the software at `{package}\'.'
|
'you can download the software at `{package}\'.'
|
||||||
.format(command=command, package=package))
|
.format(command=command, package=package))
|
||||||
|
|
|
@ -51,8 +51,8 @@ class SetGroups(Task):
|
||||||
from bootstrapvz.common.tools import sed_i
|
from bootstrapvz.common.tools import sed_i
|
||||||
cloud_cfg = os.path.join(info.root, 'etc/cloud/cloud.cfg')
|
cloud_cfg = os.path.join(info.root, 'etc/cloud/cloud.cfg')
|
||||||
groups = info.manifest.plugins['cloud_init']['groups']
|
groups = info.manifest.plugins['cloud_init']['groups']
|
||||||
search = ('^ groups: \[adm, audio, cdrom, dialout, floppy, video,'
|
search = (r'^ groups: \[adm, audio, cdrom, dialout, floppy, video,'
|
||||||
' plugdev, dip\]$')
|
r' plugdev, dip\]$')
|
||||||
replace = (' groups: [adm, audio, cdrom, dialout, floppy, video,'
|
replace = (' groups: [adm, audio, cdrom, dialout, floppy, video,'
|
||||||
' plugdev, dip, {groups}]').format(groups=', '.join(groups))
|
' plugdev, dip, {groups}]').format(groups=', '.join(groups))
|
||||||
sed_i(cloud_cfg, search, replace)
|
sed_i(cloud_cfg, search, replace)
|
||||||
|
@ -92,7 +92,7 @@ class DisableModules(Task):
|
||||||
if patterns != "":
|
if patterns != "":
|
||||||
patterns = patterns + "|" + pattern
|
patterns = patterns + "|" + pattern
|
||||||
else:
|
else:
|
||||||
patterns = "^\s+-\s+(" + pattern
|
patterns = r"^\s+-\s+(" + pattern
|
||||||
patterns = patterns + ")$"
|
patterns = patterns + ")$"
|
||||||
regex = re.compile(patterns)
|
regex = re.compile(patterns)
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class CreateBootstrapFilterScripts(Task):
|
||||||
# The pattern matching when excluding is needed in order to filter
|
# The pattern matching when excluding is needed in order to filter
|
||||||
# everything below e.g. /usr/share/locale but not the folder itself
|
# everything below e.g. /usr/share/locale but not the folder itself
|
||||||
filter_lists = info._minimize_size['bootstrap_filter']
|
filter_lists = info._minimize_size['bootstrap_filter']
|
||||||
exclude_list = '\|'.join(map(lambda p: '.' + p + '.\+', filter_lists['exclude']))
|
exclude_list = r'\|'.join(map(lambda p: '.' + p + r'.\+', filter_lists['exclude']))
|
||||||
include_list = '\n'.join(map(lambda p: '.' + p, filter_lists['include']))
|
include_list = '\n'.join(map(lambda p: '.' + p, filter_lists['include']))
|
||||||
sed_i(filter_script, r'EXCLUDE_PATTERN', exclude_list)
|
sed_i(filter_script, r'EXCLUDE_PATTERN', exclude_list)
|
||||||
sed_i(filter_script, r'INCLUDE_PATHS', include_list)
|
sed_i(filter_script, r'INCLUDE_PATHS', include_list)
|
||||||
|
|
|
@ -24,7 +24,7 @@ class SetNtpServers(Task):
|
||||||
import re
|
import re
|
||||||
ntp_path = os.path.join(info.root, 'etc/ntp.conf')
|
ntp_path = os.path.join(info.root, 'etc/ntp.conf')
|
||||||
servers = list(info.manifest.plugins['ntp']['servers'])
|
servers = list(info.manifest.plugins['ntp']['servers'])
|
||||||
debian_ntp_server = re.compile('.*[0-9]\.debian\.pool\.ntp\.org.*')
|
debian_ntp_server = re.compile(r'.*[0-9]\.debian\.pool\.ntp\.org.*')
|
||||||
for line in fileinput.input(files=ntp_path, inplace=True):
|
for line in fileinput.input(files=ntp_path, inplace=True):
|
||||||
# Will write all the specified servers on the first match, then supress all other default servers
|
# Will write all the specified servers on the first match, then supress all other default servers
|
||||||
if re.match(debian_ntp_server, line):
|
if re.match(debian_ntp_server, line):
|
||||||
|
|
|
@ -104,20 +104,20 @@ class CreateFromFolder(Task):
|
||||||
|
|
||||||
|
|
||||||
def set_fs_states(vol):
|
def set_fs_states(vol):
|
||||||
vol.fsm.current = 'detached'
|
vol.fsm.current = 'detached'
|
||||||
|
|
||||||
p_map = vol.partition_map
|
p_map = vol.partition_map
|
||||||
from bootstrapvz.base.fs.partitionmaps.none import NoPartitions
|
from bootstrapvz.base.fs.partitionmaps.none import NoPartitions
|
||||||
if not isinstance(p_map, NoPartitions):
|
if not isinstance(p_map, NoPartitions):
|
||||||
p_map.fsm.current = 'unmapped'
|
p_map.fsm.current = 'unmapped'
|
||||||
|
|
||||||
from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition
|
from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition
|
||||||
from bootstrapvz.base.fs.partitions.single import SinglePartition
|
from bootstrapvz.base.fs.partitions.single import SinglePartition
|
||||||
for partition in p_map.partitions:
|
for partition in p_map.partitions:
|
||||||
if isinstance(partition, UnformattedPartition):
|
if isinstance(partition, UnformattedPartition):
|
||||||
partition.fsm.current = 'unmapped'
|
partition.fsm.current = 'unmapped'
|
||||||
continue
|
continue
|
||||||
if isinstance(partition, SinglePartition):
|
if isinstance(partition, SinglePartition):
|
||||||
partition.fsm.current = 'formatted'
|
partition.fsm.current = 'formatted'
|
||||||
continue
|
continue
|
||||||
partition.fsm.current = 'unmapped_fmt'
|
partition.fsm.current = 'unmapped_fmt'
|
||||||
|
|
|
@ -147,7 +147,7 @@ class ApplyPuppetManifest(Task):
|
||||||
log_check_call(['chroot', info.root, 'puppet', 'apply', '--verbose', '--debug', manifest_path])
|
log_check_call(['chroot', info.root, 'puppet', 'apply', '--verbose', '--debug', manifest_path])
|
||||||
os.remove(manifest_dst)
|
os.remove(manifest_dst)
|
||||||
hosts_path = os.path.join(info.root, 'etc/hosts')
|
hosts_path = os.path.join(info.root, 'etc/hosts')
|
||||||
sed_i(hosts_path, '127.0.0.1\s*{hostname}\n?'.format(hostname=hostname), '')
|
sed_i(hosts_path, '127.0.0.1\\s*{hostname}\n?'.format(hostname=hostname), '')
|
||||||
|
|
||||||
|
|
||||||
class EnableAgent(Task):
|
class EnableAgent(Task):
|
||||||
|
|
|
@ -35,19 +35,19 @@ def validate_manifest(data, validator, error):
|
||||||
error('Paravirtualized AMIs only support pvgrub as a bootloader', ['system', 'bootloader'])
|
error('Paravirtualized AMIs only support pvgrub as a bootloader', ['system', 'bootloader'])
|
||||||
|
|
||||||
if backing != 'ebs' and virtualization == 'hvm':
|
if backing != 'ebs' and virtualization == 'hvm':
|
||||||
error('HVM AMIs currently only work when they are EBS backed', ['volume', 'backing'])
|
error('HVM AMIs currently only work when they are EBS backed', ['volume', 'backing'])
|
||||||
|
|
||||||
if backing == 's3' and partition_type != 'none':
|
if backing == 's3' and partition_type != 'none':
|
||||||
error('S3 backed AMIs currently only work with unpartitioned volumes', ['system', 'bootloader'])
|
error('S3 backed AMIs currently only work with unpartitioned volumes', ['system', 'bootloader'])
|
||||||
|
|
||||||
if backing != 'ebs' and encrypted:
|
if backing != 'ebs' and encrypted:
|
||||||
error('Encryption is supported only on EBS volumes')
|
error('Encryption is supported only on EBS volumes')
|
||||||
|
|
||||||
if encrypted is False and kms_key_id is not None:
|
if encrypted is False and kms_key_id is not None:
|
||||||
error('KMS Key Id can be set only when encryption is enabled')
|
error('KMS Key Id can be set only when encryption is enabled')
|
||||||
|
|
||||||
if enhanced_networking == 'simple' and virtualization != 'hvm':
|
if enhanced_networking == 'simple' and virtualization != 'hvm':
|
||||||
error('Enhanced networking only works with HVM virtualization', ['provider', 'virtualization'])
|
error('Enhanced networking only works with HVM virtualization', ['provider', 'virtualization'])
|
||||||
|
|
||||||
|
|
||||||
def resolve_tasks(taskset, manifest):
|
def resolve_tasks(taskset, manifest):
|
||||||
|
|
|
@ -53,7 +53,7 @@ class CreatePVGrubCustomRule(Task):
|
||||||
grub_device = 'GRUB_DEVICE=/dev/xvda' + str(root_idx)
|
grub_device = 'GRUB_DEVICE=/dev/xvda' + str(root_idx)
|
||||||
sed_i(script_dst, '^GRUB_DEVICE=/dev/xvda$', grub_device)
|
sed_i(script_dst, '^GRUB_DEVICE=/dev/xvda$', grub_device)
|
||||||
grub_root = '\troot (hd0,{idx})'.format(idx=root_idx - 1)
|
grub_root = '\troot (hd0,{idx})'.format(idx=root_idx - 1)
|
||||||
sed_i(script_dst, '^\troot \(hd0\)$', grub_root)
|
sed_i(script_dst, '^\troot \\(hd0\\)$', grub_root)
|
||||||
|
|
||||||
if info.manifest.volume['backing'] == 's3':
|
if info.manifest.volume['backing'] == 's3':
|
||||||
from bootstrapvz.common.tools import sed_i
|
from bootstrapvz.common.tools import sed_i
|
||||||
|
|
|
@ -23,7 +23,7 @@ def prepare_bootstrap(manifest, build_server):
|
||||||
bucket.delete_key(item.key)
|
bucket.delete_key(item.key)
|
||||||
s3_connection.delete_bucket(manifest.image['bucket'])
|
s3_connection.delete_bucket(manifest.image['bucket'])
|
||||||
else:
|
else:
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|
|
@ -46,42 +46,42 @@ def waituntil(predicate, timeout=5, interval=0.05):
|
||||||
|
|
||||||
|
|
||||||
def read_from_socket(socket_path, termination_string, timeout, read_timeout=0.5):
|
def read_from_socket(socket_path, termination_string, timeout, read_timeout=0.5):
|
||||||
import socket
|
import socket
|
||||||
import select
|
import select
|
||||||
import errno
|
import errno
|
||||||
console = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
console = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
console.connect(socket_path)
|
console.connect(socket_path)
|
||||||
console.setblocking(0)
|
console.setblocking(0)
|
||||||
|
|
||||||
from timeit import default_timer
|
from timeit import default_timer
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
|
|
||||||
output = ''
|
output = ''
|
||||||
ptr = 0
|
ptr = 0
|
||||||
continue_select = True
|
continue_select = True
|
||||||
while continue_select:
|
while continue_select:
|
||||||
read_ready, _, _ = select.select([console], [], [], read_timeout)
|
read_ready, _, _ = select.select([console], [], [], read_timeout)
|
||||||
if console in read_ready:
|
if console in read_ready:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
output += console.recv(1024)
|
output += console.recv(1024)
|
||||||
if termination_string in output[ptr:]:
|
if termination_string in output[ptr:]:
|
||||||
continue_select = False
|
|
||||||
else:
|
|
||||||
ptr = len(output) - len(termination_string)
|
|
||||||
break
|
|
||||||
except socket.error, e:
|
|
||||||
if e.errno != errno.EWOULDBLOCK:
|
|
||||||
raise Exception(e)
|
|
||||||
continue_select = False
|
continue_select = False
|
||||||
if default_timer() - start > timeout:
|
else:
|
||||||
from .exceptions import SocketReadTimeout
|
ptr = len(output) - len(termination_string)
|
||||||
msg = ('Reading from socket `{path}\' timed out after {seconds} seconds.\n'
|
break
|
||||||
'Here is the output so far:\n{output}'
|
except socket.error, e:
|
||||||
.format(path=socket_path, seconds=timeout, output=output))
|
if e.errno != errno.EWOULDBLOCK:
|
||||||
raise SocketReadTimeout(msg)
|
raise Exception(e)
|
||||||
console.close()
|
continue_select = False
|
||||||
return output
|
if default_timer() - start > timeout:
|
||||||
|
from .exceptions import SocketReadTimeout
|
||||||
|
msg = ('Reading from socket `{path}\' timed out after {seconds} seconds.\n'
|
||||||
|
'Here is the output so far:\n{output}'
|
||||||
|
.format(path=socket_path, seconds=timeout, output=output))
|
||||||
|
raise SocketReadTimeout(msg)
|
||||||
|
console.close()
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|
2
tox.ini
2
tox.ini
|
@ -2,7 +2,7 @@
|
||||||
envlist = flake8, pylint, yamllint, unit, integration, docs
|
envlist = flake8, pylint, yamllint, unit, integration, docs
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E221,E241,E501
|
ignore = E221,E241,E501,W504
|
||||||
max-line-length = 110
|
max-line-length = 110
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
|
Loading…
Add table
Reference in a new issue