使用Jenkins REST API将Mark Jenkins节点临时标记为脱机

时间:2015-05-19 13:34:47

标签: python json jenkins

我们有一个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 = required%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

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

蟒-詹金斯:

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脚本触发重启。但是一个时髦的剧本也足够好了。

提前感谢您的帮助

1 个答案:

答案 0 :(得分:4)

您可以查看可以测试脚本的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());
}