Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
c234b5b2
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c234b5b2
编写于
3月 06, 2017
作者:
baltery
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update AdHocRunner
上级
eb5a9dd2
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
61 addition
and
476 deletion
+61
-476
apps/ops/models/task.py
apps/ops/models/task.py
+12
-38
apps/ops/utils/ansible_api.py
apps/ops/utils/ansible_api.py
+0
-404
apps/ops/utils/callback.py
apps/ops/utils/callback.py
+4
-1
apps/ops/utils/runner.py
apps/ops/utils/runner.py
+45
-33
未找到文件。
apps/ops/models/task.py
浏览文件 @
c234b5b2
...
...
@@ -10,49 +10,23 @@ from ops.models import TaskRecord
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
__all__
=
[
"Task"
,
"SubTask"
]
logger
=
logging
.
getLogger
(
__name__
)
__all__
=
[
"Task"
]
class
Task
(
models
.
Model
):
record
=
models
.
OneToOneField
(
TaskRecord
)
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
is_gather_facts
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Is Gather Ansible Facts'
))
assets
=
models
.
ManyToManyField
(
Asset
,
related_name
=
'tasks'
)
"""
Ansible 的Task
"""
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Task name'
))
module_name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Task module'
))
module_args
=
models
.
CharField
(
max_length
=
512
,
blank
=
True
,
verbose_name
=
_
(
"Module args"
))
def
__unicode__
(
self
):
return
"%s"
%
self
.
name
@
property
def
ansible_assets
(
self
):
return
[]
def
run
(
self
):
from
ops.utils.ansible_api
import
ADHocRunner
,
Options
conf
=
Options
()
gather_facts
=
"yes"
if
self
.
is_gather_facts
else
"no"
play_source
=
{
"name"
:
"Ansible Play"
,
"hosts"
:
"default"
,
"gather_facts"
:
gather_facts
,
"tasks"
:
[
dict
(
action
=
dict
(
module
=
'ping'
)),
]
}
hoc
=
ADHocRunner
(
conf
,
play_source
,
*
self
.
ansible_assets
)
uuid
=
"tasker-"
+
uuid4
().
hex
ext_code
,
result
=
hoc
.
run
(
"test_task"
,
uuid
)
print
(
ext_code
)
print
(
result
)
class
SubTask
(
models
.
Model
):
task
=
models
.
ForeignKey
(
Task
,
related_name
=
'sub_tasks'
,
verbose_name
=
_
(
'Ansible Task'
))
module_name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Ansible Module Name'
))
module_args
=
models
.
CharField
(
max_length
=
512
,
blank
=
True
,
verbose_name
=
_
(
"Ansible Module Args"
))
register
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Ansible Task Register'
))
def
__unicode__
(
self
):
return
"%s %s"
%
(
self
.
module_name
,
self
.
module_args
)
class
Play
(
models
.
Model
):
"""
Playbook 模板, 定义好Template后生成 Playbook
"""
apps/ops/utils/ansible_api.py
已删除
100644 → 0
浏览文件 @
eb5a9dd2
# ~*~ coding: utf-8 ~*~
# from __future__ import unicode_literals, print_function
import
os
import
logging
from
collections
import
namedtuple
from
ansible.executor.task_queue_manager
import
TaskQueueManager
from
ansible.vars
import
VariableManager
from
ansible.parsing.dataloader
import
DataLoader
from
ansible.executor.playbook_executor
import
PlaybookExecutor
from
ansible.playbook.play
import
Play
from
ansible.plugins.callback
import
CallbackBase
import
ansible.constants
as
C
from
ansible.utils.vars
import
load_extra_vars
from
ansible.utils.vars
import
load_options_vars
from
.inventory
import
JMSInventory
from
common.utils
import
get_logger
__all__
=
[
"ADHocRunner"
,
"Options"
]
C
.
HOST_KEY_CHECKING
=
False
logger
=
get_logger
(
__name__
)
class
AnsibleError
(
StandardError
):
pass
class
AdHocResultCallback
(
CallbackBase
):
"""
Custom Callback
"""
def
__init__
(
self
,
display
=
None
):
self
.
result_q
=
dict
(
contacted
=
{},
dark
=
{})
super
(
AdHocResultCallback
,
self
).
__init__
(
display
)
def
gather_result
(
self
,
n
,
res
):
self
.
result_q
[
n
].
update
({
res
.
_host
.
name
:
res
.
_result
})
def
v2_runner_on_ok
(
self
,
result
):
self
.
gather_result
(
"contacted"
,
result
)
def
v2_runner_on_failed
(
self
,
result
,
ignore_errors
=
False
):
self
.
gather_result
(
"dark"
,
result
)
def
v2_runner_on_unreachable
(
self
,
result
):
self
.
gather_result
(
"dark"
,
result
)
def
v2_runner_on_skipped
(
self
,
result
):
self
.
gather_result
(
"dark"
,
result
)
def
v2_playbook_on_task_start
(
self
,
task
,
is_conditional
):
pass
def
v2_playbook_on_play_start
(
self
,
play
):
pass
class
PlaybookResultCallBack
(
CallbackBase
):
"""
Custom callback model for handlering the output data of
execute playbook file,
Base on the build-in callback plugins of ansible which named `json`.
"""
CALLBACK_VERSION
=
2.0
CALLBACK_TYPE
=
'stdout'
CALLBACK_NAME
=
'Dict'
def
__init__
(
self
,
display
=
None
):
super
(
PlaybookResultCallBack
,
self
).
__init__
(
display
)
self
.
results
=
[]
self
.
output
=
""
self
.
item_results
=
{}
# {"host": []}
def
_new_play
(
self
,
play
):
return
{
'play'
:
{
'name'
:
play
.
name
,
'id'
:
str
(
play
.
_uuid
)
},
'tasks'
:
[]
}
def
_new_task
(
self
,
task
):
return
{
'task'
:
{
'name'
:
task
.
get_name
(),
},
'hosts'
:
{}
}
def
v2_playbook_on_no_hosts_matched
(
self
):
self
.
output
=
"skipping: No match hosts."
def
v2_playbook_on_no_hosts_remaining
(
self
):
pass
def
v2_playbook_on_task_start
(
self
,
task
,
is_conditional
):
self
.
results
[
-
1
][
'tasks'
].
append
(
self
.
_new_task
(
task
))
def
v2_playbook_on_play_start
(
self
,
play
):
self
.
results
.
append
(
self
.
_new_play
(
play
))
def
v2_playbook_on_stats
(
self
,
stats
):
hosts
=
sorted
(
stats
.
processed
.
keys
())
summary
=
{}
for
h
in
hosts
:
s
=
stats
.
summarize
(
h
)
summary
[
h
]
=
s
if
self
.
output
:
pass
else
:
self
.
output
=
{
'plays'
:
self
.
results
,
'stats'
:
summary
}
def
gather_result
(
self
,
res
):
if
res
.
_task
.
loop
and
"results"
in
res
.
_result
and
res
.
_host
.
name
in
self
.
item_results
:
res
.
_result
.
update
({
"results"
:
self
.
item_results
[
res
.
_host
.
name
]})
del
self
.
item_results
[
res
.
_host
.
name
]
self
.
results
[
-
1
][
'tasks'
][
-
1
][
'hosts'
][
res
.
_host
.
name
]
=
res
.
_result
def
v2_runner_on_ok
(
self
,
res
,
**
kwargs
):
if
"ansible_facts"
in
res
.
_result
:
del
res
.
_result
[
"ansible_facts"
]
self
.
gather_result
(
res
)
def
v2_runner_on_failed
(
self
,
res
,
**
kwargs
):
self
.
gather_result
(
res
)
def
v2_runner_on_unreachable
(
self
,
res
,
**
kwargs
):
self
.
gather_result
(
res
)
def
v2_runner_on_skipped
(
self
,
res
,
**
kwargs
):
self
.
gather_result
(
res
)
def
gather_item_result
(
self
,
res
):
self
.
item_results
.
setdefault
(
res
.
_host
.
name
,
[]).
append
(
res
.
_result
)
def
v2_runner_item_on_ok
(
self
,
res
):
self
.
gather_item_result
(
res
)
def
v2_runner_item_on_failed
(
self
,
res
):
self
.
gather_item_result
(
res
)
def
v2_runner_item_on_skipped
(
self
,
res
):
self
.
gather_item_result
(
res
)
class
PlayBookRunner
(
object
):
"""
用于执行AnsiblePlaybook的接口.简化Playbook对象的使用.
"""
Options
=
namedtuple
(
'Options'
,
[
'listtags'
,
'listtasks'
,
'listhosts'
,
'syntax'
,
'connection'
,
'module_path'
,
'forks'
,
'remote_user'
,
'private_key_file'
,
'timeout'
,
'ssh_common_args'
,
'ssh_extra_args'
,
'sftp_extra_args'
,
'scp_extra_args'
,
'become'
,
'become_method'
,
'become_user'
,
'verbosity'
,
'check'
,
'extra_vars'
])
def
__init__
(
self
,
hosts
=
None
,
playbook_path
=
None
,
forks
=
C
.
DEFAULT_FORKS
,
listtags
=
False
,
listtasks
=
False
,
listhosts
=
False
,
syntax
=
False
,
module_path
=
None
,
remote_user
=
'root'
,
timeout
=
C
.
DEFAULT_TIMEOUT
,
ssh_common_args
=
None
,
ssh_extra_args
=
None
,
sftp_extra_args
=
None
,
scp_extra_args
=
None
,
become
=
True
,
become_method
=
None
,
become_user
=
"root"
,
verbosity
=
None
,
extra_vars
=
None
,
connection_type
=
"ssh"
,
passwords
=
None
,
private_key_file
=
None
,
check
=
False
):
C
.
RETRY_FILES_ENABLED
=
False
self
.
callbackmodule
=
PlaybookResultCallBack
()
if
playbook_path
is
None
or
not
os
.
path
.
exists
(
playbook_path
):
raise
AnsibleError
(
"Not Found the playbook file: %s."
%
playbook_path
)
self
.
playbook_path
=
playbook_path
self
.
loader
=
DataLoader
()
self
.
variable_manager
=
VariableManager
()
self
.
passwords
=
passwords
or
{}
self
.
inventory
=
JMSInventory
(
hosts
)
self
.
options
=
self
.
Options
(
listtags
=
listtags
,
listtasks
=
listtasks
,
listhosts
=
listhosts
,
syntax
=
syntax
,
timeout
=
timeout
,
connection
=
connection_type
,
module_path
=
module_path
,
forks
=
forks
,
remote_user
=
remote_user
,
private_key_file
=
private_key_file
,
ssh_common_args
=
ssh_common_args
or
""
,
ssh_extra_args
=
ssh_extra_args
or
""
,
sftp_extra_args
=
sftp_extra_args
,
scp_extra_args
=
scp_extra_args
,
become
=
become
,
become_method
=
become_method
,
become_user
=
become_user
,
verbosity
=
verbosity
,
extra_vars
=
extra_vars
or
[],
check
=
check
)
self
.
variable_manager
.
extra_vars
=
load_extra_vars
(
loader
=
self
.
loader
,
options
=
self
.
options
)
self
.
variable_manager
.
options_vars
=
load_options_vars
(
self
.
options
)
self
.
variable_manager
.
set_inventory
(
self
.
inventory
)
# 初始化playbook的executor
self
.
runner
=
PlaybookExecutor
(
playbooks
=
[
self
.
playbook_path
],
inventory
=
self
.
inventory
,
variable_manager
=
self
.
variable_manager
,
loader
=
self
.
loader
,
options
=
self
.
options
,
passwords
=
self
.
passwords
)
if
self
.
runner
.
_tqm
:
self
.
runner
.
_tqm
.
_stdout_callback
=
self
.
callbackmodule
def
run
(
self
):
if
not
self
.
inventory
.
list_hosts
(
'all'
):
raise
AnsibleError
(
'Inventory is empty'
)
self
.
runner
.
run
()
self
.
runner
.
_tqm
.
cleanup
()
return
self
.
callbackmodule
.
output
class
ADHocRunner
(
object
):
"""
ADHoc接口
"""
Options
=
namedtuple
(
"Options"
,
[
'connection'
,
'module_path'
,
'private_key_file'
,
"remote_user"
,
'timeout'
,
'forks'
,
'become'
,
'become_method'
,
'become_user'
,
'check'
,
'extra_vars'
,
]
)
def
__init__
(
self
,
hosts
=
C
.
DEFAULT_HOST_LIST
,
task_name
=
'Ansible Ad-hoc'
,
module_name
=
C
.
DEFAULT_MODULE_NAME
,
# * command
module_args
=
C
.
DEFAULT_MODULE_ARGS
,
# * 'cmd args'
forks
=
C
.
DEFAULT_FORKS
,
# 5
timeout
=
C
.
DEFAULT_TIMEOUT
,
# SSH timeout = 10s
pattern
=
"all"
,
# all
remote_user
=
C
.
DEFAULT_REMOTE_USER
,
# root
module_path
=
None
,
# dirs of custome modules
connection_type
=
"smart"
,
become
=
None
,
become_method
=
None
,
become_user
=
None
,
check
=
False
,
passwords
=
None
,
extra_vars
=
None
,
private_key_file
=
None
,
gather_facts
=
'no'
):
self
.
pattern
=
pattern
self
.
variable_manager
=
VariableManager
()
self
.
loader
=
DataLoader
()
self
.
module_name
=
module_name
self
.
module_args
=
module_args
self
.
check_module_args
()
self
.
gather_facts
=
gather_facts
self
.
results_callback
=
AdHocResultCallback
()
self
.
options
=
self
.
Options
(
connection
=
connection_type
,
timeout
=
timeout
,
module_path
=
module_path
,
forks
=
forks
,
become
=
become
,
become_method
=
become_method
,
become_user
=
become_user
,
check
=
check
,
remote_user
=
remote_user
,
extra_vars
=
extra_vars
or
[],
private_key_file
=
private_key_file
,
)
self
.
variable_manager
.
extra_vars
=
load_extra_vars
(
self
.
loader
,
options
=
self
.
options
)
self
.
variable_manager
.
options_vars
=
load_options_vars
(
self
.
options
)
self
.
passwords
=
passwords
or
{}
self
.
inventory
=
JMSInventory
(
hosts
)
self
.
variable_manager
.
set_inventory
(
self
.
inventory
)
self
.
play_source
=
dict
(
name
=
task_name
,
hosts
=
self
.
pattern
,
gather_facts
=
self
.
gather_facts
,
tasks
=
[
dict
(
action
=
dict
(
module
=
self
.
module_name
,
args
=
self
.
module_args
,
)
)
]
)
self
.
play
=
Play
().
load
(
self
.
play_source
,
variable_manager
=
self
.
variable_manager
,
loader
=
self
.
loader
,
)
self
.
runner
=
TaskQueueManager
(
inventory
=
self
.
inventory
,
variable_manager
=
self
.
variable_manager
,
loader
=
self
.
loader
,
options
=
self
.
options
,
passwords
=
self
.
passwords
,
stdout_callback
=
self
.
results_callback
,
)
def
check_module_args
(
self
):
if
self
.
module_name
in
C
.
MODULE_REQUIRE_ARGS
and
not
self
.
module_args
:
err
=
"No argument passed to '%s' module."
%
self
.
module_name
raise
AnsibleError
(
err
)
def
run
(
self
):
if
not
self
.
inventory
.
list_hosts
(
"all"
):
raise
AnsibleError
(
"Inventory is empty."
)
if
not
self
.
inventory
.
list_hosts
(
self
.
pattern
):
raise
AnsibleError
(
"pattern: %s dose not match any hosts."
%
self
.
pattern
)
try
:
self
.
runner
.
run
(
self
.
play
)
except
Exception
as
e
:
logger
.
warning
(
e
)
else
:
logger
.
debug
(
self
.
results_callback
.
result_q
)
return
self
.
results_callback
.
result_q
finally
:
if
self
.
runner
:
self
.
runner
.
cleanup
()
if
self
.
loader
:
self
.
loader
.
cleanup_all_tmp_files
()
def
clean_result
(
self
):
failed
=
self
.
results_callback
.
result_q
[
'dark'
].
keys
()
success
=
self
.
results_callback
.
result_q
[
'contacted'
].
keys
()
return
{
'failed'
:
failed
,
'success'
:
success
}
def
test_run
():
assets
=
[
{
"hostname"
:
"192.168.152.129"
,
"ip"
:
"192.168.152.129"
,
"port"
:
22
,
"username"
:
"root"
,
"password"
:
"redhat"
,
},
]
hoc
=
ADHocRunner
(
module_name
=
'shell'
,
module_args
=
'ls'
,
hosts
=
assets
)
ret
=
hoc
.
run
()
print
(
ret
)
play
=
PlayBookRunner
(
assets
,
playbook_path
=
'/tmp/some.yml'
)
"""
# /tmp/some.yml
---
- name: Test the plabybook API.
hosts: all
remote_user: root
gather_facts: yes
tasks:
- name: exec uptime
shell: uptime
"""
play
.
run
()
if
__name__
==
"__main__"
:
test_run
()
apps/ops/utils/callback.py
浏览文件 @
c234b5b2
...
...
@@ -12,7 +12,10 @@ class AdHocResultCallback(CallbackBase):
super
(
AdHocResultCallback
,
self
).
__init__
(
display
)
def
gather_result
(
self
,
n
,
res
):
self
.
result_q
[
n
].
update
({
res
.
_host
.
name
:
res
.
_result
})
if
res
.
_host
.
name
in
self
.
result_q
[
n
]:
self
.
result_q
[
n
][
res
.
_host
.
name
].
append
(
res
.
_result
)
else
:
self
.
result_q
[
n
][
res
.
_host
.
name
]
=
[
res
.
_result
]
def
v2_runner_on_ok
(
self
,
result
):
self
.
gather_result
(
"contacted"
,
result
)
...
...
apps/ops/utils/runner.py
浏览文件 @
c234b5b2
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
# from __future__ import unicode_literals, print_function
import
os
from
collections
import
namedtuple
import
sys
from
collections
import
namedtuple
,
defaultdict
from
ansible.executor.task_queue_manager
import
TaskQueueManager
from
ansible.vars
import
VariableManager
from
ansible.parsing.dataloader
import
DataLoader
from
ansible.executor.playbook_executor
import
PlaybookExecutor
from
ansible.playbook.play
import
Play
from
ansible.plugins.callback
import
CallbackBase
import
ansible.constants
as
C
from
ansible.utils.vars
import
load_extra_vars
from
ansible.utils.vars
import
load_options_vars
...
...
@@ -128,7 +125,7 @@ class PlayBookRunner(object):
return
self
.
callbackmodule
.
output
class
A
D
HocRunner
(
object
):
class
A
d
HocRunner
(
object
):
"""
ADHoc接口
"""
...
...
@@ -141,12 +138,8 @@ class ADHocRunner(object):
def
__init__
(
self
,
hosts
=
C
.
DEFAULT_HOST_LIST
,
task_name
=
'Ansible Ad-hoc'
,
module_name
=
C
.
DEFAULT_MODULE_NAME
,
# * command
module_args
=
C
.
DEFAULT_MODULE_ARGS
,
# * 'cmd args'
forks
=
C
.
DEFAULT_FORKS
,
# 5
timeout
=
C
.
DEFAULT_TIMEOUT
,
# SSH timeout = 10s
pattern
=
"all"
,
# all
remote_user
=
C
.
DEFAULT_REMOTE_USER
,
# root
module_path
=
None
,
# dirs of custome modules
connection_type
=
"smart"
,
...
...
@@ -159,12 +152,9 @@ class ADHocRunner(object):
private_key_file
=
None
,
gather_facts
=
'no'
):
self
.
pattern
=
pattern
self
.
pattern
=
''
self
.
variable_manager
=
VariableManager
()
self
.
loader
=
DataLoader
()
self
.
module_name
=
module_name
self
.
module_args
=
module_args
self
.
check_module_args
()
self
.
gather_facts
=
gather_facts
self
.
results_callback
=
AdHocResultCallback
()
self
.
options
=
self
.
Options
(
...
...
@@ -186,18 +176,41 @@ class ADHocRunner(object):
self
.
passwords
=
passwords
or
{}
self
.
inventory
=
JMSInventory
(
hosts
)
self
.
variable_manager
.
set_inventory
(
self
.
inventory
)
self
.
tasks
=
[]
self
.
play_source
=
None
self
.
play
=
None
self
.
runner
=
None
@
staticmethod
def
check_module_args
(
module_name
,
module_args
=
''
):
if
module_name
in
C
.
MODULE_REQUIRE_ARGS
and
not
module_args
:
err
=
"No argument passed to '%s' module."
%
module_name
print
(
err
)
return
False
return
True
def
run
(
self
,
task_tuple
,
pattern
=
'all'
,
task_name
=
'Ansible Ad-hoc'
):
"""
:param task_tuple: (('shell', 'ls'), ('ping', ''))
:param pattern:
:param task_name:
:return:
"""
for
module
,
args
in
task_tuple
:
if
not
self
.
check_module_args
(
module
,
args
):
return
self
.
tasks
.
append
(
dict
(
action
=
dict
(
module
=
module
,
args
=
args
,
))
)
self
.
play_source
=
dict
(
name
=
task_name
,
hosts
=
self
.
pattern
,
hosts
=
pattern
,
gather_facts
=
self
.
gather_facts
,
tasks
=
[
dict
(
action
=
dict
(
module
=
self
.
module_name
,
args
=
self
.
module_args
,
)
)
]
tasks
=
self
.
tasks
)
self
.
play
=
Play
().
load
(
...
...
@@ -215,12 +228,6 @@ class ADHocRunner(object):
stdout_callback
=
self
.
results_callback
,
)
def
check_module_args
(
self
):
if
self
.
module_name
in
C
.
MODULE_REQUIRE_ARGS
and
not
self
.
module_args
:
err
=
"No argument passed to '%s' module."
%
self
.
module_name
raise
AnsibleError
(
err
)
def
run
(
self
):
if
not
self
.
inventory
.
list_hosts
(
"all"
):
raise
AnsibleError
(
"Inventory is empty."
)
...
...
@@ -242,9 +249,13 @@ class ADHocRunner(object):
self
.
loader
.
cleanup_all_tmp_files
()
def
clean_result
(
self
):
failed
=
self
.
results_callback
.
result_q
[
'dark'
].
keys
()
success
=
self
.
results_callback
.
result_q
[
'contacted'
].
keys
()
return
{
'failed'
:
failed
,
'success'
:
success
}
result
=
defaultdict
(
dict
)
for
host
,
msgs
in
self
.
results_callback
.
result_q
[
'contacted'
].
items
():
result
[
host
][
'success'
]
=
len
(
msgs
)
for
host
,
msgs
in
self
.
results_callback
.
result_q
[
'dark'
].
items
():
result
[
host
][
'failed'
]
=
len
(
msgs
)
return
result
def
test_run
():
...
...
@@ -257,8 +268,9 @@ def test_run():
"password"
:
"redhat"
,
},
]
hoc
=
ADHocRunner
(
module_name
=
'shell'
,
module_args
=
'ls'
,
hosts
=
assets
)
ret
=
hoc
.
run
()
task_tuple
=
((
'shell'
,
'ls'
),
(
'ping'
,
''
))
hoc
=
AdHocRunner
(
hosts
=
assets
)
ret
=
hoc
.
run
(
task_tuple
)
print
(
ret
)
play
=
PlayBookRunner
(
assets
,
playbook_path
=
'/tmp/some.yml'
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录