我们有一个 Jenkins 矩阵作业,它在许多从属节点上并行测试我们软件的多个变体。有时会发生,其中一个从站崩溃并且必须重新启动。在这种情况下,我不想跳过运行。我不想将特定的从节点标记为底层脚本暂时不可用,该脚本会检测到崩溃并随后重新启动节点。我发现,这应该可以通过 Jenkins REST API 实现。我找到了两个 python 库,它们应该可以完成这项工作; https://python-jenkins.readthedocs.org/en/latest/index.html和 http://pythonhosted.org/jenkinsapi/index.html .但是这两个库在使用 python 3.4.3 更改我的 Jenkins 1.580.2 系统(获取信息不是问题)上的某些内容时都存在问题。
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] certificate verify failed (_ssl.c:600)
好吧,如果我尝试使用 jenkins 对象获取一些信息,一切都很好。
node.is_temporarily_offline()
False
但是如果我尝试切换节点,我会收到以下信息:
node.toggle_temporarily_offline()
JenkinsAPIException: Operation failed. 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\nAuthentication required\n\n\n
我的登录数据完全被忽略了。
python-jenkins:
import jenkins
j = jenkins.Jenkins(jenkinsurl, username, password)
j.disable_node(slavenode)
TypeError: the JSON object must be str, not 'bytes'
经过简短的谷歌搜索后,我发现我必须修补库,因为 JSON 不喜欢 Jenkins JSON API 提供的字节数组。插入几个 decode('utf-8') 语句后,我能够调用以下语句:
j.get_node_info(slavenode)
但我仍然无法将其标记为离线:
j.disable_node(slavenode)
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.
所以,把它归结为一个简单的问题。您是否知道其他一些方便的、可编写脚本的方法来将节点标记为暂时离线(当然,如果重启成功,则再次在线)?我更喜欢 python 解决方案,因为我从我的 python 脚本触发重启。但常规脚本也足够好。
预先感谢您的帮助
最佳答案
你可以看看 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());
}
关于python - 使用 Jenkins REST API 将 Jenkins 节点暂时标记为离线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30327219/