Commit d05c61d1 by James Cammarata

Merge branch 'devel' into fireball2

Conflicts:
	lib/ansible/playbook/__init__.py
	lib/ansible/playbook/play.py
parents d69d5c29 50f54f6b
...@@ -568,10 +568,10 @@ Role dependencies can also be specified as a full path, just like top level role ...@@ -568,10 +568,10 @@ Role dependencies can also be specified as a full path, just like top level role
dependencies: dependencies:
- { role: '/path/to/common/roles/foo', x: 1 } - { role: '/path/to/common/roles/foo', x: 1 }
Roles dependencies are always executed before the role that includes them, and are recursive. Roles dependencies are always executed before the role that includes them, and are recursive. By default,
roles can also only be added as a dependency once - if another role also lists it as a dependency it will
Role dependencies may be included more than once. Continuing the above example, the 'car' role could not be run again. This behavior can be overridden by adding `allow_duplicates: yes` to the `meta/main.yml` file.
add 'wheel' dependencies as follows:: For example, a role named 'car' could add a role named 'wheel' to its dependencies as follows::
--- ---
dependencies: dependencies:
...@@ -580,7 +580,15 @@ add 'wheel' dependencies as follows:: ...@@ -580,7 +580,15 @@ add 'wheel' dependencies as follows::
- { role: wheel, n: 3 } - { role: wheel, n: 3 }
- { role: wheel, n: 4 } - { role: wheel, n: 4 }
If the wheel role required tire and brake in turn, this would result in the following execution order:: And the `meta/main.yml` for wheel contained the following::
---
allow_duplicates: yes
dependencies:
- { role: tire }
- { role: brake }
The resulting order of execution would be as follows::
tire(n=1) tire(n=1)
brake(n=1) brake(n=1)
......
...@@ -285,7 +285,7 @@ Example:: ...@@ -285,7 +285,7 @@ Example::
As of Ansible 1.2, you can also pass in extra vars as quoted JSON, like so:: As of Ansible 1.2, you can also pass in extra vars as quoted JSON, like so::
--extra-vars "{'pacman':'mrs','ghosts':['inky','pinky','clyde','sue']}" --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
The key=value form is obviously simpler, but it's there if you need it! The key=value form is obviously simpler, but it's there if you need it!
......
...@@ -307,7 +307,7 @@ class PlayBook(object): ...@@ -307,7 +307,7 @@ class PlayBook(object):
remote_pass=self.remote_pass, module_path=self.module_path, remote_pass=self.remote_pass, module_path=self.module_path,
timeout=self.timeout, remote_user=task.play.remote_user, timeout=self.timeout, remote_user=task.play.remote_user,
remote_port=task.play.remote_port, module_vars=task.module_vars, remote_port=task.play.remote_port, module_vars=task.module_vars,
private_key_file=self.private_key_file, default_vars=task.default_vars, private_key_file=self.private_key_file,
setup_cache=self.SETUP_CACHE, basedir=task.play.basedir, setup_cache=self.SETUP_CACHE, basedir=task.play.basedir,
conditional=task.only_if, callbacks=self.runner_callbacks, conditional=task.only_if, callbacks=self.runner_callbacks,
sudo=task.sudo, sudo_user=task.sudo_user, sudo=task.sudo, sudo_user=task.sudo_user,
...@@ -448,7 +448,8 @@ class PlayBook(object): ...@@ -448,7 +448,8 @@ class PlayBook(object):
remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file, remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file,
setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user, setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user,
transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True, module_vars=play.vars, transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True, module_vars=play.vars,
check=self.check, diff=self.diff, accelerate=play.accelerate, accelerate_port=play.accelerate_port default_vars=play.default_vars, check=self.check, diff=self.diff,
accelerate=play.accelerate, accelerate_port=play.accelerate_port
).run() ).run()
self.stats.compute(setup_results, setup=True) self.stats.compute(setup_results, setup=True)
......
...@@ -24,7 +24,7 @@ class Task(object): ...@@ -24,7 +24,7 @@ class Task(object):
__slots__ = [ __slots__ = [
'name', 'meta', 'action', 'only_if', 'when', 'async_seconds', 'async_poll_interval', 'name', 'meta', 'action', 'only_if', 'when', 'async_seconds', 'async_poll_interval',
'notify', 'module_name', 'module_args', 'module_vars', 'notify', 'module_name', 'module_args', 'module_vars', 'default_vars',
'play', 'notified_by', 'tags', 'register', 'play', 'notified_by', 'tags', 'register',
'delegate_to', 'first_available_file', 'ignore_errors', 'delegate_to', 'first_available_file', 'ignore_errors',
'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass', 'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass',
...@@ -41,7 +41,7 @@ class Task(object): ...@@ -41,7 +41,7 @@ class Task(object):
'any_errors_fatal', 'changed_when', 'always_run' 'any_errors_fatal', 'changed_when', 'always_run'
] ]
def __init__(self, play, ds, module_vars=None, additional_conditions=None): def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None):
''' constructor loads from a task or handler datastructure ''' ''' constructor loads from a task or handler datastructure '''
# meta directives are used to tell things like ansible/playbook to run # meta directives are used to tell things like ansible/playbook to run
...@@ -100,8 +100,9 @@ class Task(object): ...@@ -100,8 +100,9 @@ class Task(object):
elif not x in Task.VALID_KEYS: elif not x in Task.VALID_KEYS:
raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x) raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)
self.module_vars = module_vars self.module_vars = module_vars
self.play = play self.default_vars = default_vars
self.play = play
# load various attributes # load various attributes
self.name = ds.get('name', None) self.name = ds.get('name', None)
......
...@@ -55,7 +55,6 @@ multiprocessing_runner = None ...@@ -55,7 +55,6 @@ multiprocessing_runner = None
OUTPUT_LOCKFILE = tempfile.TemporaryFile() OUTPUT_LOCKFILE = tempfile.TemporaryFile()
PROCESS_LOCKFILE = tempfile.TemporaryFile() PROCESS_LOCKFILE = tempfile.TemporaryFile()
MULTIPROCESSING_MANAGER = multiprocessing.Manager()
################################################ ################################################
...@@ -131,6 +130,7 @@ class Runner(object): ...@@ -131,6 +130,7 @@ class Runner(object):
sudo=False, # whether to run sudo or not sudo=False, # whether to run sudo or not
sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root' sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root'
module_vars=None, # a playbooks internals thing module_vars=None, # a playbooks internals thing
default_vars=None, # ditto
is_playbook=False, # running from playbook or not? is_playbook=False, # running from playbook or not?
inventory=None, # reference to Inventory object inventory=None, # reference to Inventory object
subset=None, # subset pattern subset=None, # subset pattern
...@@ -161,6 +161,7 @@ class Runner(object): ...@@ -161,6 +161,7 @@ class Runner(object):
self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list)) self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list))
self.module_vars = utils.default(module_vars, lambda: {}) self.module_vars = utils.default(module_vars, lambda: {})
self.default_vars = utils.default(default_vars, lambda: {})
self.always_run = None self.always_run = None
self.connector = connection.Connection(self) self.connector = connection.Connection(self)
self.conditional = conditional self.conditional = conditional
...@@ -415,6 +416,7 @@ class Runner(object): ...@@ -415,6 +416,7 @@ class Runner(object):
port = self.remote_port port = self.remote_port
inject = {} inject = {}
inject = utils.combine_vars(inject, self.default_vars)
inject = utils.combine_vars(inject, host_variables) inject = utils.combine_vars(inject, host_variables)
inject = utils.combine_vars(inject, self.module_vars) inject = utils.combine_vars(inject, self.module_vars)
inject = utils.combine_vars(inject, self.setup_cache[host]) inject = utils.combine_vars(inject, self.setup_cache[host])
...@@ -423,6 +425,7 @@ class Runner(object): ...@@ -423,6 +425,7 @@ class Runner(object):
inject['group_names'] = host_variables.get('group_names', []) inject['group_names'] = host_variables.get('group_names', [])
inject['groups'] = self.inventory.groups_list() inject['groups'] = self.inventory.groups_list()
inject['vars'] = self.module_vars inject['vars'] = self.module_vars
inject['defaults'] = self.default_vars
inject['environment'] = self.environment inject['environment'] = self.environment
if self.inventory.basedir() is not None: if self.inventory.basedir() is not None:
...@@ -845,7 +848,7 @@ class Runner(object): ...@@ -845,7 +848,7 @@ class Runner(object):
def _parallel_exec(self, hosts): def _parallel_exec(self, hosts):
''' handles mulitprocessing when more than 1 fork is required ''' ''' handles mulitprocessing when more than 1 fork is required '''
manager = MULTIPROCESSING_MANAGER manager = multiprocessing.Manager()
job_queue = manager.Queue() job_queue = manager.Queue()
for host in hosts: for host in hosts:
job_queue.put(host) job_queue.put(host)
......
...@@ -73,7 +73,7 @@ class ActionModule(object): ...@@ -73,7 +73,7 @@ class ActionModule(object):
# use slurp if sudo and permissions are lacking # use slurp if sudo and permissions are lacking
remote_data = None remote_data = None
if remote_md5 in ('1', '2') and self.runner.sudo: if remote_md5 in ('1', '2') or self.runner.sudo:
slurpres = self.runner._execute_module(conn, tmp, 'slurp', 'src=%s' % source, inject=inject) slurpres = self.runner._execute_module(conn, tmp, 'slurp', 'src=%s' % source, inject=inject)
if slurpres.is_successful(): if slurpres.is_successful():
if slurpres.result['encoding'] == 'base64': if slurpres.result['encoding'] == 'base64':
......
...@@ -44,6 +44,11 @@ options: ...@@ -44,6 +44,11 @@ options:
- The tenant name of the login user - The tenant name of the login user
required: true required: true
default: 'yes' default: 'yes'
tenant_name:
description:
- The name of the tenant for whom the network is created
required: false
default: None
auth_url: auth_url:
description: description:
- The keystone url for authentication - The keystone url for authentication
...@@ -99,15 +104,15 @@ requirements: ["quantumclient", "keystoneclient"] ...@@ -99,15 +104,15 @@ requirements: ["quantumclient", "keystoneclient"]
''' '''
EXAMPLES = ''' EXAMPLES = '''
# Creates an external,public network # Create a GRE backed Quantum network with tunnel id 1 for tenant1
- quantum_network: state=present login_username=admin login_password=admin - quantum_network: name=t1network tenant_name=tenant1 state=present
provider_network_type=gre login_tenant_name=admin provider_network_type=gre provider_segmentation_id=1
provider_segmentation_id=1 tenant_name=tenant1 name=t1network" login_username=admin login_password=admin login_tenant_name=admin
# Createss a GRE nework with tunnel id of 1 for tenant 1 # Create an external network
- quantum_network: state=present login_username=admin login_password=admin - quantum_network: name=external_network state=present
provider_network_type=local login_tenant_name=admin provider_network_type=local router_external=yes
provider_segmentation_id=1 router_external=yes name=external_network login_username=admin login_password=admin login_tenant_name=admin
''' '''
_os_keystone = None _os_keystone = None
...@@ -130,7 +135,7 @@ def _get_endpoint(module, ksclient): ...@@ -130,7 +135,7 @@ def _get_endpoint(module, ksclient):
try: try:
endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
except Exception as e: except Exception as e:
module.fail_json(msg = "Error getting endpoint for glance: %s " %e.message) module.fail_json(msg = "Error getting endpoint for Quantum: %s " %e.message)
return endpoint return endpoint
def _get_quantum_client(module, kwargs): def _get_quantum_client(module, kwargs):
......
...@@ -1273,20 +1273,24 @@ class AIX(User): ...@@ -1273,20 +1273,24 @@ class AIX(User):
if self.groups is not None: if self.groups is not None:
current_groups = self.user_group_membership() current_groups = self.user_group_membership()
groups = self.get_groups_set()
group_diff = set(current_groups).symmetric_difference(groups)
groups_need_mod = False groups_need_mod = False
groups = []
if group_diff: if self.groups == '':
if self.append: if current_groups and not self.append:
for g in groups:
if g in group_diff:
groups.extend(current_groups)
set(groups)
groups_need_mod = True
break
else:
groups_need_mod = True groups_need_mod = True
else:
groups = self.get_groups_set()
group_diff = set(current_groups).symmetric_difference(groups)
if group_diff:
if self.append:
for g in groups:
if g in group_diff:
groups_need_mod = True
break
else:
groups_need_mod = True
if groups_need_mod: if groups_need_mod:
cmd.append('-G') cmd.append('-G')
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
# in AWS and merge the results together. Alternatively, set this to a comma # in AWS and merge the results together. Alternatively, set this to a comma
# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2' # separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
regions = all regions = all
regions_exclude = us-gov-west-1
# When generating inventory, Ansible needs to know how to address a server. # When generating inventory, Ansible needs to know how to address a server.
# Each EC2 instance has a lot of variables associated with it. Here is the list: # Each EC2 instance has a lot of variables associated with it. Here is the list:
......
...@@ -189,12 +189,14 @@ class Ec2Inventory(object): ...@@ -189,12 +189,14 @@ class Ec2Inventory(object):
# Regions # Regions
self.regions = [] self.regions = []
configRegions = config.get('ec2', 'regions') configRegions = config.get('ec2', 'regions')
configRegions_exclude = config.get('ec2', 'regions_exclude')
if (configRegions == 'all'): if (configRegions == 'all'):
if self.eucalyptus_host: if self.eucalyptus_host:
self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name) self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
else: else:
for regionInfo in ec2.regions(): for regionInfo in ec2.regions():
self.regions.append(regionInfo.name) if regionInfo.name not in configRegions_exclude:
self.regions.append(regionInfo.name)
else: else:
self.regions = configRegions.split(",") self.regions = configRegions.split(",")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment