From 4ffb533625b32da9a84e16e56ecc821a775c7fda Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Sun, 29 Dec 2013 17:45:23 +0100 Subject: [PATCH] Use new package handling in the cloud-init plugin This saves quite a few "package" lines in the manifest --- ...bs-debian-official-amd64-hvm.manifest.json | 12 -- ...bs-debian-official-amd64-pvm.manifest.json | 12 -- ...ebs-debian-official-i386-pvm.manifest.json | 12 -- plugins/cloud_init/__init__.py | 42 +++---- plugins/cloud_init/manifest-schema.json | 13 +- plugins/cloud_init/tasks.py | 111 +++++++++--------- 6 files changed, 84 insertions(+), 118 deletions(-) diff --git a/manifests/ec2-ebs-debian-official-amd64-hvm.manifest.json b/manifests/ec2-ebs-debian-official-amd64-hvm.manifest.json index 5a09085..01887ae 100644 --- a/manifests/ec2-ebs-debian-official-amd64-hvm.manifest.json +++ b/manifests/ec2-ebs-debian-official-amd64-hvm.manifest.json @@ -30,18 +30,6 @@ } } }, - "packages": { - "sources": { - "backports": [ - "deb {apt_mirror} {system.release}-backports main", - "deb-src {apt_mirror} {system.release}-backports main" - ] - }, - "remote": [ - "sudo", - { "name": "cloud-init", "target": "{system.release}-backports" } - ] - }, "plugins": { "cloud_init": { "username": "admin", diff --git a/manifests/ec2-ebs-debian-official-amd64-pvm.manifest.json b/manifests/ec2-ebs-debian-official-amd64-pvm.manifest.json index 560a135..f81c444 100644 --- a/manifests/ec2-ebs-debian-official-amd64-pvm.manifest.json +++ b/manifests/ec2-ebs-debian-official-amd64-pvm.manifest.json @@ -30,18 +30,6 @@ } } }, - "packages": { - "sources": { - "backports": [ - "deb {apt_mirror} {system.release}-backports main", - "deb-src {apt_mirror} {system.release}-backports main" - ] - }, - "remote": [ - "sudo", - { "name": "cloud-init", "target": "{system.release}-backports" } - ] - }, "plugins": { "cloud_init": { "username": "admin", diff --git a/manifests/ec2-ebs-debian-official-i386-pvm.manifest.json b/manifests/ec2-ebs-debian-official-i386-pvm.manifest.json index 894c102..eee7125 100644 --- a/manifests/ec2-ebs-debian-official-i386-pvm.manifest.json +++ b/manifests/ec2-ebs-debian-official-i386-pvm.manifest.json @@ -30,18 +30,6 @@ } } }, - "packages": { - "sources": { - "backports": [ - "deb {apt_mirror} {system.release}-backports main", - "deb-src {apt_mirror} {system.release}-backports main" - ] - }, - "remote": [ - "sudo", - { "name": "cloud-init", "target": "{system.release}-backports" } - ] - }, "plugins": { "cloud_init": { "username": "admin", diff --git a/plugins/cloud_init/__init__.py b/plugins/cloud_init/__init__.py index df3a11c..35cfa05 100644 --- a/plugins/cloud_init/__init__.py +++ b/plugins/cloud_init/__init__.py @@ -4,40 +4,26 @@ def validate_manifest(data, schema_validate): from os import path schema_path = path.normpath(path.join(path.dirname(__file__), 'manifest-schema.json')) schema_validate(data, schema_path) - packages = data['plugins']['packages'] - cloud_init_installed = False - if 'remote' in packages: - for package in packages['remote']: - if isinstance(package, basestring): - name = package - else: - name = package['name'] - if name == 'cloud-init': - cloud_init_installed = True - break - if not cloud_init_installed: - from common.exceptions import ManifestError - raise ManifestError('The cloud-init package must be installed for the cloud_init plugin to work') def resolve_tasks(tasklist, manifest): - from tasks import SetUsername - from tasks import SetMetadataSource - from tasks import AutoSetMetadataSource - from tasks import DisableModules - from providers.ec2.tasks.initd import AddEC2InitScripts + import tasks + import providers.ec2.tasks.initd as initd_ec2 from common.tasks import initd - options = manifest.plugins['cloud_init'] - tasklist.add(AutoSetMetadataSource) - if 'username' in options: - tasklist.add(SetUsername) - if 'disable_modules' in options: - tasklist.add(DisableModules) - if 'metadata_sources' in options: - tasklist.add(SetMetadataSource) + if manifest.system['release'] in ['wheezy', 'stable']: + tasklist.add(tasks.AddBackports) - tasklist.remove(AddEC2InitScripts, + tasklist.add(tasks.AddCloudInitPackages, + tasks.SetMetadataSource) + + options = manifest.plugins['cloud_init'] + if 'username' in options: + tasklist.add(tasks.SetUsername) + if 'disable_modules' in options: + tasklist.add(tasks.DisableModules) + + tasklist.remove(initd_ec2.AddEC2InitScripts, initd.AddExpandRoot, initd.AdjustExpandRootScript, initd.AddSSHKeyGeneration) diff --git a/plugins/cloud_init/manifest-schema.json b/plugins/cloud_init/manifest-schema.json index 719716a..08cd153 100644 --- a/plugins/cloud_init/manifest-schema.json +++ b/plugins/cloud_init/manifest-schema.json @@ -3,6 +3,17 @@ "title": "cloud-init plugin manifest", "type": "object", "properties": { + "system": { + "type": "object", + "properties": { + "release": { + "type": "string", + "enum": ["wheezy", "stable", + "jessie", "testing", + "sid", "unstable"] + } + } + }, "plugins": { "type": "object", "properties": { @@ -27,7 +38,7 @@ }, "packages": {"type": "object"} }, - "required": ["cloud_init", "packages"] + "required": ["cloud_init"] } } } diff --git a/plugins/cloud_init/tasks.py b/plugins/cloud_init/tasks.py index 5613a56..1dbbc27 100644 --- a/plugins/cloud_init/tasks.py +++ b/plugins/cloud_init/tasks.py @@ -1,19 +1,42 @@ from base import Task from common import phases -from plugins.packages.tasks import InstallRemotePackages -from common.tasks import apt from common.tools import log_check_call -import re +import os.path + + +class AddBackports(Task): + description = 'Adding backports to the apt sources' + phase = phases.preparation + + def run(self, info): + if info.source_lists.target_exists('{system.release}-backports'): + import logging + msg = ('{system.release}-backports target already exists').format(**info.manifest_vars) + logging.getLogger(__name__).info(msg) + else: + info.source_lists.add('backports', 'deb {apt_mirror} {system.release}-backports main') + info.source_lists.add('backports', 'deb-src {apt_mirror} {system.release}-backports main') + + +class AddCloudInitPackages(Task): + description = 'Adding cloud-init package and sudo' + phase = phases.preparation + predecessors = [AddBackports] + + def run(self, info): + target = None + if info.manifest.system['release'] in ['wheezy', 'stable']: + target = '{system.release}-backports' + info.packages.add('cloud-init', target) + info.packages.add('sudo') class SetUsername(Task): description = 'Setting username in cloud.cfg' phase = phases.system_modification - predecessors = [InstallRemotePackages] def run(self, info): from common.tools import sed_i - import os.path cloud_cfg = os.path.join(info.root, 'etc/cloud/cloud.cfg') username = info.manifest.plugins['cloud_init']['username'] search = '^ name: debian$' @@ -24,60 +47,42 @@ class SetUsername(Task): class SetMetadataSource(Task): - description = 'Setting metadata source' - phase = phases.system_modification - predecessors = [apt.AptSources] - successors = [apt.AptUpdate] - - def run(self, info): - if "metadata_sources" in info.manifest.plugins['cloud_init']: - sources = "cloud-init cloud-init/datasources multiselect " + info.manifest.plugins['cloud_init']['metadata_sources'] - log_check_call(['/usr/sbin/chroot', info.root, '/usr/bin/debconf-set-selections'], sources) - - -class AutoSetMetadataSource(Task): - description = 'Auto-setting metadata source' - phase = phases.system_modification - predecessors = [apt.AptSources] - successors = [SetMetadataSource] + description = 'Setting metadata source' + phase = phases.system_modification def run(self, info): - sources = "" - if info.manifest.provider == "ec2": - sources = "Ec2" - - if sources: - print ("Setting metadata source to " + sources) - sources = "cloud-init cloud-init/datasources multiselect " + sources - log_check_call(['/usr/sbin/chroot', info.root, '/usr/bin/debconf-set-selections'], sources) + if 'metadata_sources' in info.manifest.plugins['cloud_init']: + sources = info.manifest.plugins['cloud_init']['metadata_sources'] + else: + source_mapping = {'ec2': 'Ec2'} + sources = source_mapping.get(info.manifest.provider, None) + if sources is None: + import logging + msg = ('No cloud-init metadata source mapping found for provider `{provider}\', ' + 'skipping selections setting.').format(info.manifest.provider) + logging.getLogger(__name__).warn(msg) + return + sources = "cloud-init cloud-init/datasources multiselect " + sources + log_check_call(['/usr/sbin/chroot', info.root, '/usr/bin/debconf-set-selections'], sources) class DisableModules(Task): description = 'Setting cloud.cfg modules' - phase = phases.system_modification - predecessors = [apt.AptUpgrade] + phase = phases.system_modification def run(self, info): - if 'disable_modules' in info.manifest.plugins['cloud_init']: - patterns = "" - for pattern in info.manifest.plugins['cloud_init']['disable_modules']: - if patterns != "": - patterns = patterns + "|" + pattern - else: - patterns = "^\s+-\s+(" + pattern - patterns = patterns + ")$" - regex = re.compile(patterns) + import re + patterns = "" + for pattern in info.manifest.plugins['cloud_init']['disable_modules']: + if patterns != "": + patterns = patterns + "|" + pattern + else: + patterns = "^\s+-\s+(" + pattern + patterns = patterns + ")$" + regex = re.compile(patterns) - try: - f = open(info.root + "/etc/cloud/cloud.cfg") - lines = f.readlines() - f.close() - except: - print "Cannot read cloud.cfg" - return -1 - - f = open(info.root + "/etc/cloud/cloud.cfg", "w") - for line in lines: - if not regex.match(line): - f.write(line) - f.close + cloud_cfg = os.path.join(info.root, 'etc/cloud/cloud.cfg') + import fileinput + for line in fileinput.input(files=cloud_cfg, inplace=True): + if not regex.match(line): + print line,