【问题标题】:Mark Jenkins node temporarily as offline by using the Jenkins REST API使用 Jenkins REST API 将 Jenkins 节点暂时标记为离线
【发布时间】:2015-05-20 04:58:15
【问题描述】:

我们有一个 Jenkins 矩阵作业,它在许多从属节点上并行测试我们软件的几个变体。有时会发生,其中一个从站崩溃并且必须重新启动。在这种情况下,我不想跳过跑步。我不想将特定的从节点标记为临时不可用的下属脚本,该脚本检测到崩溃并随后重新启动节点。我发现,Jenkins REST API 应该可以做到这一点。我找到了两个 python 库,它们应该可以完成这项工作; https://python-jenkins.readthedocs.org/en/latest/index.htmlhttp://pythonhosted.org/jenkinsapi/index.html。但是这两个库都无法在我的 Jenkins 1.580.2 系统上使用 python 3.4.3 更改某些内容(获取信息不是问题)。

JenkinsAPI:

from jenkinsapi.jenkins import Jenkins
from jenkinsapi.utils.requester import Requester

class SSLRequester(Requester):
    def __init__(self, username=None, password=None):
        super(SSLRequester, self).__init__(username, password)

   def get_request_dict(self, *largs, **kwargs):
        requestKWargs = super(SSLRequester, self).get_request_dict(*largs, **kwargs)
        requestKWargs['verify'] = False
        return requestKWargs 

jenkins = Jenkins(jenkinsurl, username, password, requester=SSLRequester())

我必须使用自定义 SSLRequester,因为我为我的 Jenkins 服务器使用 https:// 连接,否则我会收到以下错误

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:600)

好吧,如果我尝试使用 jenkins 对象获取一些信息,一切都很好。

node.is_temporarily_offline()
False

但如果我尝试切换节点,我会收到以下信息:

node.toggle_temporarily_offline()

JenkinsAPIException:操作失败。 url=https:///computer//toggleOffline?offlineMessage=requested%20from%20jenkinsapi, data={}, headers={'Content-Type': 'application/x-www-form-urlencoded'}, status=403 , text=b"%2FtoggleOffline%3FofflineMessage%3Drequested%2520from%2520jenkinsapi'/>window.location.replace('/login?from=%2Fcomputer%2F%2FtoggleOffline%3FofflineMessage%3Drequested%2520from%2520jenkinsapi');\n\ n\n需要身份验证\n\n\n

我的登录数据完全被忽略了。

python-jenkins:

import jenkins
j = jenkins.Jenkins(jenkinsurl, username, password)
j.disable_node(slavenode)

TypeError:JSON 对象必须是 str,而不是 'bytes'

在谷歌搜索后,我发现我必须修补库,因为 JSON 不喜欢 Jenkins JSON API 提供的字节数组。插入几个 decode('utf-8') 语句后,我可以调用以下语句:

j.get_node_info(slavenode)

但我仍然无法将其标记为离线:

j.disable_node(slavenode)

TypeError: POST 数据应该是字节或可迭代的字节。它不能是 str 类型。

所以,把它归结为一个简单的问题。您是否知道其他一些方便的、可编写脚本的方式将节点标记为暂时离线(当然,如果重新启动成功,则再次在线)?我更喜欢 python 解决方案,因为我从 python 脚本触发了重启。但是一个 groovy 脚本也足够了。

提前感谢您的帮助

【问题讨论】:

    标签: python json jenkins


    【解决方案1】:

    您可以查看script console,您可以在其中测试脚本。你也可以使用 curl 或 CLI 调用这些脚本,我想象一个 python 库

    这是查看 nodes 并删除节点的 groovy 脚本的一个很好的示例

    for (aSlave in hudson.model.Hudson.instance.slaves) {
      println('====================');
      println('Name: ' + aSlave.name);
      println('getLabelString: ' + aSlave.getLabelString());
      println('getNumExectutors: ' + aSlave.getNumExecutors());
      println('getRemoteFS: ' + aSlave.getRemoteFS());
      println('getMode: ' + aSlave.getMode());
      println('getRootPath: ' + aSlave.getRootPath());
      println('getDescriptor: ' + aSlave.getDescriptor());
      println('getComputer: ' + aSlave.getComputer());
      println('\tcomputer.isAcceptingTasks: ' + aSlave.getComputer().isAcceptingTasks());
      println('\tcomputer.isLaunchSupported: ' + aSlave.getComputer().isLaunchSupported());
      println('\tcomputer.getConnectTime: ' + aSlave.getComputer().getConnectTime());
      println('\tcomputer.getDemandStartMilliseconds: ' + aSlave.getComputer().getDemandStartMilliseconds());
      println('\tcomputer.isOffline: ' + aSlave.getComputer().isOffline());
      println('\tcomputer.countBusy: ' + aSlave.getComputer().countBusy());
      //if (aSlave.name == 'NAME OF NODE TO DELETE') {
      //  println('Shutting down node!!!!');
      //  aSlave.getComputer().setTemporarilyOffline(true,null);
      //  aSlave.getComputer().doDoDelete();
      //}
      println('\tcomputer.getLog: ' + aSlave.getComputer().getLog());
      println('\tcomputer.getBuilds: ' + aSlave.getComputer().getBuilds());
    }
    

    【讨论】:

    猜你喜欢
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多