Merge "Ansible 2.0 support in ansible handlers"

This commit is contained in:
Jenkins 2016-02-04 09:57:24 +00:00 committed by Gerrit Code Review
commit ecd6bb0842
5 changed files with 91 additions and 80 deletions

2
bootstrap/playbooks/files/ubuntu-ansible.sh Normal file → Executable file
View File

@ -8,4 +8,4 @@ sudo apt-get update
sudo apt-get install -y python-setuptools python-dev autoconf g++
sudo easy_install pip
sudo pip install -U pip
sudo pip install "ansible<2.0"
sudo pip install "ansible"

View File

@ -14,7 +14,7 @@ tabulate==0.7.5
gevent>=1.0.2
# we need callbacks for now
ansible<2.0
ansible
mock
multipledispatch==0.4.8

View File

@ -19,7 +19,6 @@ import json
import shutil
import tempfile
from solar.core.handlers import base
from solar.core.handlers.base import SOLAR_TEMP_LOCAL_LOCATION
from solar.core.handlers.base import TempFileHandler
from solar.core.log import log
@ -29,7 +28,7 @@ from solar.core.provider import SVNProvider
ROLES_PATH = '/etc/ansible/roles'
class AnsiblePlaybookBase(base.BaseHandler):
class AnsiblePlaybookBase(TempFileHandler):
def download_roles(self, urls):
if not os.path.exists(ROLES_PATH):
@ -39,8 +38,43 @@ class AnsiblePlaybookBase(base.BaseHandler):
provider.run()
shutil.copytree(provider.directory, ROLES_PATH)
def make_ansible_command(self, remote_playbook_file,
remote_inventory_file, remote_extra_vars_file,
ansible_library_path):
if ansible_library_path:
remote_ansible_library_path = ansible_library_path.replace(
SOLAR_TEMP_LOCAL_LOCATION, '/tmp/')
call_args = [
'ansible-playbook',
'--module-path',
remote_ansible_library_path,
'-i',
remote_inventory_file,
'--extra-vars',
'@%s' % remote_extra_vars_file,
remote_playbook_file
]
else:
call_args = [
'ansible-playbook',
'-i',
remote_inventory_file,
'--extra-vars',
'@%s' % remote_extra_vars_file,
remote_playbook_file
]
return call_args
class AnsiblePlaybook(AnsiblePlaybookBase, TempFileHandler):
def _copy_ansible_library(self, resource):
base_path = resource.db_obj.base_path
src_ansible_library_dir = os.path.join(base_path, 'ansible_library')
trg_ansible_library_dir = None
if os.path.exists(src_ansible_library_dir):
log.debug("Adding ansible_library for %s", resource.name)
trg_ansible_library_dir = os.path.join(
self.dirs[resource.name], 'ansible_library')
shutil.copytree(src_ansible_library_dir, trg_ansible_library_dir)
return trg_ansible_library_dir
def _make_playbook(self, resource, action, action_path):
dir_path = self.dirs[resource.name]
@ -68,6 +102,9 @@ class AnsiblePlaybook(AnsiblePlaybookBase, TempFileHandler):
r_args = resource.args
return json.dumps(r_args)
class AnsiblePlaybook(AnsiblePlaybookBase):
def action(self, resource, action):
action_file = os.path.join(
resource.db_obj.actions_path,
@ -95,28 +132,11 @@ class AnsiblePlaybook(AnsiblePlaybookBase, TempFileHandler):
remote_extra_vars_file = extra_vars_file.replace(
SOLAR_TEMP_LOCAL_LOCATION, '/tmp/')
if ansible_library_path:
remote_ansible_library_path = ansible_library_path.replace(
SOLAR_TEMP_LOCAL_LOCATION, '/tmp/')
call_args = [
'ansible-playbook',
'--module-path',
remote_ansible_library_path,
'-i',
remote_inventory_file,
'--extra-vars',
'@%s' % remote_extra_vars_file,
remote_playbook_file
]
else:
call_args = [
'ansible-playbook',
'-i',
remote_inventory_file,
'--extra-vars',
'@%s' % remote_extra_vars_file,
remote_playbook_file
]
call_args = self.make_ansible_command(remote_playbook_file,
remote_inventory_file,
remote_extra_vars_file,
ansible_library_path)
log.debug('EXECUTING: %s', ' '.join(call_args))
rst = self.transport_run.run(resource, *call_args)

View File

@ -15,73 +15,60 @@
import os
# this has to be before callbacks, otherwise ansible circural import problem
from ansible import utils
# intentional line, otherwise H306
from ansible import callbacks
import ansible.constants as C
from ansible.playbook import PlayBook
from solar.core.transports.base import find_named_transport
from solar import errors
from solar.core.handlers.ansible_playbook import AnsiblePlaybookBase
from solar.core.log import log
from solar.core.transports.base import find_named_transport
from solar.utils import execute
class AnsiblePlaybookLocal(AnsiblePlaybookBase):
def _make_inventory(self, resource):
ssh_transport = find_named_transport(resource, 'ssh')
ssh_key = ssh_transport.get('key')
ssh_password = ssh_transport.get('password')
if ssh_key:
inventory = '{0} ansible_ssh_host={1} ansible_connection=ssh \
ansible_ssh_user={2} ansible_ssh_private_key_file={3}'
ssh_auth_data = ssh_key
elif ssh_password:
inventory = '{0} ansible_ssh_host={1} \
ansible_ssh_user={2} ansible_ssh_pass={3}'
ssh_auth_data = ssh_password
else:
raise Exception("No key and no password given")
user = ssh_transport['user']
host = resource.ip()
return inventory.format(host, host, user, ssh_auth_data)
def action(self, resource, action):
# This would require to put this file to remote and execute it (mostly)
ssh_props = find_named_transport(resource, 'ssh')
remote_user = ssh_props['user']
private_key_file = ssh_props.get('key')
ssh_password = ssh_props.get('password')
action_file = os.path.join(
resource.db_obj.actions_path,
resource.actions[action])
files = self._make_playbook(resource,
action,
action_file)
playbook_file, inventory_file, extra_vars_file = files
variables = resource.args
if 'roles' in variables:
self.download_roles(variables['roles'])
host = resource.ip()
transport = C.DEFAULT_TRANSPORT
ansible_library_path = self._copy_ansible_library(resource)
call_args = self.make_ansible_command(playbook_file,
inventory_file,
extra_vars_file,
ansible_library_path)
C.HOST_KEY_CHECKING = False
log.debug('EXECUTING: %s', ' '.join(call_args))
stats = callbacks.AggregateStats()
playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
runner_cb = callbacks.PlaybookRunnerCallbacks(
stats, verbose=utils.VERBOSITY)
opts = dict(
playbook=action_file,
remote_user=remote_user,
host_list=[host],
extra_vars=variables,
callbacks=playbook_cb,
runner_callbacks=runner_cb,
stats=stats,
transport=transport)
if ssh_password:
opts['remote_pass'] = ssh_password
elif private_key_file:
opts['private_key_file'] = private_key_file
ret, out, err = execute(call_args)
if ret == 0:
return
else:
raise Exception("No key and no password given")
play = PlayBook(**opts)
play.run()
summary = stats.summarize(host)
if summary.get('unreachable') or summary.get('failures'):
raise errors.SolarError(
'Ansible playbook %s failed with next summary %s',
action_file, summary)
raise errors.SolarError(out)

View File

@ -57,9 +57,13 @@ class AnsibleTemplateLocal(AnsibleTemplateBase):
log.debug('inventory_file: %s', inventory_file)
log.debug('playbook_file: %s', playbook_file)
lib_path = self.get_library_path()
call_args = ['ansible-playbook', '--module-path', lib_path,
'-i', inventory_file, playbook_file]
lib_path = self._copy_ansible_library(resource)
if lib_path:
call_args = ['ansible-playbook', '--module-path', lib_path,
'-i', inventory_file, playbook_file]
else:
call_args = ['ansible-playbook', '-i', inventory_file,
playbook_file]
log.debug('EXECUTING: %s', ' '.join(call_args))
ret, out, err = execute(call_args)