diff --git a/plugins/chef/__init__.py b/plugins/chef/__init__.py new file mode 100644 index 0000000..7ba2396 --- /dev/null +++ b/plugins/chef/__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.AddPackages) + if 'assets' in manifest.plugins['chef']: + taskset.add(tasks.CheckAssetsPath) + taskset.add(tasks.CopyChefAssets) diff --git a/plugins/chef/manifest-schema.json b/plugins/chef/manifest-schema.json new file mode 100644 index 0000000..9bc9d47 --- /dev/null +++ b/plugins/chef/manifest-schema.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Puppet plugin manifest", + "type": "object", + "properties": { + "plugins": { + "type": "object", + "properties": { + "chef": { + "type": "object", + "properties": { + "assets": { "$ref": "#/definitions/absolute_path" } + }, + "minProperties": 1, + "additionalProperties": false + } + } + } + }, + "definitions": { + "absolute_path": { + "type": "string", + "pattern": "^/[^\\0]+$" + } + } +} diff --git a/plugins/chef/tasks.py b/plugins/chef/tasks.py new file mode 100644 index 0000000..198bc7f --- /dev/null +++ b/plugins/chef/tasks.py @@ -0,0 +1,55 @@ +from base import Task +from common import phases +from common.tasks import apt +import os + + +class CheckAssetsPath(Task): + description = 'Checking whether the assets path exist' + phase = phases.preparation + + @classmethod + def run(cls, info): + from common.exceptions import TaskError + assets = info.manifest.plugins['chef']['assets'] + if not os.path.exists(assets): + msg = 'The assets directory {assets} does not exist.'.format(assets=assets) + raise TaskError(msg) + if not os.path.isdir(assets): + msg = 'The assets path {assets} does not point to a directory.'.format(assets=assets) + raise TaskError(msg) + + +class AddPackages(Task): + description = 'Add chef package' + phase = phases.preparation + predecessors = [apt.AddDefaultSources] + + @classmethod + def run(cls, info): + info.packages.add('chef') + + +class CopyChefAssets(Task): + description = 'Copying chef assets' + phase = phases.system_modification + + @classmethod + def run(cls, info): + from shutil import copy + chef_path = os.path.join(info.root, 'etc/chef') + chef_assets = info.manifest.plugins['chef']['assets'] + for abs_prefix, dirs, files in os.walk(chef_assets): + prefix = os.path.normpath(os.path.relpath(abs_prefix, chef_assets)) + for path in dirs: + full_path = os.path.join(chef_path, prefix, path) + if os.path.exists(full_path): + if os.path.isdir(full_path): + continue + else: + os.remove(full_path) + os.mkdir(full_path) + for path in files: + copy(os.path.join(abs_prefix, path), + os.path.join(chef_path, prefix, path)) +