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):
if
len
(
args
)
==
0
or
len
(
args
)
>
1
:
parser
.
print_help
()
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
)
# ----------------------------------------------
...
...
@@ -96,31 +104,46 @@ class Cli(object):
sshpass
=
None
sudopass
=
None
su_pass
=
None
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
# Never ask for an SSH password when we run with local connection
if
options
.
connection
==
"local"
:
options
.
ask_pass
=
False
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
)
if
options
.
sudo_user
or
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
)
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_user
=
options
.
sudo_user
or
C
.
DEFAULT_SUDO_USER
options
.
su_user
=
options
.
su_user
or
C
.
DEFAULT_SU_USER
if
options
.
tree
:
utils
.
prepare_writeable_dir
(
options
.
tree
)
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
,
remote_user
=
options
.
remote_user
,
remote_pass
=
sshpass
,
inventory
=
inventory_manager
,
timeout
=
options
.
timeout
,
remote_user
=
options
.
remote_user
,
remote_pass
=
sshpass
,
inventory
=
inventory_manager
,
timeout
=
options
.
timeout
,
private_key_file
=
options
.
private_key_file
,
forks
=
options
.
forks
,
pattern
=
pattern
,
callbacks
=
self
.
callbacks
,
sudo
=
options
.
sudo
,
sudo_pass
=
sudopass
,
sudo_user
=
options
.
sudo_user
,
transport
=
options
.
connection
,
subset
=
options
.
subset
,
callbacks
=
self
.
callbacks
,
sudo
=
options
.
sudo
,
sudo_pass
=
sudopass
,
sudo_user
=
options
.
sudo_user
,
transport
=
options
.
connection
,
subset
=
options
.
subset
,
check
=
options
.
check
,
diff
=
options
.
check
diff
=
options
.
check
,
su
=
options
.
su
,
su_pass
=
su_pass
,
su_user
=
options
.
su_user
)
if
options
.
seconds
:
...
...
bin/ansible-playbook
View file @
da136dbe
...
...
@@ -83,6 +83,13 @@ def main(args):
parser
.
print_help
(
file
=
sys
.
stderr
)
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
.
subset
(
options
.
subset
)
if
len
(
inventory
.
list_hosts
())
==
0
:
...
...
@@ -90,14 +97,18 @@ def main(args):
sshpass
=
None
sudopass
=
None
su_pass
=
None
if
not
options
.
listhosts
and
not
options
.
syntax
and
not
options
.
listtasks
:
options
.
ask_pass
=
options
.
ask_pass
or
C
.
DEFAULT_ASK_PASS
# Never ask for an SSH password when we run with local connection
if
options
.
connection
==
"local"
:
options
.
ask_pass
=
False
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
.
su_user
=
options
.
su_user
or
C
.
DEFAULT_SU_USER
extra_vars
=
{}
for
extra_vars_opt
in
options
.
extra_vars
:
...
...
@@ -156,7 +167,10 @@ def main(args):
only_tags
=
only_tags
,
skip_tags
=
skip_tags
,
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
:
...
...
lib/ansible/constants.py
View file @
da136dbe
...
...
@@ -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_JINJA2_EXTENSIONS
=
get_config
(
p
,
DEFAULTS
,
'jinja2_extensions'
,
'ANSIBLE_JINJA2_EXTENSIONS'
,
None
)
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_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 + ".,:-_"
DEFAULT_SUDO_PASS
=
None
DEFAULT_REMOTE_PASS
=
None
DEFAULT_SUBSET
=
None
DEFAULT_SU_PASS
=
None
lib/ansible/playbook/__init__.py
View file @
da136dbe
...
...
@@ -68,7 +68,11 @@ class PlayBook(object):
inventory
=
None
,
check
=
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
...
...
@@ -122,6 +126,9 @@ class PlayBook(object):
self
.
only_tags
=
only_tags
self
.
skip_tags
=
skip_tags
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
.
runner_callbacks
.
playbook
=
self
...
...
@@ -303,20 +310,39 @@ class PlayBook(object):
self
.
inventory
.
restrict_to
(
hosts
)
runner
=
ansible
.
runner
.
Runner
(
pattern
=
task
.
play
.
hosts
,
inventory
=
self
.
inventory
,
module_name
=
task
.
module_name
,
module_args
=
task
.
module_args
,
forks
=
self
.
forks
,
remote_pass
=
self
.
remote_pass
,
module_path
=
self
.
module_path
,
timeout
=
self
.
timeout
,
remote_user
=
task
.
remote_user
,
remote_port
=
task
.
play
.
remote_port
,
module_vars
=
task
.
module_vars
,
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
,
pattern
=
task
.
play
.
hosts
,
inventory
=
self
.
inventory
,
module_name
=
task
.
module_name
,
module_args
=
task
.
module_args
,
forks
=
self
.
forks
,
remote_pass
=
self
.
remote_pass
,
module_path
=
self
.
module_path
,
timeout
=
self
.
timeout
,
remote_user
=
task
.
remote_user
,
remote_port
=
task
.
play
.
remote_port
,
module_vars
=
task
.
module_vars
,
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
,
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
:
...
...
@@ -446,13 +472,30 @@ class PlayBook(object):
# push any variables down to the system
setup_results
=
ansible
.
runner
.
Runner
(
pattern
=
play
.
hosts
,
module_name
=
'setup'
,
module_args
=
{},
inventory
=
self
.
inventory
,
forks
=
self
.
forks
,
module_path
=
self
.
module_path
,
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
,
pattern
=
play
.
hosts
,
module_name
=
'setup'
,
module_args
=
{},
inventory
=
self
.
inventory
,
forks
=
self
.
forks
,
module_path
=
self
.
module_path
,
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
()
self
.
stats
.
compute
(
setup_results
,
setup
=
True
)
...
...
lib/ansible/playbook/play.py
View file @
da136dbe
...
...
@@ -34,7 +34,7 @@ class Play(object):
'handlers'
,
'remote_user'
,
'remote_port'
,
'included_roles'
,
'accelerate'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'sudo'
,
'sudo_user'
,
'transport'
,
'playbook'
,
'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
...
...
@@ -43,7 +43,8 @@ class Play(object):
'hosts'
,
'name'
,
'vars'
,
'vars_prompt'
,
'vars_files'
,
'tasks'
,
'handlers'
,
'remote_user'
,
'user'
,
'port'
,
'include'
,
'accelerate'
,
'accelerate_port'
,
'accelerate_ipv6'
,
'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):
self
.
accelerate_port
=
ds
.
get
(
'accelerate_port'
,
None
)
self
.
accelerate_ipv6
=
ds
.
get
(
'accelerate_ipv6'
,
False
)
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
[
'playbook_dir'
]
=
self
.
basedir
...
...
@@ -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 '''
results
=
[]
...
...
@@ -469,7 +473,7 @@ class Play(object):
if
'meta'
in
x
:
if
x
[
'meta'
]
==
'flush_handlers'
:
results
.
append
(
Task
(
self
,
x
))
results
.
append
(
Task
(
self
,
x
))
continue
task_vars
=
self
.
vars
.
copy
()
...
...
@@ -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
)
results
+=
loaded
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
)
else
:
raise
Exception
(
"unexpected task type"
)
...
...
lib/ansible/playbook/task.py
View file @
da136dbe
...
...
@@ -30,7 +30,8 @@ class Task(object):
'delegate_to'
,
'first_available_file'
,
'ignore_errors'
,
'local_action'
,
'transport'
,
'sudo'
,
'remote_user'
,
'sudo_user'
,
'sudo_pass'
,
'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
...
...
@@ -39,7 +40,8 @@ class Task(object):
'first_available_file'
,
'include'
,
'tags'
,
'register'
,
'ignore_errors'
,
'delegate_to'
,
'local_action'
,
'transport'
,
'remote_user'
,
'sudo'
,
'sudo_user'
,
'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
):
...
...
@@ -117,6 +119,7 @@ class Task(object):
self
.
tags
=
[
'all'
]
self
.
register
=
ds
.
get
(
'register'
,
None
)
self
.
sudo
=
utils
.
boolean
(
ds
.
get
(
'sudo'
,
play
.
sudo
))
self
.
su
=
utils
.
boolean
(
ds
.
get
(
'sudo'
,
play
.
su
))
self
.
environment
=
ds
.
get
(
'environment'
,
{})
self
.
role_name
=
role_name
...
...
@@ -142,13 +145,18 @@ class Task(object):
else
:
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
:
self
.
sudo_user
=
ds
.
get
(
'sudo_user'
,
play
.
sudo_user
)
self
.
sudo_pass
=
ds
.
get
(
'sudo_pass'
,
play
.
playbook
.
sudo_pass
)
el
se
:
self
.
su
do_user
=
None
self
.
su
do_pass
=
None
el
if
self
.
su
:
self
.
su
_user
=
ds
.
get
(
'su_user'
,
play
.
su_user
)
self
.
su
_pass
=
ds
.
get
(
'su_pass'
,
play
.
playbook
.
su_pass
)
# Both are defined
if
(
'action'
in
ds
)
and
(
'local_action'
in
ds
):
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):
accelerate
=
False
,
# use accelerated connection
accelerate_ipv6
=
False
,
# accelerated connection w/ IPv6
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
...
...
@@ -188,6 +191,9 @@ class Runner(object):
self
.
accelerate_ipv6
=
accelerate_ipv6
self
.
callbacks
.
runner
=
self
self
.
original_transport
=
self
.
transport
self
.
su
=
su
self
.
su_user
=
su_user
self
.
su_pass
=
su_pass
if
self
.
transport
==
'smart'
:
# if the transport is 'smart' see if SSH can support ControlPersist if not use paramiko
...
...
@@ -311,12 +317,13 @@ class Runner(object):
or
async_jid
is
not
None
or
not
conn
.
has_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
)
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
cmd_chmod
=
"chmod a+r
%
s"
%
remote_module_path
self
.
_low_level_exec_command
(
conn
,
cmd_chmod
,
tmp
,
sudoable
=
False
)
...
...
@@ -343,7 +350,7 @@ class Runner(object):
else
:
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
cmd_args_chmod
=
"chmod a+r
%
s"
%
argsfile
self
.
_low_level_exec_command
(
conn
,
cmd_args_chmod
,
tmp
,
sudoable
=
False
)
...
...
@@ -354,7 +361,7 @@ class Runner(object):
cmd
=
" "
.
join
([
str
(
x
)
for
x
in
[
remote_module_path
,
async_jid
,
async_limit
,
async_module
,
argsfile
]])
else
:
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
else
:
cmd
=
"
%
s"
%
(
remote_module_path
)
...
...
@@ -369,7 +376,7 @@ class Runner(object):
cmd
=
cmd
.
strip
()
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
cmd
=
cmd
+
"; rm -rf
%
s >/dev/null 2>&1"
%
tmp
...
...
@@ -379,10 +386,13 @@ class Runner(object):
# specified in the play, not the sudo_user
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
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
# have to clean up temp files as original user in a second step
cmd2
=
"rm -rf
%
s >/dev/null 2>&1"
%
tmp
...
...
@@ -613,6 +623,9 @@ class Runner(object):
actual_transport
=
inject
.
get
(
'ansible_connection'
,
self
.
transport
)
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
.
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
:
actual_private_key_file
=
os
.
path
.
expanduser
(
actual_private_key_file
)
...
...
@@ -798,7 +811,10 @@ class Runner(object):
if
tmp
.
find
(
"tmp"
)
!=
-
1
:
# tmp has already been created
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
# or we want to keep the files on the target system
return
True
...
...
@@ -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 '''
if
executable
is
None
:
executable
=
C
.
DEFAULT_EXECUTABLE
sudo_user
=
self
.
sudo_user
su_user
=
self
.
su_user
# compare connection user to sudo_user and disable if the same
if
hasattr
(
conn
,
'user'
):
if
conn
.
user
==
sudo_user
:
if
conn
.
user
==
sudo_user
or
conn
.
user
==
su_user
:
sudoable
=
False
rc
,
stdin
,
stdout
,
stderr
=
conn
.
exec_command
(
cmd
,
tmp
,
sudo_user
,
sudoable
=
sudoable
,
executable
=
executable
,
in_data
=
in_data
)
su
=
False
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
]:
out
=
''
.
join
(
stdout
.
readlines
())
...
...
@@ -881,11 +913,11 @@ class Runner(object):
basefile
=
'ansible-tmp-
%
s-
%
s'
%
(
time
.
time
(),
random
.
randint
(
0
,
2
**
48
))
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
)
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
+=
' && echo
%
s'
%
basetmp
...
...
lib/ansible/runner/connection_plugins/accelerate.py
View file @
da136dbe
...
...
@@ -159,9 +159,12 @@ class Connection(object):
except
socket
.
timeout
:
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 '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
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):
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 '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
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):
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 '''
if
in_data
:
...
...
@@ -76,9 +76,9 @@ class Connection(object):
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
(
"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. "
+
"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):
self
.
client
=
fc
.
Client
(
self
.
host
)
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 remote minion '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
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):
local_cmd
=
'
%
s "
%
s"
%
s'
%
(
self
.
jexec_cmd
,
self
.
jail
,
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 '''
if
su
or
su_user
:
raise
errors
.
AnsibleError
(
"Internal Error: this module does not support running commands via su"
)
if
in_data
:
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):
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 '''
# 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
:
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):
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 '''
bufsize
=
4096
...
...
@@ -188,7 +188,7 @@ class Connection(object):
msg
+=
":
%
s"
%
str
(
e
)
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
:
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
else
:
...
...
@@ -208,7 +208,7 @@ class Connection(object):
sudo_output
=
''
try
:
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
:
chunk
=
chan
.
recv
(
bufsize
)
if
not
chunk
:
...
...
@@ -220,7 +220,10 @@ class Connection(object):
'closed waiting for password prompt'
)
sudo_output
+=
chunk
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
:
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):
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 '''
if
in_data
:
...
...
@@ -191,7 +191,7 @@ class Connection(object):
msg
+=
":
%
s"
%
str
(
e
)
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
:
quoted_command
=
executable
+
' -c '
+
pipes
.
quote
(
cmd
)
else
:
...
...
@@ -206,12 +206,15 @@ class Connection(object):
chan
.
get_pty
(
term
=
os
.
getenv
(
'TERM'
,
'vt100'
),
width
=
int
(
os
.
getenv
(
'COLUMNS'
,
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
)
sudo_output
=
''
try
:
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
:
chunk
=
chan
.
recv
(
bufsize
)
if
not
chunk
:
...
...
@@ -223,7 +226,10 @@ class Connection(object):
'closed waiting for password prompt'
)
sudo_output
+=
chunk
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
:
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):
return
False
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 '''
ssh_cmd
=
self
.
_password_cmd
()
...
...
@@ -165,7 +165,10 @@ class Connection(object):
ssh_cmd
+=
[
'-6'
]
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
:
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
else
:
...
...
@@ -183,7 +186,7 @@ class Connection(object):
# the host to known hosts is not intermingled with multiprocess output.
fcntl
.
lockf
(
self
.
runner
.
process_lockfile
,
fcntl
.
LOCK_EX
)
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
# create process
if
in_data
:
# do not use pseudo-pty
...
...
@@ -206,7 +209,8 @@ class Connection(object):
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
# * NOPASSWD (tty & no-tty): detect success_key on stdout
# * without NOPASSWD:
...
...
@@ -225,7 +229,7 @@ class Connection(object):
if
p
.
stderr
in
rfd
:
chunk
=
p
.
stderr
.
read
()
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
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
...
...
@@ -237,16 +241,19 @@ class Connection(object):
if
p
.
stdout
in
rfd
:
chunk
=
p
.
stdout
.
read
()
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
if
not
rfd
:
# timeout. wrap up process communication
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
:
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
.
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
...
...
@@ -262,12 +269,18 @@ class Connection(object):
while
True
:
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
:
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
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
:
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):
return
False
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 '''
if
in_data
:
...
...
@@ -163,7 +163,10 @@ class Connection(object):
ssh_cmd
+=
[
'-6'
]
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
:
ssh_cmd
.
append
(
executable
+
' -c '
+
pipes
.
quote
(
cmd
))
else
:
...
...
@@ -183,7 +186,6 @@ class Connection(object):
fcntl
.
lockf
(
self
.
runner
.
output_lockfile
,
fcntl
.
LOCK_EX
)
try
:
# Make sure stdin is a proper (pseudo) pty to avoid: tcgetattr errors
master
,
slave
=
pty
.
openpty
()
...
...
@@ -198,7 +200,8 @@ class Connection(object):
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_GETFL
)
|
os
.
O_NONBLOCK
)
sudo_output
=
''
...
...
@@ -208,13 +211,17 @@ class Connection(object):
if
p
.
stdout
in
rfd
:
chunk
=
p
.
stdout
.
read
()
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
else
:
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
:
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
)
# We can't use p.communicate here because the ControlMaster may have stdout open as well
...
...
@@ -224,12 +231,18 @@ class Connection(object):
while
True
:
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
:
incorrect_password
=
gettext
.
dgettext
(
"sudo"
,
"Sorry, try again."
)
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
:
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,
help
=
'use this file to authenticate the connection'
)
parser
.
add_option
(
'-K'
,
'--ask-sudo-pass'
,
default
=
False
,
dest
=
'ask_sudo_pass'
,
action
=
'store_true'
,
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'
,
help
=
'outputs a list of matching hosts; does not execute anything else'
)
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,
if
runas_opts
:
parser
.
add_option
(
"-s"
,
"--sudo"
,
default
=
constants
.
DEFAULT_SUDO
,
action
=
"store_true"
,
dest
=
'sudo'
,
help
=
"run operations with sudo (nopasswd)"
)
parser
.
add_option
(
'-U'
,
'--sudo-user'
,
dest
=
'sudo_user'
,
help
=
'desired sudo user (default=root)'
,
default
=
None
)
# Can't default to root because we need to detect when this option was given
parser
.
add_option
(
'-U'
,
'--sudo-user'
,
dest
=
'sudo_user'
,
default
=
None
,
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
,
dest
=
'remote_user'
,
help
=
'connect as this user (default=
%
s)'
%
constants
.
DEFAULT_REMOTE_USER
)
dest
=
'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
:
parser
.
add_option
(
'-c'
,
'--connection'
,
dest
=
'connection'
,
...
...
@@ -699,10 +705,12 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
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
sudopass
=
None
su_pass
=
None
sudo_prompt
=
"sudo password: "
su_prompt
=
"su password: "
if
ask_pass
:
sshpass
=
getpass
.
getpass
(
prompt
=
"SSH password: "
)
...
...
@@ -713,7 +721,10 @@ def ask_passwords(ask_pass=False, ask_sudo_pass=False):
if
ask_pass
and
sudopass
==
''
:
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
):
if
PASSLIB_AVAILABLE
:
...
...
@@ -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
)))
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
))
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