كيف تجعل النسيج يتجاهل المضيفين في وضع عدم الاتصال في قائمة Env.Hosts؟
سؤال
هذا مرتبط ب السؤال السابق, ولكن واحدة مختلفة.
لدي فابفيل التالي:
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" ، لكن ربما أستخدمه بشكل غير صحيح.
كيف يمكنني تعديل هذا السلوك بحيث يطبع الخطأ فقط ومواصلة التنفيذ؟
المحلول
بحسب ال وثائق النسيج على warn_only,
env.warn_only
"يحدد ما إذا كان التحذير أم لا ، بدلاً من الإحباط ، متىrun
/sudo
/local
مواجهة شروط الخطأ.
لن يساعد هذا في حالة انخفاض الخادم ، حيث يحدث الفشل أثناء محاولة SSH قبل التنفيذ run
/sudo
/local
.
سيكون أحد الحلول هو إنشاء وظيفة للتحقق مما إذا كان كل خادم قد انتهى قبل تنفيذ مهامك. فيما يلي الرمز الذي استخدمته.
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
نصائح أخرى
اعتبارا من النسخة 1.4 النسيج لديه ملف --skip-bad-hosts
الخيار الذي يمكن تعيينه من سطر الأوامر ، أو عن طريق تعيين المتغير في ملف FAB الخاص بك.
env.skip_bad_hosts = True
وثائق الخيار هنا:http://docs.fabfile.org/en/latest/usage/fab.html#cmdoption--skip-bad-hosts
لا تنسى ضبط قيمة المهلة بشكل صريح.
أنت لا تستخدمه بشكل غير صحيح. يمكنك حتى توفير --warn-only=true
على سطر الأوامر. إنها الطريقة الموثقة التي اقترحها فريق التطوير.
بناءً على إجابة ماثيو ، توصلت إلى ديكور ينجز ذلك تمامًا:
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")
إنه مفيد بشكل خاص عندما يكون لديك مضيفات وأدوار متعددة.