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
157b697a
Commit
157b697a
authored
Aug 22, 2013
by
James Cammarata
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'always_run-6' of
https://github.com/stoned/ansible
into stoned-always_run-6
parents
abac7202
f0743fc3
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
136 additions
and
13 deletions
+136
-13
docsite/latest/rst/playbooks2.rst
+23
-0
lib/ansible/playbook/task.py
+6
-3
lib/ansible/runner/__init__.py
+15
-0
lib/ansible/runner/action_plugins/add_host.py
+1
-1
lib/ansible/runner/action_plugins/async.py
+1
-1
lib/ansible/runner/action_plugins/copy.py
+2
-2
lib/ansible/runner/action_plugins/fetch.py
+1
-1
lib/ansible/runner/action_plugins/normal.py
+1
-1
lib/ansible/runner/action_plugins/raw.py
+1
-1
lib/ansible/runner/action_plugins/script.py
+1
-1
lib/ansible/runner/action_plugins/template.py
+1
-1
lib/ansible/utils/__init__.py
+4
-1
test/TestPlayBook.py
+31
-0
test/playbook-always-run.yml
+48
-0
No files found.
docsite/latest/rst/playbooks2.rst
View file @
157b697a
...
...
@@ -1060,6 +1060,29 @@ Example::
ansible-playbook foo.yml --check
Running a task in check mode
````````````````````````````
.. versionadded:: 1.3
Sometimes you may want to have a task to be executed even in check
mode. To achieve this use the `always_run` clause on the task. Its
value is a Python expression, just like the `when` clause. In simple
cases a boolean YAML value would be sufficient as a value.
Example::
tasks:
- name: this task is run even in check mode
command: /something/to/run --even-in-check-mode
always_run: yes
As a reminder, a task with a `when` clause evaluated to false, will
still be skipped even if it has a `always_run` clause evaluated to
true.
Showing Differences with --diff
```````````````````````````````
...
...
lib/ansible/playbook/task.py
View file @
157b697a
...
...
@@ -29,7 +29,7 @@ class Task(object):
'delegate_to'
,
'first_available_file'
,
'ignore_errors'
,
'local_action'
,
'transport'
,
'sudo'
,
'sudo_user'
,
'sudo_pass'
,
'items_lookup_plugin'
,
'items_lookup_terms'
,
'environment'
,
'args'
,
'any_errors_fatal'
,
'changed_when'
'any_errors_fatal'
,
'changed_when'
,
'always_run'
]
# to prevent typos and such
...
...
@@ -38,7 +38,7 @@ class Task(object):
'first_available_file'
,
'include'
,
'tags'
,
'register'
,
'ignore_errors'
,
'delegate_to'
,
'local_action'
,
'transport'
,
'sudo'
,
'sudo_user'
,
'sudo_pass'
,
'when'
,
'connection'
,
'environment'
,
'args'
,
'any_errors_fatal'
,
'changed_when'
'any_errors_fatal'
,
'changed_when'
,
'always_run'
]
def
__init__
(
self
,
play
,
ds
,
module_vars
=
None
,
additional_conditions
=
None
):
...
...
@@ -178,6 +178,8 @@ class Task(object):
self
.
ignore_errors
=
ds
.
get
(
'ignore_errors'
,
False
)
self
.
any_errors_fatal
=
ds
.
get
(
'any_errors_fatal'
,
play
.
any_errors_fatal
)
self
.
always_run
=
ds
.
get
(
'always_run'
,
False
)
# action should be a string
if
not
isinstance
(
self
.
action
,
basestring
):
raise
errors
.
AnsibleError
(
"action is of type '
%
s' and not a string in task. name:
%
s"
%
(
type
(
self
.
action
)
.
__name__
,
self
.
name
))
...
...
@@ -216,10 +218,11 @@ class Task(object):
# allow runner to see delegate_to option
self
.
module_vars
[
'delegate_to'
]
=
self
.
delegate_to
# make
ignore_errors accessa
ble to Runner code
# make
some task attributes accessi
ble to Runner code
self
.
module_vars
[
'ignore_errors'
]
=
self
.
ignore_errors
self
.
module_vars
[
'register'
]
=
self
.
register
self
.
module_vars
[
'changed_when'
]
=
self
.
changed_when
self
.
module_vars
[
'always_run'
]
=
self
.
always_run
# tags allow certain parts of a playbook to be run without running the whole playbook
apply_tags
=
ds
.
get
(
'tags'
,
None
)
...
...
lib/ansible/runner/__init__.py
View file @
157b697a
...
...
@@ -37,6 +37,7 @@ import ansible.constants as C
import
ansible.inventory
from
ansible
import
utils
from
ansible.utils
import
template
from
ansible.utils
import
check_conditional
from
ansible
import
errors
from
ansible
import
module_common
import
poller
...
...
@@ -156,6 +157,7 @@ class Runner(object):
self
.
inventory
=
utils
.
default
(
inventory
,
lambda
:
ansible
.
inventory
.
Inventory
(
host_list
))
self
.
module_vars
=
utils
.
default
(
module_vars
,
lambda
:
{})
self
.
always_run
=
None
self
.
connector
=
connection
.
Connection
(
self
)
self
.
conditional
=
conditional
self
.
module_name
=
module_name
...
...
@@ -941,3 +943,16 @@ class Runner(object):
self
.
background
=
time_limit
results
=
self
.
run
()
return
results
,
poller
.
AsyncPoller
(
results
,
self
)
# *****************************************************
def
noop_on_check
(
self
,
inject
):
''' Should the runner run in check mode or not ? '''
# initialize self.always_run on first call
if
self
.
always_run
is
None
:
self
.
always_run
=
self
.
module_vars
.
get
(
'always_run'
,
False
)
self
.
always_run
=
check_conditional
(
self
.
always_run
,
self
.
basedir
,
inject
,
fail_on_undefined
=
True
,
jinja2
=
True
)
return
(
self
.
check
and
not
self
.
always_run
)
lib/ansible/runner/action_plugins/add_host.py
View file @
157b697a
...
...
@@ -36,7 +36,7 @@ class ActionModule(object):
def
run
(
self
,
conn
,
tmp
,
module_name
,
module_args
,
inject
,
complex_args
=
None
,
**
kwargs
):
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
,
msg
=
'check mode not supported for this module'
))
args
=
{}
...
...
lib/ansible/runner/action_plugins/async.py
View file @
157b697a
...
...
@@ -25,7 +25,7 @@ class ActionModule(object):
def
run
(
self
,
conn
,
tmp
,
module_name
,
module_args
,
inject
,
complex_args
=
None
,
**
kwargs
):
''' transfer the given module name, plus the async module, then run it '''
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
,
msg
=
'check mode not supported for this module'
))
# shell and command module are the same
...
...
lib/ansible/runner/action_plugins/copy.py
View file @
157b697a
...
...
@@ -126,7 +126,7 @@ class ActionModule(object):
else
:
diff
=
{}
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
if
content
is
not
None
:
os
.
remove
(
tmp_content
)
return
ReturnData
(
conn
=
conn
,
result
=
dict
(
changed
=
True
),
diff
=
diff
)
...
...
@@ -172,7 +172,7 @@ class ActionModule(object):
# don't send down raw=no
module_args
.
pop
(
'raw'
)
module_args
=
"
%
s src=
%
s"
%
(
module_args
,
pipes
.
quote
(
tmp_src
))
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
module_args
=
"
%
s CHECKMODE=True"
%
module_args
return
self
.
runner
.
_execute_module
(
conn
,
tmp
,
'file'
,
module_args
,
inject
=
inject
,
complex_args
=
complex_args
)
...
...
lib/ansible/runner/action_plugins/fetch.py
View file @
157b697a
...
...
@@ -36,7 +36,7 @@ class ActionModule(object):
def
run
(
self
,
conn
,
tmp
,
module_name
,
module_args
,
inject
,
complex_args
=
None
,
**
kwargs
):
''' handler for fetch operations '''
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
,
msg
=
'check mode not (yet) supported for this module'
))
# load up options
...
...
lib/ansible/runner/action_plugins/normal.py
View file @
157b697a
...
...
@@ -38,7 +38,7 @@ class ActionModule(object):
module_args
=
self
.
runner
.
_complex_args_hack
(
complex_args
,
module_args
)
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
if
module_name
in
[
'shell'
,
'command'
]:
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
,
msg
=
'check mode not supported for
%
s'
%
module_name
))
# else let the module parsing code decide, though this will only be allowed for AnsibleModuleCommon using
...
...
lib/ansible/runner/action_plugins/raw.py
View file @
157b697a
...
...
@@ -30,7 +30,7 @@ class ActionModule(object):
def
run
(
self
,
conn
,
tmp
,
module_name
,
module_args
,
inject
,
complex_args
=
None
,
**
kwargs
):
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
# in --check mode, always skip this module execution
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
))
...
...
lib/ansible/runner/action_plugins/script.py
View file @
157b697a
...
...
@@ -32,7 +32,7 @@ class ActionModule(object):
def
run
(
self
,
conn
,
tmp
,
module_name
,
module_args
,
inject
,
complex_args
=
None
,
**
kwargs
):
''' handler for file transfer operations '''
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
# in check mode, always skip this module
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
skipped
=
True
,
msg
=
'check mode not supported for this module'
))
...
...
lib/ansible/runner/action_plugins/template.py
View file @
157b697a
...
...
@@ -117,7 +117,7 @@ class ActionModule(object):
# run the copy module
module_args
=
"
%
s src=
%
s dest=
%
s original_basename=
%
s"
%
(
module_args
,
pipes
.
quote
(
xfered
),
pipes
.
quote
(
dest
),
pipes
.
quote
(
os
.
path
.
basename
(
source
)))
if
self
.
runner
.
check
:
if
self
.
runner
.
noop_on_check
(
inject
)
:
return
ReturnData
(
conn
=
conn
,
comm_ok
=
True
,
result
=
dict
(
changed
=
True
),
diff
=
dict
(
before_header
=
dest
,
after_header
=
source
,
before
=
dest_contents
,
after
=
resultant
))
else
:
res
=
self
.
runner
.
_execute_module
(
conn
,
tmp
,
'copy'
,
module_args
,
inject
=
inject
,
complex_args
=
complex_args
)
...
...
lib/ansible/utils/__init__.py
View file @
157b697a
...
...
@@ -155,7 +155,10 @@ def is_changed(result):
return
(
result
.
get
(
'changed'
,
False
)
in
[
True
,
'True'
,
'true'
])
def
check_conditional
(
conditional
,
basedir
,
inject
,
fail_on_undefined
=
False
):
def
check_conditional
(
conditional
,
basedir
,
inject
,
fail_on_undefined
=
False
,
jinja2
=
False
):
if
jinja2
:
conditional
=
"jinja2_compare
%
s"
%
conditional
if
conditional
.
startswith
(
"jinja2_compare"
):
conditional
=
conditional
.
replace
(
"jinja2_compare "
,
""
)
...
...
test/TestPlayBook.py
View file @
157b697a
...
...
@@ -474,6 +474,37 @@ class TestPlaybook(unittest.TestCase):
assert
utils
.
jsonify
(
expected
,
format
=
True
)
==
utils
.
jsonify
(
actual
,
format
=
True
)
def
test_playbook_always_run
(
self
):
test_callbacks
=
TestCallbacks
()
playbook
=
ansible
.
playbook
.
PlayBook
(
playbook
=
os
.
path
.
join
(
self
.
test_dir
,
'playbook-always-run.yml'
),
host_list
=
'test/ansible_hosts'
,
stats
=
ans_callbacks
.
AggregateStats
(),
callbacks
=
test_callbacks
,
runner_callbacks
=
test_callbacks
,
check
=
True
)
actual
=
playbook
.
run
()
# if different, this will output to screen
print
"**ACTUAL**"
print
utils
.
jsonify
(
actual
,
format
=
True
)
expected
=
{
"localhost"
:
{
"changed"
:
4
,
"failures"
:
0
,
"ok"
:
4
,
"skipped"
:
8
,
"unreachable"
:
0
}
}
print
"**EXPECTED**"
print
utils
.
jsonify
(
expected
,
format
=
True
)
assert
utils
.
jsonify
(
expected
,
format
=
True
)
==
utils
.
jsonify
(
actual
,
format
=
True
)
def
_compare_file_output
(
self
,
filename
,
expected_lines
):
actual_lines
=
[]
with
open
(
filename
)
as
f
:
...
...
test/playbook-always-run.yml
0 → 100644
View file @
157b697a
---
-
hosts
:
all
connection
:
local
gather_facts
:
False
vars
:
var_true
:
True
var_false
:
False
var_empty_str
:
"
''"
var_null
:
~
tasks
:
-
action
:
command echo ping
always_run
:
yes
-
action
:
command echo pong 1
-
action
:
command echo pong 2
always_run
:
no
-
action
:
command echo pong 3
always_run
:
1 + 1
-
action
:
command echo pong 4
always_run
:
"
''"
-
action
:
command echo pong 5
always_run
:
False
-
action
:
command echo pong 6
always_run
:
True
-
action
:
command echo pong 7
always_run
:
var_true
-
action
:
command echo pong 8
always_run
:
var_false
-
action
:
command echo pong 9
always_run
:
var_empty_str
-
action
:
command echo pong 10
always_run
:
var_null
# this will never run...
-
action
:
command echo pong 11
always_run
:
yes
when
:
no
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