Ansible 2.0 support in ansible handlers
All ansible handlers are now using ansible process instead of python API Change-Id: I14c06830e52610b41a1c5776a6d6cb8af1651478 Closes-bug: #1534145
This commit is contained in:
parent
75858724e4
commit
038c46c3e7
2
bootstrap/playbooks/files/ubuntu-ansible.sh
Normal file → Executable file
2
bootstrap/playbooks/files/ubuntu-ansible.sh
Normal file → Executable 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"
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user