كيف تجعل النسيج يتجاهل المضيفين في وضع عدم الاتصال في قائمة Env.Hosts؟

StackOverflow https://stackoverflow.com/questions/1956777

  •  21-09-2019
  •  | 
  •  

سؤال

هذا مرتبط ب السؤال السابق, ولكن واحدة مختلفة.

لدي فابفيل التالي:

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")

إنه مفيد بشكل خاص عندما يكون لديك مضيفات وأدوار متعددة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top