mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-10-07 17:40:30 +00:00
Added an Ansible plugin, which runs a playbook on the chroot before before build completion.
NOTE: I'm not doing any validation on the opt_flags param and I don't recommend using for more then adding a -vvvv. Also, I'm purposely excluding the vault flags (which also pretty commonly used) because you shouldn't be baking private keys and certs into your images. Instead, just avoid running the vault specific code or use the opt_flags if absolutely necessary.
This commit is contained in:
parent
fce3f502ab
commit
c372757104
3 changed files with 140 additions and 0 deletions
13
bootstrapvz/plugins/ansible/__init__.py
Normal file
13
bootstrapvz/plugins/ansible/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
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.yml'))
|
||||
validator(data, schema_path)
|
||||
|
||||
|
||||
def resolve_tasks(taskset, manifest):
|
||||
taskset.add(tasks.AddPackages)
|
||||
taskset.add(tasks.CheckPlaybookPath)
|
||||
taskset.add(tasks.RunAnsiblePlaybook)
|
29
bootstrapvz/plugins/ansible/manifest-schema.yml
Normal file
29
bootstrapvz/plugins/ansible/manifest-schema.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
$schema: http://json-schema.org/draft-04/schema#
|
||||
title: Ansible plugin manifest
|
||||
type: object
|
||||
properties:
|
||||
plugins:
|
||||
type: object
|
||||
properties:
|
||||
ansible:
|
||||
type: object
|
||||
properties:
|
||||
extra_vars: {type: string}
|
||||
tags: {type: string}
|
||||
skip_tags: {type: string}
|
||||
opt_flags:
|
||||
type: array
|
||||
flag: {type: string}
|
||||
minItems: 1
|
||||
hosts:
|
||||
type: array
|
||||
host: {type: string}
|
||||
minItems: 1
|
||||
playbook: {$ref: '#/definitions/absolute_path'}
|
||||
required:
|
||||
- playbook
|
||||
definitions:
|
||||
absolute_path:
|
||||
pattern: ^/[^\0]+$
|
||||
type: string
|
98
bootstrapvz/plugins/ansible/tasks.py
Normal file
98
bootstrapvz/plugins/ansible/tasks.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
from bootstrapvz.base import Task
|
||||
from bootstrapvz.common import phases
|
||||
from bootstrapvz.common.tasks import apt
|
||||
import os
|
||||
|
||||
|
||||
class CheckPlaybookPath(Task):
|
||||
description = 'Checking whether the playbook path exist'
|
||||
phase = phases.preparation
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from bootstrapvz.common.exceptions import TaskError
|
||||
playbook = info.manifest.plugins['ansible']['playbook']
|
||||
if not os.path.exists(playbook):
|
||||
msg = 'The playbook file {playbook} does not exist.'.format(playbook=playbook)
|
||||
raise TaskError(msg)
|
||||
if not os.path.isfile(playbook):
|
||||
msg = 'The playbook path {playbook} does not point to a file.'.format(playbook=playbook)
|
||||
raise TaskError(msg)
|
||||
|
||||
|
||||
class AddPackages(Task):
|
||||
description = 'Making sure python is installed'
|
||||
phase = phases.preparation
|
||||
predecessors = [apt.AddDefaultSources]
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
info.packages.add('python')
|
||||
|
||||
|
||||
class RunAnsiblePlaybook(Task):
|
||||
description = 'Running ansible playbooks'
|
||||
phase = phases.system_modification
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
|
||||
# Extract playbook and directory
|
||||
playbook = info.manifest.plugins['ansible']['playbook']
|
||||
playbook_dir = os.path.dirname(os.path.realpath(playbook))
|
||||
|
||||
# Check for hosts
|
||||
hosts = None
|
||||
if 'hosts' in info.manifest.plugins['ansible']:
|
||||
hosts = info.manifest.plugins['ansible']['hosts']
|
||||
|
||||
# Check for extra vars
|
||||
extra_vars = None
|
||||
if 'extra_vars' in info.manifest.plugins['ansible']:
|
||||
extra_vars = info.manifest.plugins['ansible']['extra_vars']
|
||||
|
||||
tags = None
|
||||
if 'tags' in info.manifest.plugins['ansible']:
|
||||
tags = info.manifest.plugins['ansible']['tags']
|
||||
|
||||
skip_tags = None
|
||||
if 'skip_tags' in info.manifest.plugins['ansible']:
|
||||
skip_tags = info.manifest.plugins['ansible']['skip_tags']
|
||||
|
||||
opt_flags = None
|
||||
if 'opt_flags' in info.manifest.plugins['ansible']:
|
||||
opt_flags = info.manifest.plugins['ansible']['opt_flags']
|
||||
|
||||
# build the inventory file
|
||||
inventory = os.path.join(info.root, 'tmp/bootstrap-inventory')
|
||||
with open(inventory, 'w') as handle:
|
||||
conn = '{} ansible_connection=chroot'.format(info.root)
|
||||
content = ""
|
||||
|
||||
if hosts:
|
||||
for host in hosts:
|
||||
content += '[{}]\n{}\n'.format(host, conn)
|
||||
else:
|
||||
content = conn
|
||||
|
||||
handle.write(content)
|
||||
|
||||
# build the ansible command
|
||||
cmd = ['ansible-playbook', '-i', inventory, os.path.basename(playbook)]
|
||||
if extra_vars:
|
||||
tmp_cmd = ['--extra-vars', '\"{}\"'.format(extra_vars)]
|
||||
cmd.extend(tmp_cmd)
|
||||
if tags:
|
||||
tmp_cmd = ['--tags={}'.format(tags)]
|
||||
cmd.extend(tmp_cmd)
|
||||
if skip_tags:
|
||||
tmp_cmd = ['--skip_tags={}'.format(skip_tags)]
|
||||
cmd.extend(tmp_cmd)
|
||||
if opt_flags:
|
||||
# Should probably do proper validation on these, but I don't think it should be used very often.
|
||||
cmd.extend(opt_flags)
|
||||
|
||||
# Run and remove the inventory file
|
||||
log_check_call(cmd, cwd=playbook_dir)
|
||||
os.remove(inventory)
|
Loading…
Add table
Reference in a new issue