From 064c4f24bddd0525f5b6ae4a136a3ab41ba1a893 Mon Sep 17 00:00:00 2001 From: Dhananjay Balan Date: Sun, 20 Apr 2014 22:24:41 +0530 Subject: [PATCH] Add salt plugin - uses salt bootstrap to install minion code - custom grains can be set. - option to specify master in the manifest. e.g manifest (TODO: Add this to doc.) "salt": { "install_source": "git", "version": "develop", \\ Only if the source is git "master": "", \\ salt master ip or fqdn "grains": { "custom_grain1": "custom_grain_value1", "custom_grain2": "custom_grain_value2", } } --- bootstrapvz/plugins/salt/__init__.py | 14 ++++ bootstrapvz/plugins/salt/manifest-schema.json | 38 +++++++++++ bootstrapvz/plugins/salt/tasks.py | 65 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 bootstrapvz/plugins/salt/__init__.py create mode 100644 bootstrapvz/plugins/salt/manifest-schema.json create mode 100644 bootstrapvz/plugins/salt/tasks.py diff --git a/bootstrapvz/plugins/salt/__init__.py b/bootstrapvz/plugins/salt/__init__.py new file mode 100644 index 0000000..0b9cf11 --- /dev/null +++ b/bootstrapvz/plugins/salt/__init__.py @@ -0,0 +1,14 @@ +import tasks + + +def validate_manifest(data, validator, error): + import os.path + schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.json')) + validator(data, schema_path) + + +def resolve_tasks(taskset, manifest): + taskset.add(tasks.InstallSaltDependencies) + taskset.add(tasks.BootstrapSaltMinion) + if 'grains' in manifest.plugins['salt']: + taskset.add(tasks.SetSaltGrains) diff --git a/bootstrapvz/plugins/salt/manifest-schema.json b/bootstrapvz/plugins/salt/manifest-schema.json new file mode 100644 index 0000000..82a7952 --- /dev/null +++ b/bootstrapvz/plugins/salt/manifest-schema.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Saltstack plugin manifest", + "type": "object", + "properties": { + "plugins": { + "type": "object", + "properties": { + "salt": { + "type": "object", + "properties": { + "master": { + "type": "string" + }, + "install_source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "grains": { + "type": "object", + "patternProperties": { + "^[^\/\\0]+$": { + "type": "string" + } + }, + "minItems": 1 + } + }, + "required": ["install_source"] + } + }, + "required": ["salt"] + } + }, + "required": ["plugins"] +} diff --git a/bootstrapvz/plugins/salt/tasks.py b/bootstrapvz/plugins/salt/tasks.py new file mode 100644 index 0000000..5a1b294 --- /dev/null +++ b/bootstrapvz/plugins/salt/tasks.py @@ -0,0 +1,65 @@ +from bootstrapvz.base import Task +from bootstrapvz.common import phases +from bootstrapvz.common.tasks import packages +from bootstrapvz.common.tasks import apt +from bootstrapvz.common.tools import log_check_call +from bootstrapvz.common.tools import sed_i +import os +import urllib + + +class InstallSaltDependencies(Task): + description = 'Add depended packages for salt-minion' + phase = phases.package_installation + predecessors = [apt.AddDefaultSources] + + @classmethod + def run(cls, info): + info.packages.add('curl') + info.packages.add('ca-certificates') + + +class BootstrapSaltMinion(Task): + description = 'Installing salt-minion using the bootstrap script' + phase = phases.package_installation + predecessors = [packages.InstallPackages] + + @classmethod + def run(cls, info): + # Download bootstrap script + bootstrap_script = os.path.join(info.root, 'install_salt.sh') + with open(bootstrap_script, 'w') as f: + d = urllib.urlopen('http://bootstrap.saltstack.org') + f.write(d.read()) + + # This is needed since bootstrap doesn't handle -X for debian distros properly. + # We disable checking for running services at end since we do not start them. + sed_i( + bootstrap_script, 'install_debian_check_services', + "disabled_debian_check_services") + + bootstrap_command = [ + 'chroot', info.root, 'bash', 'install_salt.sh', '-X'] + + if 'master' in info.manifest.plugins['salt']: + bootstrap_command.extend(['-A', info.manifest.plugins['salt']['master']]) + + install_source = info.manifest.plugins['salt']['install_source'] + + bootstrap_command.append(install_source) + if install_source == 'git' and ('version' in info.manifest.plugins['salt']): + bootstrap_command.append(info.manifest.plugins['salt']['version']) + log_check_call(bootstrap_command) + + +class SetSaltGrains(Task): + description = 'Set custom salt grains' + phase = phases.system_modification + + @classmethod + def run(cls, info): + grains_file = os.path.join(info.root, 'etc/salt/grains') + grains = info.manifest.plugins['salt']['grains'] + with open(grains_file, 'a') as f: + for g in grains: + f.write('%s: %s\n' % (g, grains[g]))