Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
dfbe591c
Commit
dfbe591c
authored
Mar 20, 2012
by
Michael DeHaan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add "only_if" capability, which allows task steps to be skipped if they do not match a conditional.
parent
149cc57b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
42 additions
and
13 deletions
+42
-13
lib/ansible/playbook.py
+32
-12
lib/ansible/runner.py
+8
-0
test/playbook1.events
+2
-1
No files found.
lib/ansible/playbook.py
View file @
dfbe591c
...
@@ -77,6 +77,7 @@ class PlayBook(object):
...
@@ -77,6 +77,7 @@ class PlayBook(object):
self
.
changed
=
{}
self
.
changed
=
{}
self
.
invocations
=
{}
self
.
invocations
=
{}
self
.
failures
=
{}
self
.
failures
=
{}
self
.
skipped
=
{}
# playbook file can be passed in as a path or
# playbook file can be passed in as a path or
# as file contents (to support API usage)
# as file contents (to support API usage)
...
@@ -158,8 +159,13 @@ class PlayBook(object):
...
@@ -158,8 +159,13 @@ class PlayBook(object):
'resources'
:
self
.
invocations
.
get
(
host
,
0
),
'resources'
:
self
.
invocations
.
get
(
host
,
0
),
'changed'
:
self
.
changed
.
get
(
host
,
0
),
'changed'
:
self
.
changed
.
get
(
host
,
0
),
'dark'
:
self
.
dark
.
get
(
host
,
0
),
'dark'
:
self
.
dark
.
get
(
host
,
0
),
'failed'
:
self
.
failures
.
get
(
host
,
0
)
'failed'
:
self
.
failures
.
get
(
host
,
0
),
'skipped'
:
self
.
skipped
.
get
(
host
,
0
)
}
}
# FIXME: TODO: use callback to reinstate per-host summary
# and add corresponding code in /bin/ansible-playbook
# print results
return
results
return
results
def
_prune_failed_hosts
(
self
,
host_list
):
def
_prune_failed_hosts
(
self
,
host_list
):
...
@@ -175,12 +181,12 @@ class PlayBook(object):
...
@@ -175,12 +181,12 @@ class PlayBook(object):
for
(
host
,
res
)
in
results
[
'contacted'
]
.
iteritems
():
for
(
host
,
res
)
in
results
[
'contacted'
]
.
iteritems
():
# FIXME: make polling pattern in /bin/ansible match
# FIXME: make polling pattern in /bin/ansible match
# move to common function in utils
# move to common function in utils
if
not
'finished'
in
res
and
'started'
in
res
:
if
not
'finished'
in
res
and
not
'skipped'
in
res
and
'started'
in
res
:
hosts
.
append
(
host
)
hosts
.
append
(
host
)
return
hosts
return
hosts
def
_async_poll
(
self
,
runner
,
async_seconds
,
async_poll_interval
):
def
_async_poll
(
self
,
runner
,
async_seconds
,
async_poll_interval
,
only_if
):
''' launch an async job, if poll_interval is set, wait for completion '''
''' launch an async job, if poll_interval is set, wait for completion '''
# TODO: refactor this function
# TODO: refactor this function
...
@@ -197,6 +203,8 @@ class PlayBook(object):
...
@@ -197,6 +203,8 @@ class PlayBook(object):
if
'failed'
in
host_result
:
if
'failed'
in
host_result
:
self
.
callbacks
.
on_failed
(
host
,
host_result
)
self
.
callbacks
.
on_failed
(
host
,
host_result
)
self
.
failures
[
host
]
=
1
self
.
failures
[
host
]
=
1
if
'skipped'
in
host_result
:
self
.
skipped
[
host
]
=
self
.
skipped
.
get
(
host
,
0
)
+
1
if
async_poll_interval
<=
0
:
if
async_poll_interval
<=
0
:
# if not polling, playbook requested fire and forget
# if not polling, playbook requested fire and forget
...
@@ -248,6 +256,11 @@ class PlayBook(object):
...
@@ -248,6 +256,11 @@ class PlayBook(object):
if
'failed'
in
host_result
:
if
'failed'
in
host_result
:
self
.
callbacks
.
on_failed
(
host
,
host_result
)
self
.
callbacks
.
on_failed
(
host
,
host_result
)
self
.
failures
[
host
]
=
1
self
.
failures
[
host
]
=
1
if
'skipped'
in
host_result
:
# NOTE: callbacks on skipped? should not really
# happen at this point in the loop
self
.
skipped
[
host
]
=
self
.
skipped
.
get
(
host
,
0
)
+
1
for
(
host
,
host_result
)
in
poll_results
[
'contacted'
]
.
iteritems
():
for
(
host
,
host_result
)
in
poll_results
[
'contacted'
]
.
iteritems
():
results
[
'contacted'
][
host
]
=
host_result
results
[
'contacted'
][
host
]
=
host_result
...
@@ -267,7 +280,7 @@ class PlayBook(object):
...
@@ -267,7 +280,7 @@ class PlayBook(object):
return
results
return
results
def
_run_module
(
self
,
pattern
,
module
,
args
,
hosts
,
remote_user
,
def
_run_module
(
self
,
pattern
,
module
,
args
,
hosts
,
remote_user
,
async_seconds
,
async_poll_interval
):
async_seconds
,
async_poll_interval
,
only_if
):
''' run a particular module step in a playbook '''
''' run a particular module step in a playbook '''
runner
=
ansible
.
runner
.
Runner
(
runner
=
ansible
.
runner
.
Runner
(
...
@@ -281,13 +294,14 @@ class PlayBook(object):
...
@@ -281,13 +294,14 @@ class PlayBook(object):
timeout
=
self
.
timeout
,
timeout
=
self
.
timeout
,
remote_user
=
remote_user
,
remote_user
=
remote_user
,
setup_cache
=
SETUP_CACHE
,
setup_cache
=
SETUP_CACHE
,
basedir
=
self
.
basedir
basedir
=
self
.
basedir
,
conditionally_execute_if
=
only_if
)
)
if
async_seconds
==
0
:
if
async_seconds
==
0
:
rc
=
runner
.
run
()
rc
=
runner
.
run
()
else
:
else
:
rc
=
self
.
_async_poll
(
runner
,
async_seconds
,
async_poll_interval
)
rc
=
self
.
_async_poll
(
runner
,
async_seconds
,
async_poll_interval
,
only_if
)
dark_hosts
=
rc
.
get
(
'dark'
,{})
dark_hosts
=
rc
.
get
(
'dark'
,{})
for
(
host
,
error
)
in
dark_hosts
.
iteritems
():
for
(
host
,
error
)
in
dark_hosts
.
iteritems
():
...
@@ -314,13 +328,12 @@ class PlayBook(object):
...
@@ -314,13 +328,12 @@ class PlayBook(object):
host_list
=
self
.
_prune_failed_hosts
(
host_list
)
host_list
=
self
.
_prune_failed_hosts
(
host_list
)
# load the module name and parameters from the task entry
# load the module name and parameters from the task entry
name
=
task
[
'name'
]
name
=
task
[
'name'
]
# FIXME: error if not set
action
=
task
[
'action'
]
action
=
task
[
'action'
]
# FIXME: error if not set
only_if
=
task
.
get
(
'only_if'
,
'True'
)
async_seconds
=
int
(
task
.
get
(
'async'
,
0
))
# not async by default
async_seconds
=
int
(
task
.
get
(
'async'
,
0
))
# not async by default
async_poll_interval
=
int
(
task
.
get
(
'poll'
,
10
))
# default poll = 10 seconds
async_poll_interval
=
int
(
task
.
get
(
'poll'
,
10
))
# default poll = 10 seconds
# comment = task.get('comment', '')
tokens
=
shlex
.
split
(
action
)
tokens
=
shlex
.
split
(
action
)
module_name
=
tokens
[
0
]
module_name
=
tokens
[
0
]
module_args
=
tokens
[
1
:]
module_args
=
tokens
[
1
:]
...
@@ -336,7 +349,7 @@ class PlayBook(object):
...
@@ -336,7 +349,7 @@ class PlayBook(object):
# run the task in parallel
# run the task in parallel
results
=
self
.
_run_module
(
pattern
,
module_name
,
results
=
self
.
_run_module
(
pattern
,
module_name
,
module_args
,
host_list
,
remote_user
,
module_args
,
host_list
,
remote_user
,
async_seconds
,
async_poll_interval
)
async_seconds
,
async_poll_interval
,
only_if
)
# if no hosts are matched, carry on, unlike /bin/ansible
# if no hosts are matched, carry on, unlike /bin/ansible
# which would warn you about this
# which would warn you about this
...
@@ -357,7 +370,8 @@ class PlayBook(object):
...
@@ -357,7 +370,8 @@ class PlayBook(object):
self
.
dark
[
host
]
=
1
self
.
dark
[
host
]
=
1
else
:
else
:
self
.
dark
[
host
]
=
self
.
dark
[
host
]
+
1
self
.
dark
[
host
]
=
self
.
dark
[
host
]
+
1
# FIXME: refactor
for
host
,
results
in
contacted
.
iteritems
():
for
host
,
results
in
contacted
.
iteritems
():
self
.
processed
[
host
]
=
1
self
.
processed
[
host
]
=
1
...
@@ -378,6 +392,12 @@ class PlayBook(object):
...
@@ -378,6 +392,12 @@ class PlayBook(object):
self
.
changed
[
host
]
=
1
self
.
changed
[
host
]
=
1
else
:
else
:
self
.
changed
[
host
]
=
self
.
changed
[
host
]
+
1
self
.
changed
[
host
]
=
self
.
changed
[
host
]
+
1
# TODO: verify/test that async steps are skippable
if
results
.
get
(
'skipped'
,
False
):
if
not
host
in
self
.
changed
:
self
.
skipped
[
host
]
=
1
else
:
self
.
skipped
[
host
]
=
self
.
skipped
[
host
]
+
1
# flag which notify handlers need to be run
# flag which notify handlers need to be run
# this will be on a SUBSET of the actual host list. For instance
# this will be on a SUBSET of the actual host list. For instance
...
...
lib/ansible/runner.py
View file @
dfbe591c
...
@@ -76,6 +76,7 @@ class Runner(object):
...
@@ -76,6 +76,7 @@ class Runner(object):
basedir
=
None
,
basedir
=
None
,
setup_cache
=
None
,
setup_cache
=
None
,
transport
=
'paramiko'
,
transport
=
'paramiko'
,
conditionally_execute_if
=
'True'
,
verbose
=
False
):
verbose
=
False
):
'''
'''
...
@@ -95,6 +96,7 @@ class Runner(object):
...
@@ -95,6 +96,7 @@ class Runner(object):
if
setup_cache
is
None
:
if
setup_cache
is
None
:
setup_cache
=
{}
setup_cache
=
{}
self
.
setup_cache
=
setup_cache
self
.
setup_cache
=
setup_cache
self
.
conditionally_execute_if
=
conditionally_execute_if
self
.
host_list
,
self
.
groups
=
self
.
parse_hosts
(
host_list
)
self
.
host_list
,
self
.
groups
=
self
.
parse_hosts
(
host_list
)
self
.
module_path
=
module_path
self
.
module_path
=
module_path
...
@@ -286,12 +288,18 @@ class Runner(object):
...
@@ -286,12 +288,18 @@ class Runner(object):
modifies the command using setup_cache variables (see playbook)
modifies the command using setup_cache variables (see playbook)
'''
'''
args
=
module_args
args
=
module_args
if
type
(
args
)
==
list
:
if
type
(
args
)
==
list
:
args
=
" "
.
join
([
str
(
x
)
for
x
in
module_args
])
args
=
" "
.
join
([
str
(
x
)
for
x
in
module_args
])
# by default the args to substitute in the action line are those from the setup cache
# by default the args to substitute in the action line are those from the setup cache
inject_vars
=
self
.
setup_cache
.
get
(
conn
.
host
,{})
inject_vars
=
self
.
setup_cache
.
get
(
conn
.
host
,{})
# see if we really need to run this or not...
conditional
=
utils
.
template
(
self
.
conditionally_execute_if
,
inject_vars
)
if
not
eval
(
conditional
):
return
utils
.
smjson
(
dict
(
skipped
=
True
))
# if the host file was an external script, execute it with the hostname
# if the host file was an external script, execute it with the hostname
# as a first parameter to get the variables to use for the host
# as a first parameter to get the variables to use for the host
...
...
test/playbook1.events
View file @
dfbe591c
...
@@ -235,7 +235,8 @@
...
@@ -235,7 +235,8 @@
"changed": 2,
"changed": 2,
"dark": 0,
"dark": 0,
"failed": 0,
"failed": 0,
"resources": 9
"resources": 9,
"skipped": 0
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment