【问题标题】:How to determine if remote ESXI Host has booted fully?如何确定远程 ESXI 主机是否已完全启动?
【发布时间】:2021-10-01 11:12:16
【问题描述】:

我正在编写一个 Python 脚本来完全远程启动少数 ESXI 主机,但我无法确定 ESXI 何时完成启动并准备好接收通过 SSH 发送的命令。我在一个硬连线到每个 ESXI 主机的 Windows 主机上运行脚本,并且系统是气隙的,因此没有防火墙,也没有安全软件会干扰。

目前我正在这样做:我通过 SSH 远程进入机箱并将电源命令发送到 ESXI 主机 - 这有效并且一直有效。然后,我尝试通过 SSH 连接到每个刀片并发送以下命令

esxcli system stats uptime get

命令无关紧要,我只需要响应以确保主机已启动。下面是我用来发送 SSH 命令以希望得到响应的函数

def send_command(ip, port, timeout, retry_interval, cmd, user, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    retry_interval = float(retry_interval)
    timeout = int(timeout)
    timeout_start = time.time()
    worked = False 
    while worked == False:
        time.sleep(retry_interval)
        try:
            ssh.connect(ip, port, user, password, timeout=5)
            stdin,stdout,stderr=ssh.exec_command(cmd)
            outlines=stdout.readlines()
            resp=''.join(outlines)
            print(resp)
            worked = True 
            return (resp) 
        except socket_error as e:
            worked = False 
            print(e)
            continue
        except paramiko.ssh_exception.SSHException as e:
            worked = False 
            # socket is open, but not SSH service responded
            print(e) 
            continue
        except TimeoutError as e: 
            print(e)
            worked = False 
            pass
        except socket.timeout as e: 
            print(e)
            worked = False 
            continue
        except paramiko.ssh_exception.NoValidConnectionsError as e:
            print(e)
            worked = False 
            continue
        except socket.error as serr:
            print(serr)
            worked = False 
            continue 
        except IOError as e:
            print(e)
            worked = False 
            continue 
        except: 
            print(e)
            worked = False 
            continue 

我的目标是在足够长的时间内捕获所有异常,以便主机完成启动并收到响应。问题是有时它会循环几分钟(正如启动这样的系统时所预期的那样),然后它会打印

IO 错误:[Errno 111] 连接被拒绝

然后退出 function/try catch 块并且永远不会建立连接。我知道这是我的异常处理的错误,因为发生这种情况时,我会停止脚本,等待几分钟,然后再次运行它而不触及其他任何内容,esxcli 命令将完美运行,脚本将运行良好。

如何防止 Errno 111 错误中断我的循环?非常感谢任何帮助

编辑:一种可能的管道胶带解决方案可能是将命令更改为“esxcli system hostname get”并检查“域”一词的响应。这可能会起作用,因为 IOError 似乎是响应而不是异常,不过我必须等到星期一才能测试该解决方案。

【问题讨论】:

    标签: python networking paramiko esxi


    【解决方案1】:

    我解决了。我突然想到我正在处理任何 python 代码可能抛出的所有可能的异常,所以我的缺陷不是 python 错误,这就是为什么我没有在网上找到任何关于 Python、SSH 和Errno 111 错误。

    打印输出实际上是来自 ESXI 主机的响应,我的代码正在寻找任何响应。所以我只是将 esxcli 命令从请求正常运行时间更改为

    esxcli 系统主机名获取

    然后通过this进入函数

    substring = "Domain"
    if substring not in resp: 
        print(resp)
        continue
    

    我正在寻找“域”这个词,因为如果调用成功,它必须在那里。

    我是怎么想出来的:我在旧的 Intel Nuc 上安装了 ESXI 7,在 kickstart 脚本中打开了 SSH,启动了脚本,然后打开了 nuc。我使用 NUC 的原因是因为在简单硬件上全新安装的启动速度比 Dell Blades 更快、更安静!此外,我将 resp 变量包装在 print(type(OBJECT)) 行中,并且能够确定它实际上是一个字符串而不是一个错误对象。

    这可能对有合法 Errno 111 错误的人没有帮助,我知道我每次运行代码都会遇到这个错误,我只需要知道如何处理它并保持循环直到我得到我想要的回应。

    编辑:我想只过滤世界“errno”然后继续循环而不是使用不同的子字符串会更容易。这将处理我所有的用例并消除对不同功能的需求。

    【讨论】:

      猜你喜欢
      • 2021-08-21
      • 2011-02-01
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      相关资源
      最近更新 更多