[英]How to make Fabric ignore offline hosts in the env.hosts list?
这与我之前的问题有关 ,但与之不同。
我有以下fabfile:
from fabric.api import *
host1 = '192.168.200.181'
offline_host2 = '192.168.200.199'
host3 = '192.168.200.183'
env.hosts = [host1, offline_host2, host3]
env.warn_only = True
def df_h():
with settings(warn_only=True):
run("df -h | grep sda3")
输出是:
[192.168.200.199] run: df -h | grep sda3
Fatal error: Low level socket error connecting to host 192.168.200.199: No route to host
Aborting.
执行到达脱机服务器后,无论env.hosts列表中的其他服务器如何,它都会立即中止。
我使用了env设置“warn_only = True”,但也许我使用它不正确。
如何修改此行为以便它只打印错误并继续执行?
从版本1.4开始,Fabric有一个--skip-bad-hosts
选项,可以从命令行设置,也可以在fab文件中设置变量。
env.skip_bad_hosts = True
该选项的文档位于: http : //docs.fabfile.org/en/latest/usage/fab.html#cmdoption--skip-bad-hosts
不要忘记也明确设置超时值。
根据warn_only上的Fabric文档 ,
env.warn_only
“指定在run
/sudo
/local
遇到错误条件时是否警告而不是中止。
这对于服务器关闭的情况没有帮助,因为在执行run
/ sudo
/ local
之前SSH尝试期间发生了故障。
一种解决方案是创建一个函数来检查每个服务器在执行任务之前是否已启动。 下面是我使用的代码。
from __future__ import print_function
from fabric.api import run, sudo, local, env
import paramiko
import socket
host1 = '192.168.200.181'
offline_host2 = '192.168.200.199'
host3 = '192.168.200.183'
env.hosts = [host1, offline_host2, host3]
def df_h():
if _is_host_up(env.host, int(env.port)) is True:
run("df -h | grep sda1")
def _is_host_up(host, port):
# Set the timeout
original_timeout = socket.getdefaulttimeout()
new_timeout = 3
socket.setdefaulttimeout(new_timeout)
host_status = False
try:
transport = paramiko.Transport((host, port))
host_status = True
except:
print('***Warning*** Host {host} on port {port} is down.'.format(
host=host, port=port)
)
socket.setdefaulttimeout(original_timeout)
return host_status
基于马修的答案,我想出了一个装饰师,完成了这个:
from __future__ import with_statement
from paramiko import Transport
from socket import getdefaulttimeout, setdefaulttimeout
from fabric.api import run, cd, env, roles
roledefs = {
'greece': [
'alpha',
'beta'
],
'arabia': [
'kha',
'saad'
]
}
env.roledefs = roledefs
def if_host_offline_ignore(fn):
def wrapped():
original_timeout = getdefaulttimeout()
setdefaulttimeout(3)
try:
Transport((env.host, int(env.port)))
return fn()
except:
print "The following host appears to be offline: " + env.host
setdefaulttimeout(original_timeout)
return wrapped
@roles('greece')
@if_host_offline_ignore
def hello_greece():
with cd("/tmp"):
run("touch hello_greece")
@roles('arabia')
@if_host_offline_ignore
def hello_arabia():
with cd("/tmp"):
run("touch hello_arabia")
当您拥有多个主机和角色时,它尤其有用。
你不是不正确地使用它。 您甚至可以在命令行上提供--warn-only=true
。 这是开发团队建议的文档化方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.