用python api调用ansible playbook,报错:
TASK [mkdir ~/ansible_files/tools remote] **************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: '>' not supported between instances of 'NoneType' and 'int'
fatal: [10.229.0.58]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}
源代码如下:
#将server自动部署到10.10.23.228机器上
def remote_start_perf(hostfile='perf_server'):
try:
case_name = 'remote_start_perf'
case_info = 'remote_start_perf: start perf_server.py'
logging.info("basedir=%s",basedir)
host_source = [basedir + '/common/'+hostfile]
extra_vars = {'project_root': basedir,'playbook_dir': basedir + '/playbooks'}
pb_path = [basedir + '/playbooks/remote_start.yml']
logging.info("pb_path=%s",pb_path)
logging.info("playbook start, {}".format(case_info))
loader = DataLoader()
passwords = dict()
inventory = InventoryManager(loader=loader, sources=host_source)
# variable设置
variable_manager = VariableManager(loader=loader, inventory=inventory)
variable_manager._extra_vars = extra_vars
logging.info("extra_vars=%s", json.dumps(variable_manager.get_vars(), indent=4))
private_key_file = "~/.ssh/id_rsa"
ssh_args = '-o ProxyCommand="ssh [email protected] -W %h:%p" -o StrictHostKeyChecking=no'
# context参数设置
context.CLIARGS = ImmutableDict(connection='ssh', module_path=None, become=None, become_method=None, forks=5,start_at_task=None,become_user=None, check=False, diff=False, syntax=None,private_key_file=private_key_file, ssh_common_args=ssh_args,ansible_cfg=None)
logging.info("context.CLIARGS=%s", context.CLIARGS)
playbook_executor = PlaybookExecutor(pb_path, inventory, variable_manager, loader, passwords)
result = playbook_executor.run()
logging.info("playbook end,{} playbook result={}".format(case_name, result))
if result != 0:
raise RuntimeError('remote_start_perf play_book!=0,failed!')
# 检查一下服务是否running正常
url = 'https://ufgkhhyx.fn.bytedance.net/http/10.10.23.228:5014/'
logging.info("check url={}".format(url))
resp = requests.get(url)
if resp.status_code != 200:
raise RuntimeError('remote_start_perf play_book!=0,failed!')
else:
logging.info("check url finish, remote_start_perf success,server is running!")
except Exception as e:
logging.error("remote_start_perf has an Exception!")
logging.error(traceback.format_exc())
很奇怪,之前写的一直可以执行正确,更新了python2-->python3版本和ansible版本就报错了(之前是2.8.0,后来是2.8.10),但是用等同的ansible-playbook执行就没有错,执行命令如下:
ansible-playbook -i common/perf_server playbooks/remote_start.yml --extra-vars "project_root=/Users/luolan/go/src/code.byted.org/nss_perf" --ssh-common-args='-o ProxyCommand="ssh [email protected] -W %h:%p" -o StrictHostKeyChecking=no'
经过反复排查,发现是 以下这个代码里面没有传一个参数verbosity导致的,这个参数默认是0, 左右是用来显示错误的日志信息的。如果是3,就表示执行的时候加了-vvv,打印详细的日志信息。ansible的新版任务如果么有传这个参数,就是None, 但是它是int类型,所以会报上述的错,加上verbosity=3或者verbosity=0就可以了。
另外,python api调用ansible真的坑很多,虽然用起来能和python代码融合很方便,官方不开放维护这个api, 版本都不保证不向前兼容,所以千万别轻易改动ansible版本。
# context参数设置
context.CLIARGS = ImmutableDict(connection='ssh', module_path=None, become=None, become_method=None, forks=5,start_at_task=None,become_user=None, check=False, diff=False, syntax=None,private_key_file=private_key_file, ssh_common_args=ssh_args,ansible_cfg=None)
修改后变成:
# context参数设置 context.CLIARGS = ImmutableDict(connection='ssh', module_path=None, become=None, become_method=None, forks=5,start_at_task=None,become_user=None, check=False, diff=False, syntax=None, private_key_file=private_key_file, ssh_common_args=ssh_args,ansible_cfg=None,verbosity=3)