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
da136dbe
Commit
da136dbe
authored
Jan 21, 2014
by
jctanner
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5694 from angstwad/add-su-support-revert
Add su support
parents
07b6d6ff
f72f5a20
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
313 additions
and
100 deletions
+313
-100
bin/ansible
+32
-9
bin/ansible-playbook
+16
-2
lib/ansible/constants.py
+6
-0
lib/ansible/playbook/__init__.py
+64
-21
lib/ansible/playbook/play.py
+15
-5
lib/ansible/playbook/task.py
+14
-6
lib/ansible/runner/__init__.py
+46
-14
lib/ansible/runner/connection_plugins/accelerate.py
+4
-1
lib/ansible/runner/connection_plugins/chroot.py
+4
-1
lib/ansible/runner/connection_plugins/fireball.py
+3
-3
lib/ansible/runner/connection_plugins/funcd.py
+5
-2
lib/ansible/runner/connection_plugins/jail.py
+4
-1
lib/ansible/runner/connection_plugins/local.py
+5
-1
lib/ansible/runner/connection_plugins/paramiko_alt.py
+7
-4
lib/ansible/runner/connection_plugins/paramiko_ssh.py
+11
-5
lib/ansible/runner/connection_plugins/ssh.py
+23
-10
lib/ansible/runner/connection_plugins/ssh_old.py
+22
-9
lib/ansible/utils/__init__.py
+32
-6
No files found.
bin/ansible
View file @
da136dbe
...
@@ -67,6 +67,14 @@ class Cli(object):
...
@@ -67,6 +67,14 @@ class Cli(object):
if
len
(
args
)
==
0
or
len
(
args
)
>
1
:
if
len
(
args
)
==
0
or
len
(
args
)
>
1
:
parser
.
print_help
()
parser
.
print_help
()
sys
.
exit
(
1
)
sys
.
exit
(
1
)
# su and sudo command line arguments need to be mutually exclusive
if
(
options
.
su
or
options
.
su_user
or
options
.
ask_su_pass
)
and
\
(
options
.
sudo
or
options
.
sudo_user
or
options
.
ask_sudo_pass
):
parser
.
error
(
"Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') "
"and su arguments ('-su', '--su-user', and '--ask-su-pass') are "
"mutually exclusive"
)
return
(
options
,
args
)
return
(
options
,
args
)
# ----------------------------------------------
# ----------------------------------------------
...
@@ -96,31 +104,46 @@ class Cli(object):
...
@@ -96,31 +104,46 @@ class Cli(object):
sshpass
=
None
sshpass
=
None
sudopass
=
None
sudopass
=
None
su_pass
=
None
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
# Never ask for an SSH password when we run with local connection
# Never ask for an SSH password when we run with local connection
if
options
.
connection
==
"local"
:
if
options
.
connection
==
"local"
:
options
.
ask_pass
=
False
options
.
ask_pass
=
False
options
.
ask_sudo_pass
=
options
.
ask_sudo_pass
or
C
.
DEFAULT_ASK_SUDO_PASS
options
.
ask_sudo_pass
=
options
.
ask_sudo_pass
or
C
.
DEFAULT_ASK_SUDO_PASS
(
sshpass
,
sudopass
)
=
utils
.
ask_passwords
(
ask_pass
=
options
.
ask_pass
,
ask_sudo_pass
=
options
.
ask_sudo_pass
)
options
.
ask_su_pass
=
options
.
ask_su_pass
or
C
.
DEFAULT_ASK_SU_PASS
if
options
.
sudo_user
or
options
.
ask_sudo_pass
:
(
sshpass
,
sudopass
,
su_pass
)
=
utils
.
ask_passwords
(
ask_pass
=
options
.
ask_pass
,
ask_sudo_pass
=
options
.
ask_sudo_pass
,
ask_su_pass
=
options
.
ask_su_pass
)
if
options
.
su_user
or
options
.
ask_su_pass
:
options
.
su
=
True
elif
options
.
sudo_user
or
options
.
ask_sudo_pass
:
options
.
sudo
=
True
options
.
sudo
=
True
options
.
sudo_user
=
options
.
sudo_user
or
C
.
DEFAULT_SUDO_USER
options
.
sudo_user
=
options
.
sudo_user
or
C
.
DEFAULT_SUDO_USER
options
.
su_user
=
options
.
su_user
or
C
.
DEFAULT_SU_USER
if
options
.
tree
:
if
options
.
tree
:
utils
.
prepare_writeable_dir
(
options
.
tree
)
utils
.
prepare_writeable_dir
(
options
.
tree
)
runner
=
Runner
(
runner
=
Runner
(
module_name
=
options
.
module_name
,
module_path
=
options
.
module_path
,
module_name
=
options
.
module_name
,
module_path
=
options
.
module_path
,
module_args
=
options
.
module_args
,
module_args
=
options
.
module_args
,
remote_user
=
options
.
remote_user
,
remote_pass
=
sshpass
,
remote_user
=
options
.
remote_user
,
inventory
=
inventory_manager
,
timeout
=
options
.
timeout
,
remote_pass
=
sshpass
,
inventory
=
inventory_manager
,
timeout
=
options
.
timeout
,
private_key_file
=
options
.
private_key_file
,
private_key_file
=
options
.
private_key_file
,
forks
=
options
.
forks
,
forks
=
options
.
forks
,
pattern
=
pattern
,
pattern
=
pattern
,
callbacks
=
self
.
callbacks
,
sudo
=
options
.
sudo
,
callbacks
=
self
.
callbacks
,
sudo_pass
=
sudopass
,
sudo_user
=
options
.
sudo_user
,
sudo
=
options
.
sudo
,
transport
=
options
.
connection
,
subset
=
options
.
subset
,
sudo_pass
=
sudopass
,
sudo_user
=
options
.
sudo_user
,
transport
=
options
.
connection
,
subset
=
options
.
subset
,
check
=
options
.
check
,
check
=
options
.
check
,
diff
=
options
.
check
diff
=
options
.
check
,
su
=
options
.
su
,
su_pass
=
su_pass
,
su_user
=
options
.
su_user
)
)
if
options
.
seconds
:
if
options
.
seconds
:
...
...
bin/ansible-playbook
View file @
da136dbe
...
@@ -83,6 +83,13 @@ def main(args):
...
@@ -83,6 +83,13 @@ def main(args):
parser
.
print_help
(
file
=
sys
.
stderr
)
parser
.
print_help
(
file
=
sys
.
stderr
)
return
1
return
1
# su and sudo command line arguments need to be mutually exclusive
if
(
options
.
su
or
options
.
su_user
or
options
.
ask_su_pass
)
and
\
(
options
.
sudo
or
options
.
sudo_user
or
options
.
ask_sudo_pass
):
parser
.
error
(
"Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') "
"and su arguments ('-su', '--su-user', and '--ask-su-pass') are "
"mutually exclusive"
)
inventory
=
ansible
.
inventory
.
Inventory
(
options
.
inventory
)
inventory
=
ansible
.
inventory
.
Inventory
(
options
.
inventory
)
inventory
.
subset
(
options
.
subset
)
inventory
.
subset
(
options
.
subset
)
if
len
(
inventory
.
list_hosts
())
==
0
:
if
len
(
inventory
.
list_hosts
())
==
0
:
...
@@ -90,14 +97,18 @@ def main(args):
...
@@ -90,14 +97,18 @@ def main(args):
sshpass
=
None
sshpass
=
None
sudopass
=
None
sudopass
=
None
su_pass
=
None
if
not
options
.
listhosts
and
not
options
.
syntax
and
not
options
.
listtasks
:
if
not
options
.
listhosts
and
not
options
.
syntax
and
not
options
.
listtasks
:
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
# Never ask for an SSH password when we run with local connection
# Never ask for an SSH password when we run with local connection
if
options
.
connection
==
"local"
:
if
options
.
connection
==
"local"
:
options
.
ask_pass
=
False
options
.
ask_pass
=
False
options
.
ask_sudo_pass
=
options
.
ask_sudo_pass
or
C
.
DEFAULT_ASK_SUDO_PASS
options
.
ask_sudo_pass
=
options
.
ask_sudo_pass
or
C
.
DEFAULT_ASK_SUDO_PASS
(
sshpass
,
sudopass
)
=
utils
.
ask_passwords
(
ask_pass
=
options
.
ask_pass
,
ask_sudo_pass
=
options
.
ask_sudo_pass
)
options
.
ask_su_pass
=
options
.
ask_su_pass
or
C
.
DEFAULT_ASK_SU_PASS
(
sshpass
,
sudopass
,
su_pass
)
=
utils
.
ask_passwords
(
ask_pass
=
options
.
ask_pass
,
ask_sudo_pass
=
options
.
ask_sudo_pass
,
ask_su_pass
=
options
.
ask_su_pass
)
options
.
sudo_user
=
options
.
sudo_user
or
C
.
DEFAULT_SUDO_USER
options
.
sudo_user
=
options
.
sudo_user
or
C
.
DEFAULT_SUDO_USER
options
.
su_user
=
options
.
su_user
or
C
.
DEFAULT_SU_USER
extra_vars
=
{}
extra_vars
=
{}
for
extra_vars_opt
in
options
.
extra_vars
:
for
extra_vars_opt
in
options
.
extra_vars
:
...
@@ -156,7 +167,10 @@ def main(args):
...
@@ -156,7 +167,10 @@ def main(args):
only_tags
=
only_tags
,
only_tags
=
only_tags
,
skip_tags
=
skip_tags
,
skip_tags
=
skip_tags
,
check
=
options
.
check
,
check
=
options
.
check
,
diff
=
options
.
diff
diff
=
options
.
diff
,
su
=
options
.
su
,
su_pass
=
su_pass
,
su_user
=
options
.
su_user
)
)
if
options
.
listhosts
or
options
.
listtasks
or
options
.
syntax
:
if
options
.
listhosts
or
options
.
listtasks
or
options
.
syntax
:
...
...
lib/ansible/constants.py
View file @
da136dbe
...
@@ -127,6 +127,11 @@ DEFAULT_HASH_BEHAVIOUR = get_config(p, DEFAULTS, 'hash_behaviour', 'ANSIBLE_H
...
@@ -127,6 +127,11 @@ DEFAULT_HASH_BEHAVIOUR = get_config(p, DEFAULTS, 'hash_behaviour', 'ANSIBLE_H
DEFAULT_LEGACY_PLAYBOOK_VARIABLES
=
get_config
(
p
,
DEFAULTS
,
'legacy_playbook_variables'
,
'ANSIBLE_LEGACY_PLAYBOOK_VARIABLES'
,
True
,
boolean
=
True
)
DEFAULT_LEGACY_PLAYBOOK_VARIABLES
=
get_config
(
p
,
DEFAULTS
,
'legacy_playbook_variables'
,
'ANSIBLE_LEGACY_PLAYBOOK_VARIABLES'
,
True
,
boolean
=
True
)
DEFAULT_JINJA2_EXTENSIONS
=
get_config
(
p
,
DEFAULTS
,
'jinja2_extensions'
,
'ANSIBLE_JINJA2_EXTENSIONS'
,
None
)
DEFAULT_JINJA2_EXTENSIONS
=
get_config
(
p
,
DEFAULTS
,
'jinja2_extensions'
,
'ANSIBLE_JINJA2_EXTENSIONS'
,
None
)
DEFAULT_EXECUTABLE
=
get_config
(
p
,
DEFAULTS
,
'executable'
,
'ANSIBLE_EXECUTABLE'
,
'/bin/sh'
)
DEFAULT_EXECUTABLE
=
get_config
(
p
,
DEFAULTS
,
'executable'
,
'ANSIBLE_EXECUTABLE'
,
'/bin/sh'
)
DEFAULT_SU_EXE
=
get_config
(
p
,
DEFAULTS
,
'su_exe'
,
'ANSIBLE_SU_EXE'
,
'su'
)
DEFAULT_SU
=
get_config
(
p
,
DEFAULTS
,
'su'
,
'ANSIBLE_SU'
,
False
,
boolean
=
True
)
DEFAULT_SU_FLAGS
=
get_config
(
p
,
DEFAULTS
,
'su_flags'
,
'ANSIBLE_SU_FLAGS'
,
''
)
DEFAULT_SU_USER
=
get_config
(
p
,
DEFAULTS
,
'su_user'
,
'ANSIBLE_SU_USER'
,
'root'
)
DEFAULT_ASK_SU_PASS
=
get_config
(
p
,
DEFAULTS
,
'ask_su_pass'
,
'ANSIBLE_ASK_SU_PASS'
,
False
,
boolean
=
True
)
DEFAULT_ACTION_PLUGIN_PATH
=
get_config
(
p
,
DEFAULTS
,
'action_plugins'
,
'ANSIBLE_ACTION_PLUGINS'
,
'/usr/share/ansible_plugins/action_plugins'
)
DEFAULT_ACTION_PLUGIN_PATH
=
get_config
(
p
,
DEFAULTS
,
'action_plugins'
,
'ANSIBLE_ACTION_PLUGINS'
,
'/usr/share/ansible_plugins/action_plugins'
)
DEFAULT_CALLBACK_PLUGIN_PATH
=
get_config
(
p
,
DEFAULTS
,
'callback_plugins'
,
'ANSIBLE_CALLBACK_PLUGINS'
,
'/usr/share/ansible_plugins/callback_plugins'
)
DEFAULT_CALLBACK_PLUGIN_PATH
=
get_config
(
p
,
DEFAULTS
,
'callback_plugins'
,
'ANSIBLE_CALLBACK_PLUGINS'
,
'/usr/share/ansible_plugins/callback_plugins'
)
...
@@ -161,4 +166,5 @@ DEFAULT_PASSWORD_CHARS = ascii_letters + digits + ".,:-_"
...
@@ -161,4 +166,5 @@ DEFAULT_PASSWORD_CHARS = ascii_letters + digits + ".,:-_"
DEFAULT_SUDO_PASS
=
None
DEFAULT_SUDO_PASS
=
None
DEFAULT_REMOTE_PASS
=
None
DEFAULT_REMOTE_PASS
=
None
DEFAULT_SUBSET
=
None
DEFAULT_SUBSET
=
None
DEFAULT_SU_PASS
=
None
lib/ansible/playbook/__init__.py
View file @
da136dbe
...
@@ -68,7 +68,11 @@ class PlayBook(object):
...
@@ -68,7 +68,11 @@ class PlayBook(object):
inventory
=
None
,
inventory
=
None
,
check
=
False
,
check
=
False
,
diff
=
False
,
diff
=
False
,
any_errors_fatal
=
False
):
any_errors_fatal
=
False
,
su
=
False
,
su_user
=
False
,
su_pass
=
False
,
):
"""
"""
playbook: path to a playbook file
playbook: path to a playbook file
...
@@ -122,6 +126,9 @@ class PlayBook(object):
...
@@ -122,6 +126,9 @@ class PlayBook(object):
self
.
only_tags
=
only_tags
self
.
only_tags
=
only_tags
self
.
skip_tags
=
skip_tags
self
.
skip_tags
=
skip_tags
self
.
any_errors_fatal
=
any_errors_fatal
self
.
any_errors_fatal
=
any_errors_fatal
self
.
su
=
su
self
.
su_user
=
su_user
self
.
su_pass
=
su_pass
self
.
callbacks
.
playbook
=
self
self
.
callbacks
.
playbook
=
self
self
.
runner_callbacks
.
playbook
=
self
self
.
runner_callbacks
.
playbook
=
self
...
@@ -303,20 +310,39 @@ class PlayBook(object):
...
@@ -303,20 +310,39 @@ class PlayBook(object):
self
.
inventory
.
restrict_to
(
hosts
)
self
.
inventory
.
restrict_to
(
hosts
)
runner
=
ansible
.
runner
.
Runner
(
runner
=
ansible
.
runner
.
Runner
(
pattern
=
task
.
play
.
hosts
,
inventory
=
self
.
inventory
,
module_name
=
task
.
module_name
,
pattern
=
task
.
play
.
hosts
,
module_args
=
task
.
module_args
,
forks
=
self
.
forks
,
inventory
=
self
.
inventory
,
remote_pass
=
self
.
remote_pass
,
module_path
=
self
.
module_path
,
module_name
=
task
.
module_name
,
timeout
=
self
.
timeout
,
remote_user
=
task
.
remote_user
,
module_args
=
task
.
module_args
,
remote_port
=
task
.
play
.
remote_port
,
module_vars
=
task
.
module_vars
,
forks
=
self
.
forks
,
default_vars
=
task
.
default_vars
,
private_key_file
=
self
.
private_key_file
,
remote_pass
=
self
.
remote_pass
,
setup_cache
=
self
.
SETUP_CACHE
,
basedir
=
task
.
play
.
basedir
,
module_path
=
self
.
module_path
,
conditional
=
task
.
when
,
callbacks
=
self
.
runner_callbacks
,
timeout
=
self
.
timeout
,
sudo
=
task
.
sudo
,
sudo_user
=
task
.
sudo_user
,
remote_user
=
task
.
remote_user
,
transport
=
task
.
transport
,
sudo_pass
=
task
.
sudo_pass
,
is_playbook
=
True
,
remote_port
=
task
.
play
.
remote_port
,
check
=
self
.
check
,
diff
=
self
.
diff
,
environment
=
task
.
environment
,
complex_args
=
task
.
args
,
module_vars
=
task
.
module_vars
,
accelerate
=
task
.
play
.
accelerate
,
accelerate_port
=
task
.
play
.
accelerate_port
,
default_vars
=
task
.
default_vars
,
private_key_file
=
self
.
private_key_file
,
setup_cache
=
self
.
SETUP_CACHE
,
basedir
=
task
.
play
.
basedir
,
conditional
=
task
.
when
,
callbacks
=
self
.
runner_callbacks
,
sudo
=
task
.
sudo
,
sudo_user
=
task
.
sudo_user
,
transport
=
task
.
transport
,
sudo_pass
=
task
.
sudo_pass
,
is_playbook
=
True
,
check
=
self
.
check
,
diff
=
self
.
diff
,
environment
=
task
.
environment
,
complex_args
=
task
.
args
,
accelerate
=
task
.
play
.
accelerate
,
accelerate_port
=
task
.
play
.
accelerate_port
,
accelerate_ipv6
=
task
.
play
.
accelerate_ipv6
,
accelerate_ipv6
=
task
.
play
.
accelerate_ipv6
,
error_on_undefined_vars
=
C
.
DEFAULT_UNDEFINED_VAR_BEHAVIOR
error_on_undefined_vars
=
C
.
DEFAULT_UNDEFINED_VAR_BEHAVIOR
,
su
=
task
.
su
,
su_user
=
task
.
su_user
,
su_pass
=
task
.
su_pass
)
)
if
task
.
async_seconds
==
0
:
if
task
.
async_seconds
==
0
:
...
@@ -446,13 +472,30 @@ class PlayBook(object):
...
@@ -446,13 +472,30 @@ class PlayBook(object):
# push any variables down to the system
# push any variables down to the system
setup_results
=
ansible
.
runner
.
Runner
(
setup_results
=
ansible
.
runner
.
Runner
(
pattern
=
play
.
hosts
,
module_name
=
'setup'
,
module_args
=
{},
inventory
=
self
.
inventory
,
pattern
=
play
.
hosts
,
forks
=
self
.
forks
,
module_path
=
self
.
module_path
,
timeout
=
self
.
timeout
,
remote_user
=
play
.
remote_user
,
module_name
=
'setup'
,
remote_pass
=
self
.
remote_pass
,
remote_port
=
play
.
remote_port
,
private_key_file
=
self
.
private_key_file
,
module_args
=
{},
setup_cache
=
self
.
SETUP_CACHE
,
callbacks
=
self
.
runner_callbacks
,
sudo
=
play
.
sudo
,
sudo_user
=
play
.
sudo_user
,
inventory
=
self
.
inventory
,
transport
=
play
.
transport
,
sudo_pass
=
self
.
sudo_pass
,
is_playbook
=
True
,
module_vars
=
play
.
vars
,
forks
=
self
.
forks
,
default_vars
=
play
.
default_vars
,
check
=
self
.
check
,
diff
=
self
.
diff
,
module_path
=
self
.
module_path
,
accelerate
=
play
.
accelerate
,
accelerate_port
=
play
.
accelerate_port
,
timeout
=
self
.
timeout
,
remote_user
=
play
.
remote_user
,
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
,
transport
=
play
.
transport
,
sudo_pass
=
self
.
sudo_pass
,
is_playbook
=
True
,
module_vars
=
play
.
vars
,
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
)
...
...
lib/ansible/playbook/play.py
View file @
da136dbe
...
@@ -34,7 +34,7 @@ class Play(object):
...
@@ -34,7 +34,7 @@ class Play(object):
'handlers'
,
'remote_user'
,
'remote_port'
,
'included_roles'
,
'accelerate'
,
'handlers'
,
'remote_user'
,
'remote_port'
,
'included_roles'
,
'accelerate'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'sudo'
,
'sudo_user'
,
'transport'
,
'playbook'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'sudo'
,
'sudo_user'
,
'transport'
,
'playbook'
,
'tags'
,
'gather_facts'
,
'serial'
,
'_ds'
,
'_handlers'
,
'_tasks'
,
'tags'
,
'gather_facts'
,
'serial'
,
'_ds'
,
'_handlers'
,
'_tasks'
,
'basedir'
,
'any_errors_fatal'
,
'roles'
,
'max_fail_pct'
'basedir'
,
'any_errors_fatal'
,
'roles'
,
'max_fail_pct'
,
'su'
,
'su_user'
]
]
# to catch typos and so forth -- these are userland names
# to catch typos and so forth -- these are userland names
...
@@ -43,7 +43,8 @@ class Play(object):
...
@@ -43,7 +43,8 @@ class Play(object):
'hosts'
,
'name'
,
'vars'
,
'vars_prompt'
,
'vars_files'
,
'hosts'
,
'name'
,
'vars'
,
'vars_prompt'
,
'vars_files'
,
'tasks'
,
'handlers'
,
'remote_user'
,
'user'
,
'port'
,
'include'
,
'accelerate'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'tasks'
,
'handlers'
,
'remote_user'
,
'user'
,
'port'
,
'include'
,
'accelerate'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'sudo'
,
'sudo_user'
,
'connection'
,
'tags'
,
'gather_facts'
,
'serial'
,
'sudo'
,
'sudo_user'
,
'connection'
,
'tags'
,
'gather_facts'
,
'serial'
,
'any_errors_fatal'
,
'roles'
,
'pre_tasks'
,
'post_tasks'
,
'max_fail_percentage'
'any_errors_fatal'
,
'roles'
,
'pre_tasks'
,
'post_tasks'
,
'max_fail_percentage'
,
'su'
,
'su_user'
]
]
# *************************************************
# *************************************************
...
@@ -121,6 +122,8 @@ class Play(object):
...
@@ -121,6 +122,8 @@ class Play(object):
self
.
accelerate_port
=
ds
.
get
(
'accelerate_port'
,
None
)
self
.
accelerate_port
=
ds
.
get
(
'accelerate_port'
,
None
)
self
.
accelerate_ipv6
=
ds
.
get
(
'accelerate_ipv6'
,
False
)
self
.
accelerate_ipv6
=
ds
.
get
(
'accelerate_ipv6'
,
False
)
self
.
max_fail_pct
=
int
(
ds
.
get
(
'max_fail_percentage'
,
100
))
self
.
max_fail_pct
=
int
(
ds
.
get
(
'max_fail_percentage'
,
100
))
self
.
su
=
ds
.
get
(
'su'
,
self
.
playbook
.
su
)
self
.
su_user
=
ds
.
get
(
'su_user'
,
self
.
playbook
.
su_user
)
load_vars
=
{}
load_vars
=
{}
load_vars
[
'playbook_dir'
]
=
self
.
basedir
load_vars
[
'playbook_dir'
]
=
self
.
basedir
...
@@ -432,7 +435,8 @@ class Play(object):
...
@@ -432,7 +435,8 @@ class Play(object):
# *************************************************
# *************************************************
def
_load_tasks
(
self
,
tasks
,
vars
=
None
,
default_vars
=
None
,
sudo_vars
=
None
,
additional_conditions
=
None
,
original_file
=
None
,
role_name
=
None
):
def
_load_tasks
(
self
,
tasks
,
vars
=
None
,
default_vars
=
None
,
sudo_vars
=
None
,
additional_conditions
=
None
,
original_file
=
None
,
role_name
=
None
):
''' handle task and handler include statements '''
''' handle task and handler include statements '''
results
=
[]
results
=
[]
...
@@ -469,7 +473,7 @@ class Play(object):
...
@@ -469,7 +473,7 @@ class Play(object):
if
'meta'
in
x
:
if
'meta'
in
x
:
if
x
[
'meta'
]
==
'flush_handlers'
:
if
x
[
'meta'
]
==
'flush_handlers'
:
results
.
append
(
Task
(
self
,
x
))
results
.
append
(
Task
(
self
,
x
))
continue
continue
task_vars
=
self
.
vars
.
copy
()
task_vars
=
self
.
vars
.
copy
()
...
@@ -537,7 +541,13 @@ class Play(object):
...
@@ -537,7 +541,13 @@ class Play(object):
loaded
=
self
.
_load_tasks
(
data
,
mv
,
default_vars
,
included_sudo_vars
,
list
(
included_additional_conditions
),
original_file
=
include_filename
,
role_name
=
new_role
)
loaded
=
self
.
_load_tasks
(
data
,
mv
,
default_vars
,
included_sudo_vars
,
list
(
included_additional_conditions
),
original_file
=
include_filename
,
role_name
=
new_role
)
results
+=
loaded
results
+=
loaded
elif
type
(
x
)
==
dict
:
elif
type
(
x
)
==
dict
:
task
=
Task
(
self
,
x
,
module_vars
=
task_vars
,
default_vars
=
default_vars
,
additional_conditions
=
list
(
additional_conditions
),
role_name
=
role_name
)
task
=
Task
(
self
,
x
,
module_vars
=
task_vars
,
default_vars
=
default_vars
,
additional_conditions
=
list
(
additional_conditions
),
role_name
=
role_name
)
results
.
append
(
task
)
results
.
append
(
task
)
else
:
else
:
raise
Exception
(
"unexpected task type"
)
raise
Exception
(
"unexpected task type"
)
...
...
lib/ansible/playbook/task.py
View file @
da136dbe
...
@@ -30,7 +30,8 @@ class Task(object):
...
@@ -30,7 +30,8 @@ class Task(object):
'delegate_to'
,
'first_available_file'
,
'ignore_errors'
,
'delegate_to'
,
'first_available_file'
,
'ignore_errors'
,
'local_action'
,
'transport'
,
'sudo'
,
'remote_user'
,
'sudo_user'
,
'sudo_pass'
,
'local_action'
,
'transport'
,
'sudo'
,
'remote_user'
,
'sudo_user'
,
'sudo_pass'
,
'items_lookup_plugin'
,
'items_lookup_terms'
,
'environment'
,
'args'
,
'items_lookup_plugin'
,
'items_lookup_terms'
,
'environment'
,
'args'
,
'any_errors_fatal'
,
'changed_when'
,
'failed_when'
,
'always_run'
,
'delay'
,
'retries'
,
'until'
'any_errors_fatal'
,
'changed_when'
,
'failed_when'
,
'always_run'
,
'delay'
,
'retries'
,
'until'
,
'su'
,
'su_user'
,
'su_pass'
]
]
# to prevent typos and such
# to prevent typos and such
...
@@ -39,7 +40,8 @@ class Task(object):
...
@@ -39,7 +40,8 @@ class Task(object):
'first_available_file'
,
'include'
,
'tags'
,
'register'
,
'ignore_errors'
,
'first_available_file'
,
'include'
,
'tags'
,
'register'
,
'ignore_errors'
,
'delegate_to'
,
'local_action'
,
'transport'
,
'remote_user'
,
'sudo'
,
'sudo_user'
,
'delegate_to'
,
'local_action'
,
'transport'
,
'remote_user'
,
'sudo'
,
'sudo_user'
,
'sudo_pass'
,
'when'
,
'connection'
,
'environment'
,
'args'
,
'sudo_pass'
,
'when'
,
'connection'
,
'environment'
,
'args'
,
'any_errors_fatal'
,
'changed_when'
,
'failed_when'
,
'always_run'
,
'delay'
,
'retries'
,
'until'
'any_errors_fatal'
,
'changed_when'
,
'failed_when'
,
'always_run'
,
'delay'
,
'retries'
,
'until'
,
'su'
,
'su_user'
,
'su_pass'
]
]
def
__init__
(
self
,
play
,
ds
,
module_vars
=
None
,
default_vars
=
None
,
additional_conditions
=
None
,
role_name
=
None
):
def
__init__
(
self
,
play
,
ds
,
module_vars
=
None
,
default_vars
=
None
,
additional_conditions
=
None
,
role_name
=
None
):
...
@@ -117,6 +119,7 @@ class Task(object):
...
@@ -117,6 +119,7 @@ class Task(object):
self
.
tags
=
[
'all'
]
self
.
tags
=
[
'all'
]
self
.
register
=
ds
.
get
(
'register'
,
None
)
self
.
register
=
ds
.
get
(
'register'
,
None
)
self
.
sudo
=
utils
.
boolean
(
ds
.
get
(
'sudo'
,
play
.
sudo
))
self
.
sudo
=
utils
.
boolean
(
ds
.
get
(
'sudo'
,
play
.
sudo
))
self
.
su
=
utils
.
boolean
(
ds
.
get
(
'sudo'
,
play
.
su
))
self
.
environment
=
ds
.
get
(
'environment'
,
{})
self
.
environment
=
ds
.
get
(
'environment'
,
{})
self
.
role_name
=
role_name
self
.
role_name
=
role_name
...
@@ -142,13 +145,18 @@ class Task(object):
...
@@ -142,13 +145,18 @@ class Task(object):
else
:
else
:
self
.
remote_user
=
ds
.
get
(
'remote_user'
,
play
.
playbook
.
remote_user
)
self
.
remote_user
=
ds
.
get
(
'remote_user'
,
play
.
playbook
.
remote_user
)
self
.
sudo_user
=
None
self
.
sudo_pass
=
None
self
.
su_user
=
None
self
.
su_pass
=
None
if
self
.
sudo
:
if
self
.
sudo
:
self
.
sudo_user
=
ds
.
get
(
'sudo_user'
,
play
.
sudo_user
)
self
.
sudo_user
=
ds
.
get
(
'sudo_user'
,
play
.
sudo_user
)
self
.
sudo_pass
=
ds
.
get
(
'sudo_pass'
,
play
.
playbook
.
sudo_pass
)
self
.
sudo_pass
=
ds
.
get
(
'sudo_pass'
,
play
.
playbook
.
sudo_pass
)
el
se
:
el
if
self
.
su
:
self
.
su
do_user
=
None
self
.
su
_user
=
ds
.
get
(
'su_user'
,
play
.
su_user
)
self
.
su
do_pass
=
None
self
.
su
_pass
=
ds
.
get
(
'su_pass'
,
play
.
playbook
.
su_pass
)
# Both are defined
# Both are defined
if
(
'action'
in
ds
)
and
(
'local_action'
in
ds
):
if
(
'action'
in
ds
)
and
(
'local_action'
in
ds
):
raise
errors
.
AnsibleError
(
"the 'action' and 'local_action' attributes can not be used together"
)
raise
errors
.
AnsibleError
(
"the 'action' and 'local_action' attributes can not be used together"
)
...
...
lib/ansible/runner/__init__.py
View file @
da136dbe
...
@@ -141,6 +141,9 @@ class Runner(object):
...
@@ -141,6 +141,9 @@ class Runner(object):
accelerate
=
False
,
# use accelerated connection
accelerate
=
False
,
# use accelerated connection
accelerate_ipv6
=
False
,
# accelerated connection w/ IPv6
accelerate_ipv6
=
False
,
# accelerated connection w/ IPv6
accelerate_port
=
None
,
# port to use with accelerated connection
accelerate_port
=
None
,
# port to use with accelerated connection
su
=
False
,
# Are we running our command via su?
su_user
=
None
,
# User to su to when running command, ex: 'root'
su_pass
=
C
.
DEFAULT_SU_PASS
):
):
# used to lock multiprocess inputs and outputs at various levels
# used to lock multiprocess inputs and outputs at various levels
...
@@ -188,6 +191,9 @@ class Runner(object):
...
@@ -188,6 +191,9 @@ class Runner(object):
self
.
accelerate_ipv6
=
accelerate_ipv6
self
.
accelerate_ipv6
=
accelerate_ipv6
self
.
callbacks
.
runner
=
self
self
.
callbacks
.
runner
=
self
self
.
original_transport
=
self
.
transport
self
.
original_transport
=
self
.
transport
self
.
su
=
su
self
.
su_user
=
su_user
self
.
su_pass
=
su_pass
if
self
.
transport
==
'smart'
:
if
self
.
transport
==
'smart'
:
# if the transport is 'smart' see if SSH can support ControlPersist if not use paramiko
# if the transport is 'smart' see if SSH can support ControlPersist if not use paramiko
...
@@ -311,12 +317,13 @@ class Runner(object):
...
@@ -311,12 +317,13 @@ class Runner(object):
or
async_jid
is
not
None
or
async_jid
is
not
None
or
not
conn
.
has_pipelining
or
not
conn
.
has_pipelining
or
not
C
.
ANSIBLE_SSH_PIPELINING
or
not
C
.
ANSIBLE_SSH_PIPELINING
or
C
.
DEFAULT_KEEP_REMOTE_FILES
):
or
C
.
DEFAULT_KEEP_REMOTE_FILES
or
self
.
su
):
self
.
_transfer_str
(
conn
,
tmp
,
module_name
,
module_data
)
self
.
_transfer_str
(
conn
,
tmp
,
module_name
,
module_data
)
environment_string
=
self
.
_compute_environment_string
(
inject
)
environment_string
=
self
.
_compute_environment_string
(
inject
)
if
tmp
.
find
(
"tmp"
)
!=
-
1
and
self
.
sudo
and
self
.
sudo_user
!=
'root'
:
if
(
self
.
sudo
or
self
.
su
)
and
(
self
.
sudo_user
!=
'root'
or
self
.
su_user
!=
'root'
)
:
# deal with possible umask issues once sudo'ed to other user
# deal with possible umask issues once sudo'ed to other user
cmd_chmod
=
"chmod a+r
%
s"
%
remote_module_path
cmd_chmod
=
"chmod a+r
%
s"
%
remote_module_path
self
.
_low_level_exec_command
(
conn
,
cmd_chmod
,
tmp
,
sudoable
=
False
)
self
.
_low_level_exec_command
(
conn
,
cmd_chmod
,
tmp
,
sudoable
=
False
)
...
@@ -343,7 +350,7 @@ class Runner(object):
...
@@ -343,7 +350,7 @@ class Runner(object):
else
:
else
:
argsfile
=
self
.
_transfer_str
(
conn
,
tmp
,
'arguments'
,
args
)
argsfile
=
self
.
_transfer_str
(
conn
,
tmp
,
'arguments'
,
args
)
if
self
.
sudo
and
self
.
sudo_user
!=
'root'
:
if
(
self
.
sudo
or
self
.
su
)
and
(
self
.
sudo_user
!=
'root'
or
self
.
su_user
!=
'root'
)
:
# deal with possible umask issues once sudo'ed to other user
# deal with possible umask issues once sudo'ed to other user
cmd_args_chmod
=
"chmod a+r
%
s"
%
argsfile
cmd_args_chmod
=
"chmod a+r
%
s"
%
argsfile
self
.
_low_level_exec_command
(
conn
,
cmd_args_chmod
,
tmp
,
sudoable
=
False
)
self
.
_low_level_exec_command
(
conn
,
cmd_args_chmod
,
tmp
,
sudoable
=
False
)
...
@@ -354,7 +361,7 @@ class Runner(object):
...
@@ -354,7 +361,7 @@ class Runner(object):
cmd
=
" "
.
join
([
str
(
x
)
for
x
in
[
remote_module_path
,
async_jid
,
async_limit
,
async_module
,
argsfile
]])
cmd
=
" "
.
join
([
str
(
x
)
for
x
in
[
remote_module_path
,
async_jid
,
async_limit
,
async_module
,
argsfile
]])
else
:
else
:
if
async_jid
is
None
:
if
async_jid
is
None
:
if
conn
.
has_pipelining
and
C
.
ANSIBLE_SSH_PIPELINING
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
:
if
conn
.
has_pipelining
and
C
.
ANSIBLE_SSH_PIPELINING
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
and
not
self
.
su
:
in_data
=
module_data
in_data
=
module_data
else
:
else
:
cmd
=
"
%
s"
%
(
remote_module_path
)
cmd
=
"
%
s"
%
(
remote_module_path
)
...
@@ -369,7 +376,7 @@ class Runner(object):
...
@@ -369,7 +376,7 @@ class Runner(object):
cmd
=
cmd
.
strip
()
cmd
=
cmd
.
strip
()
if
tmp
.
find
(
"tmp"
)
!=
-
1
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
and
not
persist_files
:
if
tmp
.
find
(
"tmp"
)
!=
-
1
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
and
not
persist_files
:
if
not
self
.
sudo
or
self
.
su
do
_user
==
'root'
:
if
not
self
.
sudo
or
self
.
su
or
self
.
sudo_user
==
'root'
or
self
.
su
_user
==
'root'
:
# not sudoing or sudoing to root, so can cleanup files in the same step
# not sudoing or sudoing to root, so can cleanup files in the same step
cmd
=
cmd
+
"; rm -rf
%
s >/dev/null 2>&1"
%
tmp
cmd
=
cmd
+
"; rm -rf
%
s >/dev/null 2>&1"
%
tmp
...
@@ -379,10 +386,13 @@ class Runner(object):
...
@@ -379,10 +386,13 @@ class Runner(object):
# specified in the play, not the sudo_user
# specified in the play, not the sudo_user
sudoable
=
False
sudoable
=
False
res
=
self
.
_low_level_exec_command
(
conn
,
cmd
,
tmp
,
sudoable
=
sudoable
,
in_data
=
in_data
)
if
self
.
su
:
res
=
self
.
_low_level_exec_command
(
conn
,
cmd
,
tmp
,
su
=
sudoable
,
in_data
=
in_data
)
else
:
res
=
self
.
_low_level_exec_command
(
conn
,
cmd
,
tmp
,
sudoable
=
sudoable
,
in_data
=
in_data
)
if
tmp
.
find
(
"tmp"
)
!=
-
1
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
and
not
persist_files
:
if
tmp
.
find
(
"tmp"
)
!=
-
1
and
not
C
.
DEFAULT_KEEP_REMOTE_FILES
and
not
persist_files
:
if
self
.
sudo
and
self
.
sudo_user
!=
'root'
:
if
(
self
.
sudo
or
self
.
su
)
and
(
self
.
sudo_user
!=
'root'
or
self
.
su_user
!=
'root'
)
:
# not sudoing to root, so maybe can't delete files as that other user
# not sudoing to root, so maybe can't delete files as that other user
# have to clean up temp files as original user in a second step
# have to clean up temp files as original user in a second step
cmd2
=
"rm -rf
%
s >/dev/null 2>&1"
%
tmp
cmd2
=
"rm -rf
%
s >/dev/null 2>&1"
%
tmp
...
@@ -613,6 +623,9 @@ class Runner(object):
...
@@ -613,6 +623,9 @@ class Runner(object):
actual_transport
=
inject
.
get
(
'ansible_connection'
,
self
.
transport
)
actual_transport
=
inject
.
get
(
'ansible_connection'
,
self
.
transport
)
actual_private_key_file
=
inject
.
get
(
'ansible_ssh_private_key_file'
,
self
.
private_key_file
)
actual_private_key_file
=
inject
.
get
(
'ansible_ssh_private_key_file'
,
self
.
private_key_file
)
self
.
sudo_pass
=
inject
.
get
(
'ansible_sudo_pass'
,
self
.
sudo_pass
)
self
.
sudo_pass
=
inject
.
get
(
'ansible_sudo_pass'
,
self
.
sudo_pass
)
self
.
su
=
inject
.
get
(
'ansible_su'
,
self
.
su_pass
)
self
.
su_user
=
inject
.
get
(
'ansible_su_user'
,
self
.
su_user
)
self
.
su_pass
=
inject
.
get
(
'ansible_su_pass'
,
self
.
su_pass
)
if
actual_private_key_file
is
not
None
:
if
actual_private_key_file
is
not
None
:
actual_private_key_file
=
os
.
path
.
expanduser
(
actual_private_key_file
)
actual_private_key_file
=
os
.
path
.
expanduser
(
actual_private_key_file
)
...
@@ -798,7 +811,10 @@ class Runner(object):
...
@@ -798,7 +811,10 @@ class Runner(object):
if
tmp
.
find
(
"tmp"
)
!=
-
1
:
if
tmp
.
find
(
"tmp"
)
!=
-
1
:
# tmp has already been created
# tmp has already been created
return
False
return
False
if
not
conn
.
has_pipelining
or
not
C
.
ANSIBLE_SSH_PIPELINING
or
C
.
DEFAULT_KEEP_REMOTE_FILES
:
if
not
conn
.
has_pipelining
or
not
C
.
ANSIBLE_SSH_PIPELINING
or
C
.
DEFAULT_KEEP_REMOTE_FILES
or
self
.
su
:
# tmp is necessary to store module source code
return
True
if
not
conn
.
has_pipelining
:
# tmp is necessary to store the module source code
# tmp is necessary to store the module source code
# or we want to keep the files on the target system
# or we want to keep the files on the target system
return
True
return
True
...
@@ -810,20 +826,36 @@ class Runner(object):
...
@@ -810,20 +826,36 @@ class Runner(object):
# *****************************************************
# *****************************************************
def
_low_level_exec_command
(
self
,
conn
,
cmd
,
tmp
,
sudoable
=
False
,
executable
=
None
,
in_data
=
None
):
def
_low_level_exec_command
(
self
,
conn
,
cmd
,
tmp
,
sudoable
=
False
,
executable
=
None
,
su
=
False
,
in_data
=
None
):
''' execute a command string over SSH, return the output '''
''' execute a command string over SSH, return the output '''
if
executable
is
None
:
if
executable
is
None
:
executable
=
C
.
DEFAULT_EXECUTABLE
executable
=
C
.
DEFAULT_EXECUTABLE
sudo_user
=
self
.
sudo_user
sudo_user
=
self
.
sudo_user
su_user
=
self
.
su_user
# compare connection user to sudo_user and disable if the same
# compare connection user to sudo_user and disable if the same
if
hasattr
(
conn
,
'user'
):
if
hasattr
(
conn
,
'user'
):
if
conn
.
user
==
sudo_user
:
if
conn
.
user
==
sudo_user
or
conn
.
user
==
su_user
:
sudoable
=
False
sudoable
=
False
su
=
False
rc
,
stdin
,
stdout
,
stderr
=
conn
.
exec_command
(
cmd
,
tmp
,
sudo_user
,
sudoable
=
sudoable
,
executable
=
executable
,
in_data
=
in_data
)
if
su
:
rc
,
stdin
,
stdout
,
stderr
=
conn
.
exec_command
(
cmd
,
tmp
,
su_user
=
su_user
,
su
=
su
,
executable
=
executable
,
in_data
=
in_data
)
else
:
rc
,
stdin
,
stdout
,
stderr
=
conn
.
exec_command
(
cmd
,
tmp
,
sudo_user
,
sudoable
=
sudoable
,
executable
=
executable
,
in_data
=
in_data
)
if
type
(
stdout
)
not
in
[
str
,
unicode
]:
if
type
(
stdout
)
not
in
[
str
,
unicode
]:
out
=
''
.
join
(
stdout
.
readlines
())
out
=
''
.
join
(
stdout
.
readlines
())
...
@@ -881,11 +913,11 @@ class Runner(object):
...
@@ -881,11 +913,11 @@ class Runner(object):
basefile
=
'ansible-tmp-
%
s-
%
s'
%
(
time
.
time
(),
random
.
randint
(
0
,
2
**
48
))
basefile
=
'ansible-tmp-
%
s-
%
s'
%
(
time
.
time
(),
random
.
randint
(
0
,
2
**
48
))
basetmp
=
os
.
path
.
join
(
C
.
DEFAULT_REMOTE_TMP
,
basefile
)
basetmp
=
os
.
path
.
join
(
C
.
DEFAULT_REMOTE_TMP
,
basefile
)
if
self
.
sudo
and
self
.
sudo_user
!=
'root'
and
basetmp
.
startswith
(
'$HOME'
):
if
(
self
.
sudo
or
self
.
su
)
and
(
self
.
sudo_user
!=
'root'
or
self
.
su
!=
'root'
)
and
basetmp
.
startswith
(
'$HOME'
):
basetmp
=
os
.
path
.
join
(
'/tmp'
,
basefile
)
basetmp
=
os
.
path
.
join
(
'/tmp'
,
basefile
)
cmd
=
'mkdir -p
%
s'
%
basetmp
cmd
=
'mkdir -p
%
s'
%
basetmp
if
self
.
remote_user
!=
'root'
or
(
self
.
sudo
and
self
.
sudo_user
!=
'root'
):
if
self
.
remote_user
!=
'root'
or
(
(
self
.
sudo
or
self
.
su
)
and
(
self
.
sudo_user
!=
'root'
or
self
.
su
!=
'root'
)
):
cmd
+=
' && chmod a+rx
%
s'
%
basetmp
cmd
+=
' && chmod a+rx
%
s'
%
basetmp
cmd
+=
' && echo
%
s'
%
basetmp
cmd
+=
' && echo
%
s'
%
basetmp
...
...
lib/ansible/runner/connection_plugins/accelerate.py
View file @
da136dbe
...
@@ -159,9 +159,12 @@ class Connection(object):
...
@@ -159,9 +159,12 @@ class Connection(object):
except
socket
.
timeout
:
except
socket
.
timeout
:
raise
errors
.
AnsibleError
(
"timed out while waiting to receive data"
)
raise
errors
.
AnsibleError
(
"timed out while waiting to receive data"
)
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the remote host '''
''' run a command on the remote host '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
if
in_data
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
...
...
lib/ansible/runner/connection_plugins/chroot.py
View file @
da136dbe
...
@@ -60,9 +60,12 @@ class Connection(object):
...
@@ -60,9 +60,12 @@ class Connection(object):
return
self
return
self
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the chroot '''
''' run a command on the chroot '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
if
in_data
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
...
...
lib/ansible/runner/connection_plugins/fireball.py
View file @
da136dbe
...
@@ -68,7 +68,7 @@ class Connection(object):
...
@@ -68,7 +68,7 @@ class Connection(object):
return
self
return
self
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su_user
=
None
,
su
=
None
):
''' run a command on the remote host '''
''' run a command on the remote host '''
if
in_data
:
if
in_data
:
...
@@ -76,9 +76,9 @@ class Connection(object):
...
@@ -76,9 +76,9 @@ class Connection(object):
vvv
(
"EXEC COMMAND
%
s"
%
cmd
)
vvv
(
"EXEC COMMAND
%
s"
%
cmd
)
if
self
.
runner
.
sudo
and
sudoable
:
if
(
self
.
runner
.
sudo
and
sudoable
)
or
(
self
.
runner
.
su
and
su
)
:
raise
errors
.
AnsibleError
(
raise
errors
.
AnsibleError
(
"When using fireball, do not specify sudo to run your tasks. "
+
"When using fireball, do not specify sudo
or su
to run your tasks. "
+
"Instead sudo the fireball action with sudo. "
+
"Instead sudo the fireball action with sudo. "
+
"Task will communicate with the fireball already running in sudo mode."
"Task will communicate with the fireball already running in sudo mode."
)
)
...
...
lib/ansible/runner/connection_plugins/funcd.py
View file @
da136dbe
...
@@ -53,10 +53,13 @@ class Connection(object):
...
@@ -53,10 +53,13 @@ class Connection(object):
self
.
client
=
fc
.
Client
(
self
.
host
)
self
.
client
=
fc
.
Client
(
self
.
host
)
return
self
return
self
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the remote minion '''
''' run a command on the remote minion '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
if
in_data
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
...
...
lib/ansible/runner/connection_plugins/jail.py
View file @
da136dbe
...
@@ -91,9 +91,12 @@ class Connection(object):
...
@@ -91,9 +91,12 @@ class Connection(object):
local_cmd
=
'
%
s "
%
s"
%
s'
%
(
self
.
jexec_cmd
,
self
.
jail
,
cmd
)
local_cmd
=
'
%
s "
%
s"
%
s'
%
(
self
.
jexec_cmd
,
self
.
jail
,
cmd
)
return
local_cmd
return
local_cmd
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the chroot '''
''' run a command on the chroot '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
if
in_data
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
...
...
lib/ansible/runner/connection_plugins/local.py
View file @
da136dbe
...
@@ -41,9 +41,13 @@ class Connection(object):
...
@@ -41,9 +41,13 @@ class Connection(object):
return
self
return
self
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the local host '''
''' run a command on the local host '''
# su requires to be run from a terminal, and therefore isn't supported here (yet?)
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
if
in_data
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support optimized module pipelining"
)
...
...
lib/ansible/runner/connection_plugins/paramiko_alt.py
View file @
da136dbe
...
@@ -176,7 +176,7 @@ class Connection(object):
...
@@ -176,7 +176,7 @@ class Connection(object):
return
ssh
return
ssh
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the remote host '''
''' run a command on the remote host '''
bufsize
=
4096
bufsize
=
4096
...
@@ -188,7 +188,7 @@ class Connection(object):
...
@@ -188,7 +188,7 @@ class Connection(object):
msg
+=
":
%
s"
%
str
(
e
)
msg
+=
":
%
s"
%
str
(
e
)
raise
errors
.
AnsibleConnectionFailed
(
msg
)
raise
errors
.
AnsibleConnectionFailed
(
msg
)
if
not
self
.
runner
.
sudo
or
not
sudoable
or
in_data
:
if
not
(
self
.
runner
.
sudo
and
sudoable
)
and
not
(
self
.
runner
.
su
and
su
)
or
in_data
:
if
executable
:
if
executable
:
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
else
:
else
:
...
@@ -208,7 +208,7 @@ class Connection(object):
...
@@ -208,7 +208,7 @@ class Connection(object):
sudo_output
=
''
sudo_output
=
''
try
:
try
:
chan
.
exec_command
(
shcmd
)
chan
.
exec_command
(
shcmd
)
if
self
.
runner
.
sudo_pass
:
if
self
.
runner
.
sudo_pass
or
self
.
runner
.
su_pass
:
while
not
sudo_output
.
endswith
(
prompt
)
and
success_key
not
in
sudo_output
:
while
not
sudo_output
.
endswith
(
prompt
)
and
success_key
not
in
sudo_output
:
chunk
=
chan
.
recv
(
bufsize
)
chunk
=
chan
.
recv
(
bufsize
)
if
not
chunk
:
if
not
chunk
:
...
@@ -220,7 +220,10 @@ class Connection(object):
...
@@ -220,7 +220,10 @@ class Connection(object):
'closed waiting for password prompt'
)
'closed waiting for password prompt'
)
sudo_output
+=
chunk
sudo_output
+=
chunk
if
success_key
not
in
sudo_output
:
if
success_key
not
in
sudo_output
:
chan
.
sendall
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
if
sudoable
:
chan
.
sendall
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
elif
su
:
chan
.
sendall
(
self
.
runner
.
su_pass
+
'
\n
'
)
except
socket
.
timeout
:
except
socket
.
timeout
:
raise
errors
.
AnsibleError
(
'ssh timed out waiting for sudo.
\n
'
+
sudo_output
)
raise
errors
.
AnsibleError
(
'ssh timed out waiting for sudo.
\n
'
+
sudo_output
)
...
...
lib/ansible/runner/connection_plugins/paramiko_ssh.py
View file @
da136dbe
...
@@ -176,7 +176,7 @@ class Connection(object):
...
@@ -176,7 +176,7 @@ class Connection(object):
return
ssh
return
ssh
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
None
,
su_user
=
None
):
''' run a command on the remote host '''
''' run a command on the remote host '''
if
in_data
:
if
in_data
:
...
@@ -191,7 +191,7 @@ class Connection(object):
...
@@ -191,7 +191,7 @@ class Connection(object):
msg
+=
":
%
s"
%
str
(
e
)
msg
+=
":
%
s"
%
str
(
e
)
raise
errors
.
AnsibleConnectionFailed
(
msg
)
raise
errors
.
AnsibleConnectionFailed
(
msg
)
if
not
self
.
runner
.
sudo
or
not
sudoable
:
if
not
(
self
.
runner
.
sudo
and
sudoable
)
and
not
(
self
.
runner
.
su
and
su
)
:
if
executable
:
if
executable
:
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
else
:
else
:
...
@@ -206,12 +206,15 @@ class Connection(object):
...
@@ -206,12 +206,15 @@ class Connection(object):
chan
.
get_pty
(
term
=
os
.
getenv
(
'TERM'
,
'vt100'
),
chan
.
get_pty
(
term
=
os
.
getenv
(
'TERM'
,
'vt100'
),
width
=
int
(
os
.
getenv
(
'COLUMNS'
,
0
)),
width
=
int
(
os
.
getenv
(
'COLUMNS'
,
0
)),
height
=
int
(
os
.
getenv
(
'LINES'
,
0
)))
height
=
int
(
os
.
getenv
(
'LINES'
,
0
)))
shcmd
,
prompt
,
success_key
=
utils
.
make_sudo_cmd
(
sudo_user
,
executable
,
cmd
)
if
self
.
runner
.
sudo
or
sudoable
:
shcmd
,
prompt
,
success_key
=
utils
.
make_sudo_cmd
(
sudo_user
,
executable
,
cmd
)
elif
self
.
runner
.
su
or
su
:
shcmd
,
prompt
,
success_key
=
utils
.
make_su_cmd
(
su_user
,
executable
,
cmd
)
vvv
(
"EXEC
%
s"
%
shcmd
,
host
=
self
.
host
)
vvv
(
"EXEC
%
s"
%
shcmd
,
host
=
self
.
host
)
sudo_output
=
''
sudo_output
=
''
try
:
try
:
chan
.
exec_command
(
shcmd
)
chan
.
exec_command
(
shcmd
)
if
self
.
runner
.
sudo_pass
:
if
self
.
runner
.
sudo_pass
or
self
.
runner
.
su_pass
:
while
not
sudo_output
.
endswith
(
prompt
)
and
success_key
not
in
sudo_output
:
while
not
sudo_output
.
endswith
(
prompt
)
and
success_key
not
in
sudo_output
:
chunk
=
chan
.
recv
(
bufsize
)
chunk
=
chan
.
recv
(
bufsize
)
if
not
chunk
:
if
not
chunk
:
...
@@ -223,7 +226,10 @@ class Connection(object):
...
@@ -223,7 +226,10 @@ class Connection(object):
'closed waiting for password prompt'
)
'closed waiting for password prompt'
)
sudo_output
+=
chunk
sudo_output
+=
chunk
if
success_key
not
in
sudo_output
:
if
success_key
not
in
sudo_output
:
chan
.
sendall
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
if
sudoable
:
chan
.
sendall
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
elif
su
:
chan
.
sendall
(
self
.
runner
.
su_pass
+
'
\n
'
)
except
socket
.
timeout
:
except
socket
.
timeout
:
raise
errors
.
AnsibleError
(
'ssh timed out waiting for sudo.
\n
'
+
sudo_output
)
raise
errors
.
AnsibleError
(
'ssh timed out waiting for sudo.
\n
'
+
sudo_output
)
...
...
lib/ansible/runner/connection_plugins/ssh.py
View file @
da136dbe
...
@@ -145,7 +145,7 @@ class Connection(object):
...
@@ -145,7 +145,7 @@ class Connection(object):
return
False
return
False
return
True
return
True
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
Non
e
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su_user
=
None
,
su
=
Fals
e
):
''' run a command on the remote host '''
''' run a command on the remote host '''
ssh_cmd
=
self
.
_password_cmd
()
ssh_cmd
=
self
.
_password_cmd
()
...
@@ -165,7 +165,10 @@ class Connection(object):
...
@@ -165,7 +165,10 @@ class Connection(object):
ssh_cmd
+=
[
'-6'
]
ssh_cmd
+=
[
'-6'
]
ssh_cmd
+=
[
self
.
host
]
ssh_cmd
+=
[
self
.
host
]
if
not
self
.
runner
.
sudo
or
not
sudoable
:
if
su
and
su_user
:
sudocmd
,
prompt
,
success_key
=
utils
.
make_su_cmd
(
su_user
,
executable
,
cmd
)
ssh_cmd
.
append
(
sudocmd
)
elif
not
self
.
runner
.
sudo
or
not
sudoable
:
if
executable
:
if
executable
:
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
else
:
else
:
...
@@ -183,7 +186,7 @@ class Connection(object):
...
@@ -183,7 +186,7 @@ class Connection(object):
# the host to known hosts is not intermingled with multiprocess output.
# the host to known hosts is not intermingled with multiprocess output.
fcntl
.
lockf
(
self
.
runner
.
process_lockfile
,
fcntl
.
LOCK_EX
)
fcntl
.
lockf
(
self
.
runner
.
process_lockfile
,
fcntl
.
LOCK_EX
)
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
# create process
# create process
if
in_data
:
if
in_data
:
# do not use pseudo-pty
# do not use pseudo-pty
...
@@ -206,7 +209,8 @@ class Connection(object):
...
@@ -206,7 +209,8 @@ class Connection(object):
self
.
_send_password
()
self
.
_send_password
()
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
if
(
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
)
or
\
(
self
.
runner
.
su
and
su
and
self
.
runner
.
su_pass
):
# several cases are handled for sudo privileges with password
# several cases are handled for sudo privileges with password
# * NOPASSWD (tty & no-tty): detect success_key on stdout
# * NOPASSWD (tty & no-tty): detect success_key on stdout
# * without NOPASSWD:
# * without NOPASSWD:
...
@@ -225,7 +229,7 @@ class Connection(object):
...
@@ -225,7 +229,7 @@ class Connection(object):
if
p
.
stderr
in
rfd
:
if
p
.
stderr
in
rfd
:
chunk
=
p
.
stderr
.
read
()
chunk
=
p
.
stderr
.
read
()
if
not
chunk
:
if
not
chunk
:
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo password prompt'
)
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo
or su
password prompt'
)
sudo_errput
+=
chunk
sudo_errput
+=
chunk
incorrect_password
=
gettext
.
dgettext
(
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
"sudo"
,
"Sorry, try again."
)
...
@@ -237,16 +241,19 @@ class Connection(object):
...
@@ -237,16 +241,19 @@ class Connection(object):
if
p
.
stdout
in
rfd
:
if
p
.
stdout
in
rfd
:
chunk
=
p
.
stdout
.
read
()
chunk
=
p
.
stdout
.
read
()
if
not
chunk
:
if
not
chunk
:
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo password prompt'
)
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo
or su
password prompt'
)
sudo_output
+=
chunk
sudo_output
+=
chunk
if
not
rfd
:
if
not
rfd
:
# timeout. wrap up process communication
# timeout. wrap up process communication
stdout
=
p
.
communicate
()
stdout
=
p
.
communicate
()
raise
errors
.
AnsibleError
(
'ssh connection error waiting for sudo password prompt'
)
raise
errors
.
AnsibleError
(
'ssh connection error waiting for sudo
or su
password prompt'
)
if
success_key
not
in
sudo_output
:
if
success_key
not
in
sudo_output
:
stdin
.
write
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
if
sudoable
:
stdin
.
write
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
elif
su
:
stdin
.
write
(
self
.
runner
.
su_pass
+
'
\n
'
)
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
fcntl
.
fcntl
(
p
.
stderr
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stderr
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
fcntl
.
fcntl
(
p
.
stderr
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stderr
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
# We can't use p.communicate here because the ControlMaster may have stdout open as well
# We can't use p.communicate here because the ControlMaster may have stdout open as well
...
@@ -262,12 +269,18 @@ class Connection(object):
...
@@ -262,12 +269,18 @@ class Connection(object):
while
True
:
while
True
:
rfd
,
wfd
,
efd
=
select
.
select
(
rpipes
,
[],
rpipes
,
1
)
rfd
,
wfd
,
efd
=
select
.
select
(
rpipes
,
[],
rpipes
,
1
)
# fail early if the sudo password is wrong
# fail early if the sudo
/su
password is wrong
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
incorrect_password
=
gettext
.
dgettext
(
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
"sudo"
,
"Sorry, try again."
)
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
raise
errors
.
AnsibleError
(
'Incorrect sudo password'
)
raise
errors
.
AnsibleError
(
'Incorrect sudo password'
)
if
self
.
runner
.
su
and
su
and
self
.
runner
.
sudo_pass
:
incorrect_password
=
gettext
.
dgettext
(
"su"
,
"Sorry"
)
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
raise
errors
.
AnsibleError
(
'Incorrect su password'
)
if
p
.
stdout
in
rfd
:
if
p
.
stdout
in
rfd
:
dat
=
os
.
read
(
p
.
stdout
.
fileno
(),
9000
)
dat
=
os
.
read
(
p
.
stdout
.
fileno
(),
9000
)
...
...
lib/ansible/runner/connection_plugins/ssh_old.py
View file @
da136dbe
...
@@ -145,7 +145,7 @@ class Connection(object):
...
@@ -145,7 +145,7 @@ class Connection(object):
return
False
return
False
return
True
return
True
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
):
def
exec_command
(
self
,
cmd
,
tmp_path
,
sudo_user
=
None
,
sudoable
=
False
,
executable
=
'/bin/sh'
,
in_data
=
None
,
su
=
False
,
su_user
=
None
):
''' run a command on the remote host '''
''' run a command on the remote host '''
if
in_data
:
if
in_data
:
...
@@ -163,7 +163,10 @@ class Connection(object):
...
@@ -163,7 +163,10 @@ class Connection(object):
ssh_cmd
+=
[
'-6'
]
ssh_cmd
+=
[
'-6'
]
ssh_cmd
+=
[
self
.
host
]
ssh_cmd
+=
[
self
.
host
]
if
not
self
.
runner
.
sudo
or
not
sudoable
:
if
su
and
su_user
:
sudocmd
,
prompt
,
success_key
=
utils
.
make_su_cmd
(
su_user
,
executable
,
cmd
)
ssh_cmd
.
append
(
sudocmd
)
elif
not
self
.
runner
.
sudo
or
not
sudoable
:
if
executable
:
if
executable
:
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
else
:
else
:
...
@@ -183,7 +186,6 @@ class Connection(object):
...
@@ -183,7 +186,6 @@ class Connection(object):
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
try
:
try
:
# Make sure stdin is a proper (pseudo) pty to avoid: tcgetattr errors
# Make sure stdin is a proper (pseudo) pty to avoid: tcgetattr errors
master
,
slave
=
pty
.
openpty
()
master
,
slave
=
pty
.
openpty
()
...
@@ -198,7 +200,8 @@ class Connection(object):
...
@@ -198,7 +200,8 @@ class Connection(object):
self
.
_send_password
()
self
.
_send_password
()
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
if
(
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
)
or
\
(
self
.
runner
.
su
and
su
and
self
.
runner
.
su_pass
):
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
|
os
.
O_NONBLOCK
)
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
|
os
.
O_NONBLOCK
)
sudo_output
=
''
sudo_output
=
''
...
@@ -208,13 +211,17 @@ class Connection(object):
...
@@ -208,13 +211,17 @@ class Connection(object):
if
p
.
stdout
in
rfd
:
if
p
.
stdout
in
rfd
:
chunk
=
p
.
stdout
.
read
()
chunk
=
p
.
stdout
.
read
()
if
not
chunk
:
if
not
chunk
:
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo password prompt'
)
raise
errors
.
AnsibleError
(
'ssh connection closed waiting for sudo
or su
password prompt'
)
sudo_output
+=
chunk
sudo_output
+=
chunk
else
:
else
:
stdout
=
p
.
communicate
()
stdout
=
p
.
communicate
()
raise
errors
.
AnsibleError
(
'ssh connection error waiting for sudo password prompt'
)
raise
errors
.
AnsibleError
(
'ssh connection error waiting for sudo or su password prompt'
)
if
success_key
not
in
sudo_output
:
if
success_key
not
in
sudo_output
:
stdin
.
write
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
if
sudoable
:
stdin
.
write
(
self
.
runner
.
sudo_pass
+
'
\n
'
)
elif
su
:
stdin
.
write
(
self
.
runner
.
su_pass
+
'
\n
'
)
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_SETFL
,
fcntl
.
fcntl
(
p
.
stdout
,
fcntl
.
F_GETFL
)
&
~
os
.
O_NONBLOCK
)
# We can't use p.communicate here because the ControlMaster may have stdout open as well
# We can't use p.communicate here because the ControlMaster may have stdout open as well
...
@@ -224,12 +231,18 @@ class Connection(object):
...
@@ -224,12 +231,18 @@ class Connection(object):
while
True
:
while
True
:
rfd
,
wfd
,
efd
=
select
.
select
(
rpipes
,
[],
rpipes
,
1
)
rfd
,
wfd
,
efd
=
select
.
select
(
rpipes
,
[],
rpipes
,
1
)
# fail early if the sudo password is wrong
# fail early if the sudo
/su
password is wrong
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
if
self
.
runner
.
sudo
and
sudoable
and
self
.
runner
.
sudo_pass
:
incorrect_password
=
gettext
.
dgettext
(
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
"sudo"
,
"Sorry, try again."
)
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
raise
errors
.
AnsibleError
(
'Incorrect sudo password'
)
raise
errors
.
AnsibleError
(
'Incorrect sudo password'
)
if
self
.
runner
.
su
and
su
and
self
.
runner
.
su_pass
:
incorrect_password
=
gettext
.
dgettext
(
"su"
,
"su: Authentication failure"
)
if
stdout
.
endswith
(
"
%
s
\r\n
%
s"
%
(
incorrect_password
,
prompt
)):
raise
errors
.
AnsibleError
(
'Incorrect su password'
)
if
p
.
stdout
in
rfd
:
if
p
.
stdout
in
rfd
:
dat
=
os
.
read
(
p
.
stdout
.
fileno
(),
9000
)
dat
=
os
.
read
(
p
.
stdout
.
fileno
(),
9000
)
...
...
lib/ansible/utils/__init__.py
View file @
da136dbe
...
@@ -645,6 +645,8 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
...
@@ -645,6 +645,8 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
help
=
'use this file to authenticate the connection'
)
help
=
'use this file to authenticate the connection'
)
parser
.
add_option
(
'-K'
,
'--ask-sudo-pass'
,
default
=
False
,
dest
=
'ask_sudo_pass'
,
action
=
'store_true'
,
parser
.
add_option
(
'-K'
,
'--ask-sudo-pass'
,
default
=
False
,
dest
=
'ask_sudo_pass'
,
action
=
'store_true'
,
help
=
'ask for sudo password'
)
help
=
'ask for sudo password'
)
parser
.
add_option
(
'--ask-su-pass'
,
default
=
False
,
dest
=
'ask_su_pass'
,
action
=
'store_true'
,
help
=
'ask for su password'
)
parser
.
add_option
(
'--list-hosts'
,
dest
=
'listhosts'
,
action
=
'store_true'
,
parser
.
add_option
(
'--list-hosts'
,
dest
=
'listhosts'
,
action
=
'store_true'
,
help
=
'outputs a list of matching hosts; does not execute anything else'
)
help
=
'outputs a list of matching hosts; does not execute anything else'
)
parser
.
add_option
(
'-M'
,
'--module-path'
,
dest
=
'module_path'
,
parser
.
add_option
(
'-M'
,
'--module-path'
,
dest
=
'module_path'
,
...
@@ -668,11 +670,15 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
...
@@ -668,11 +670,15 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
if
runas_opts
:
if
runas_opts
:
parser
.
add_option
(
"-s"
,
"--sudo"
,
default
=
constants
.
DEFAULT_SUDO
,
action
=
"store_true"
,
parser
.
add_option
(
"-s"
,
"--sudo"
,
default
=
constants
.
DEFAULT_SUDO
,
action
=
"store_true"
,
dest
=
'sudo'
,
help
=
"run operations with sudo (nopasswd)"
)
dest
=
'sudo'
,
help
=
"run operations with sudo (nopasswd)"
)
parser
.
add_option
(
'-U'
,
'--sudo-user'
,
dest
=
'sudo_user'
,
help
=
'desired sudo user (default=root)'
,
parser
.
add_option
(
'-U'
,
'--sudo-user'
,
dest
=
'sudo_user'
,
default
=
None
,
default
=
None
)
# Can't default to root because we need to detect when this option was given
help
=
'desired sudo user (default=root)'
)
# Can't default to root because we need to detect when this option was given
parser
.
add_option
(
'-u'
,
'--user'
,
default
=
constants
.
DEFAULT_REMOTE_USER
,
parser
.
add_option
(
'-u'
,
'--user'
,
default
=
constants
.
DEFAULT_REMOTE_USER
,
dest
=
'remote_user'
,
dest
=
'remote_user'
,
help
=
'connect as this user (default=
%
s)'
%
constants
.
DEFAULT_REMOTE_USER
)
help
=
'connect as this user (default=
%
s)'
%
constants
.
DEFAULT_REMOTE_USER
)
parser
.
add_option
(
'-S'
,
'--su'
,
default
=
constants
.
DEFAULT_SU
,
action
=
'store_true'
,
help
=
'run operations with su'
)
parser
.
add_option
(
'-R'
,
'--su-user'
,
help
=
'run operations with su as this '
'user (default=
%
s)'
%
constants
.
DEFAULT_SU_USER
)
if
connect_opts
:
if
connect_opts
:
parser
.
add_option
(
'-c'
,
'--connection'
,
dest
=
'connection'
,
parser
.
add_option
(
'-c'
,
'--connection'
,
dest
=
'connection'
,
...
@@ -699,10 +705,12 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
...
@@ -699,10 +705,12 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
return
parser
return
parser
def
ask_passwords
(
ask_pass
=
False
,
ask_sudo_pass
=
False
):
def
ask_passwords
(
ask_pass
=
False
,
ask_sudo_pass
=
False
,
ask_su_pass
=
False
):
sshpass
=
None
sshpass
=
None
sudopass
=
None
sudopass
=
None
su_pass
=
None
sudo_prompt
=
"sudo password: "
sudo_prompt
=
"sudo password: "
su_prompt
=
"su password: "
if
ask_pass
:
if
ask_pass
:
sshpass
=
getpass
.
getpass
(
prompt
=
"SSH password: "
)
sshpass
=
getpass
.
getpass
(
prompt
=
"SSH password: "
)
...
@@ -713,7 +721,10 @@ def ask_passwords(ask_pass=False, ask_sudo_pass=False):
...
@@ -713,7 +721,10 @@ def ask_passwords(ask_pass=False, ask_sudo_pass=False):
if
ask_pass
and
sudopass
==
''
:
if
ask_pass
and
sudopass
==
''
:
sudopass
=
sshpass
sudopass
=
sshpass
return
(
sshpass
,
sudopass
)
if
ask_su_pass
:
su_pass
=
getpass
.
getpass
(
prompt
=
su_prompt
)
return
(
sshpass
,
sudopass
,
su_pass
)
def
do_encrypt
(
result
,
encrypt
,
salt_size
=
None
,
salt
=
None
):
def
do_encrypt
(
result
,
encrypt
,
salt_size
=
None
,
salt
=
None
):
if
PASSLIB_AVAILABLE
:
if
PASSLIB_AVAILABLE
:
...
@@ -786,6 +797,21 @@ def make_sudo_cmd(sudo_user, executable, cmd):
...
@@ -786,6 +797,21 @@ def make_sudo_cmd(sudo_user, executable, cmd):
prompt
,
sudo_user
,
executable
or
'$SHELL'
,
pipes
.
quote
(
'echo
%
s;
%
s'
%
(
success_key
,
cmd
)))
prompt
,
sudo_user
,
executable
or
'$SHELL'
,
pipes
.
quote
(
'echo
%
s;
%
s'
%
(
success_key
,
cmd
)))
return
(
'/bin/sh -c '
+
pipes
.
quote
(
sudocmd
),
prompt
,
success_key
)
return
(
'/bin/sh -c '
+
pipes
.
quote
(
sudocmd
),
prompt
,
success_key
)
def
make_su_cmd
(
su_user
,
executable
,
cmd
):
"""
Helper function for connection plugins to create direct su commands
"""
# TODO: work on this function
randbits
=
''
.
join
(
chr
(
random
.
randint
(
ord
(
'a'
),
ord
(
'z'
)))
for
x
in
xrange
(
32
))
prompt
=
'assword: '
success_key
=
'SUDO-SUCCESS-
%
s'
%
randbits
sudocmd
=
'
%
s
%
s
%
s
%
s -c
%
s'
%
(
C
.
DEFAULT_SU_EXE
,
C
.
DEFAULT_SU_FLAGS
,
su_user
,
executable
or
'$SHELL'
,
pipes
.
quote
(
'echo
%
s;
%
s'
%
(
success_key
,
cmd
))
)
return
(
'/bin/sh -c '
+
pipes
.
quote
(
sudocmd
),
prompt
,
success_key
)
_TO_UNICODE_TYPES
=
(
unicode
,
type
(
None
))
_TO_UNICODE_TYPES
=
(
unicode
,
type
(
None
))
def
to_unicode
(
value
):
def
to_unicode
(
value
):
...
...
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