jenkins常用插件补充
1. Subversion Plugin
- Jenkins可以拉取Subversion存储库进行更改,这只能发生在每分钟一次,所以您可能还需要等待一整分钟才能发现更改。为了减少这种延迟,可以设置一个后提交钩子,以便Subversion存储库可以在对该存储库进行更改时通知Jenkins。 为此,请将以下脚本放在您的后提交文件($ REPOSITORY / hooks目录)中:
REPOS="$1"
REV="$2"
UUID=`svnlook uuid $REPOS`
/usr/bin/wget \
--header "Content-Type:text/plain;charset=UTF-8" \
--post-data "`svnlook changed --revision $REV $REPOS`" \
--output-document "-" \
--timeout=2 \
http://server/subversion/${UUID}/notifyCommit?rev=$REV
# 请注意rev = $ REV参数,这告诉Jenkins准确检查挂钩报告的修订版本。 如果您的工作有多个Subversion模块位置定义,这可能导致检出不一致 - 所以建议在这种情况下不要使用'?rev = $ REV'。
```
如果您的Jenkins使用“防止跨站点请求伪造攻击”安全选项,则上述请求将被拒绝403错误(“未包含有效碎屑”)。 该请求中需要的碎屑可以从URL http:// server / crumbIssuer / api / xml(或/ api / json)获取。 这可以包含在上面的wget调用中,如下所示:
```
--header `wget -q --output-document - \
'http://server/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'`
```
由于wget默认情况下重试次数不超过给定超时时间为20次,所以在慢速SVN服务器上的--timeout = 2可能会导致Jenkins扫描存储库多次,进一步减缓SVN服务器一段时间后,使詹金斯没有反应。
此问题的可能解决方案是增加超时时间,使用参数-retries = 3添加更低的最大重试次数,或者通过添加2>&1&last而使wget调用异步(从而忽略任何通信错误) wget调用。超时太低可能导致您的提交挂起并抛出502错误,如果您在代理后面,或提交后错误,如果没有。 增加超时,直到不再看到wget重试。
```
#!/bin/sh
REPOS="$1"
REV="$2"
# No environment is passed to svn hook scripts; set paths to external tools explicitly:
WGET=/usr/bin/wget
SVNLOOK=/usr/bin/svnlook
# If your server requires authentication, it is recommended that you set up a .netrc file to store your username and password
# Better yet, since Jenkins v. 1.426, use the generated API Token in place of the password
# See https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients
# Since no environment is passed to hook scripts, you need to set $HOME (where your .netrc lives)
# By convention, this should be the home dir of whichever user is running the svn process (i.e. apache)
HOME=/var/www/
UUID=`$SVNLOOK uuid $REPOS`
NOTIFY_URL="subversion/${UUID}/notifyCommit?rev=${REV}"
CRUMB_ISSUER_URL='crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
function notifyCI {
# URL to Hudson/Jenkins server application (with protocol, hostname, port and deployment descriptor if needed)
CISERVER=$1
# Check if "[X] Prevent Cross Site Request Forgery exploits" is activated
# so we can present a valid crumb or a proper header
HEADER="Content-Type:text/plain;charset=UTF-8"
CRUMB=`$WGET --auth-no-challenge --output-document - ${CISERVER}/${CRUMB_ISSUER_URL}`
if [ "$CRUMB" != "" ]; then HEADER=$CRUMB; fi
$WGET \
--auth-no-challenge \
--header $HEADER \
--post-data "`$SVNLOOK changed --revision $REV $REPOS`" \
--output-document "-"\
--timeout=2 \
${CISERVER}/${NOTIFY_URL}
}
# The code above was placed in a function so you can easily notify multiple Jenkins/Hudson servers:
notifyCI "http://myPC.company.local:8080"
notifyCI "http://jenkins.company.com:8080/jenkins"
```
如果您的服务器上启用了上述脚本,则会处理“防止跨站点请求伪造漏洞”选项。 如果您没有启用该选项,额外的wget调用是无害的,但如果您不需要,可随意删除它。 上述脚本还要求您将运行subversion的用户的主目录中的.netrc文件设置为(svnserve进程或httpd)。 有关.netrc文件语法的更多信息,请看这里。 上面的脚本可以轻松地向多个Jenkins服务器通知相同的SVN提交。 如果你有一个.netrc文件,即使他们有不同的管理用户设置,它也很容易。 如果您不想混淆.netrc文件,您可以在文件中硬编码用户和密码(或API Token)信息,并将--username = user和--password =“pass”标志添加到 wget调用。
#### 2. Jenkins Master/Slave架构
1. 当自动化测试用例需要在多个PC机或虚拟机中执行时,如果在每个虚拟机中均搭建类似tomcat+jenkins的环境,将会造成例如每台虚拟机资源占用大、对环境的配置维护成本大等弊端,此时,就可以采用Jenkins分布式构建方式了。<br>
远程工作目录:指定远程中的节点机器的工作目录,即Job中checkout出的代码所在的workspace目录<br>
标签:该节点的唯一标识,当在Job中要指定只在该节点进行构建与测试时,通过该唯一标识进行指定
1. Jenkins slave开机自启动
1. 若要对所用用户均进行开机自启动,则将.bat启动文件的快捷方式放入 ‘\Documents and Settings\All Users\“开始”菜单\程序\启动’目录下
1. 若只要对指定用户进行开机自启动,则将.bat启动文件的快捷方式放入 ‘\Documents and Settings\ <用户名字>\“开始”菜单\程序\启动’目录下
1. Jenkins节点监控
jenkins节点由于系统运行、网络环境等各种因素,难免会出现系统挂机、节点掉线等情况,因此要想及时发现这些情况,就需要对节点进行监控,
可以采用这里推荐的监控并重连机制:https://wiki.jenkins-ci.org/display/JENKINS/Monitor+and+Restart+Offline+Slaves
1. 由于jenkins节点监控使用的是groovy脚本调用的jenkins内部api,因此需要先安装groovy plugin插件
1. 在Master中新建一个名字为如monitor的job,设置为例如每30分钟运行一次。
1. 新增Excute system Groovy script构建步骤:
<span style="font-size: 13px;">import hudson.model.*
import hudson.node_monitors.*
import hudson.slaves.*
import java.util.concurrent.*
jenkins = Hudson.instance
import javax.mail.internet.*;
import javax.mail.*
import javax.activation.*
def sendMail (slave, cause) {
//这里使用的是参数化构建中的变量,如果不使用此方式,可以注释掉,而使用下面的toAddress
toAddress = build.buildVariableResolver.resolve("EMAIL_RECEIVERS")
message = slave + " slave is down. Check http://192.168.10.181:8080/jenkins/computer/" + slave + "\nBecause " + cause
subject = "【jenkins节点监控】" + slave + " slave is offline"
//toAddress = "***@***.com;***@***.com"
fromAddress = "***@***.com"
host = "SMTP_SERVER"
port = "SMTP_PORT"
Properties props = new Properties();
// 发送邮件的服务器
props.setProperty("mail.smtp.host", "smtp.***.com");
// 发送邮件的协议
props.setProperty("mail.transport.protocol", "smtp");
// 在连接服务器的时候是否需要验证,发邮件是需要验证的
props.setProperty("mail.smtp.auth", "true");
// 当需要进行验证的时候,会自动从Session中去取该Authenticator对象
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your user name", "your passwd"); //输入用户名、密码
}
};
Session lSession = Session.getInstance(props,authenticator);
MimeMessage msg = new MimeMessage(lSession);
//tokenize out the recipients in case they came in as a list
StringTokenizer tok = new StringTokenizer(toAddress,";");
ArrayList emailTos = new ArrayList();
while(tok.hasMoreElements()){
emailTos.add(new InternetAddress(tok.nextElement().toString()));
}
InternetAddress[] to = new InternetAddress[emailTos.size()];
to = (InternetAddress[]) emailTos.toArray(to);
msg.setRecipients(MimeMessage.RecipientType.TO,to);
InternetAddress fromAddr = new InternetAddress(fromAddress);
msg.setFrom(fromAddr);
msg.setFrom(new InternetAddress(fromAddress));
msg.setSubject(subject);
msg.setText(message)
Transport transporter = lSession.getTransport("smtp");
transporter.connect();
transporter.send(msg);
}
def getEnviron(computer) {
def env
def thread = Thread.start("Getting env from ${computer.name}", { env = computer.environment })
thread.join(2000)
if (thread.isAlive()) thread.interrupt()
env
}
def slaveAccessible(computer) {
getEnviron(computer)?.get('PATH') != null
}
def numberOfflineNodes = 0
def numberNodes = 0
for (slave in jenkins.slaves) {
def computer = slave.computer
numberNodes ++
println ""
println "Checking computer ${computer.name}:"
def isOK = (slaveAccessible(computer) && !computer.offline)
if (isOK) {
println "\t\tOK, got PATH back from slave ${computer.name}."
println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());
println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());
println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());
println('\tcomputer.offline: ' + computer.offline);
} else {
numberOfflineNodes ++
println " ERROR: can't get PATH from slave ${computer.name}."
println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());
println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());
println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());
println('\tcomputer.offline: ' + computer.offline);
sendMail(computer.name, slave.getComputer().getOfflineCause().toString())
if (slave.getComputer().isTemporarilyOffline()) {
if (!slave.getComputer().getOfflineCause().toString().contains("Disconnected by")) {
computer.setTemporarilyOffline(false, slave.getComputer().getOfflineCause())
}
} else {
computer.connect(true)
}
}
}
println ("Number of Offline Nodes: " + numberOfflineNodes)
println ("Number of Nodes: " + numberNodes) </span><span style="font-size:14px;">
</span>
“`
3. Kerberos SSO 插件
- 该插件读取用户的Kerberos票证并使用它将用户记录到Jenkins。 它可以与Active Directory插件一起很好地使用。 它还可以重定向在请求中忽略指定域的用户。
- 可以通过在请求中设置Bypass-Kerberos头来绕过特定请求的身份验证。 它的价值无关紧要,用户将被认证为匿名的。
插件可以被配置为允许未经身份验证的请求,并且只有在请求时进行身份验证。 否则,将为每个请求执行身份验证。
jenkins上进入系统管理>系统配置中进行配置
在linux服务器上安装指南:krb5.conf的位置默认为“/etc/krb5.conf”。此外,如果用户在该字段中输入其他信息,并且在该位置找不到该文件,它将返回到“/etc/krb5.conf”以查找该文件。libdefaults部分告诉Spnego在领域中使用哪种加密类型,而领域告诉Spnego密钥分配中心所在的位置。 提供的Kerberos票证的请求被发送到该服务器。Jenkins已读取这个文件的权限是非常重要的!
[libdefaults] default_realm = INTERNALDOMAIN.NET default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5 default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5 preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5 [realms] INTERNALDOMAIN.NET = { kdc = 59.169.100.36 kdc = 7b99:a413:0:ac1b::00:01 kdc = 7b99:a413:0:ac1b::00:02 kdc = 7b99:a413:0:ac1b::00:03 }Login.conf的位置是设置中最重要的部分,而且是最复杂的。 如果这是错误的指定,Jenkins将立即告诉你一个Servlet异常。 它必须指向名为“login.conf”的服务器上的文件,或通常在文档等中指定“jaas.conf”。 与“krb5.conf”文件一样,Jenkins对此文件的读取权限非常重要!
Kerberos { com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/hostname01@INTERNALDOMAIN.NET" doNotPrompt="false" useTicketCache="false" useKeyTab="true" keyTab="/etc/krb5.keytab"; }; spnego-client { com.sun.security.auth.module.Krb5LoginModule required; }; spnego-server { com.sun.security.auth.module.Krb5LoginModule required isInitiator="false" useKeyTab="true" keyTab="/etc/krb5.keytab" principal="HTTP/hostname01@INTERNALDOMAIN.NET" tryFirstPass="true" storePass="true" storeKey="true"; }; com.sun.security.jgss.initiate { com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/hostname01@INTERNALDOMAIN.NET" useKeyTab="true" keyTab="/etc/krb5.keytab"; }; com.sun.security.jgss.accept { com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/hostname01@INTERNALDOMAIN.NET" useKeyTab="true" keyTab="/etc/krb5.keytab"; };Jenkins对keytab文件的读取权限非常重要!设置服务器时,可能需要在服务器上修改此keytab文件:
# Write the following into a terminal: sudo net ads keytab list # If the server is correctly set up, it the keytab will contain rows looking something like this: HTTP/HOSTNAME01@INTERNALDOMAIN.NET # The important part here is the HTTP principal. If it doesn't contain such a row, type the following: sudo net ads keytab add \-P HTTP # Verify with the list command that the keytab now contains HTTP entries.
要注意的一个重要事情是,您的servlet容器(例如Tomcat)需要具有足够的头部大小。 这种情况因环境而异,当事情似乎错误时,并不总是容易发现问题.
4. CloudBees Folders Plugin
- 随着项目和团队的数量的增加,Jenkins的相应数量的工作也会增加。 用户发现他们需要组织他们的项目和工作,使他们的管理更容易。 詹金斯不提供内置的功能来满足这一需求。
- CloudBees Folders 插件允许您将作业组织到分层文件夹中,就像在文件系统目录中组织文件一样。 这可以让您将相关作业组合在一起,然后可以对特定文件夹中的部门,项目和作业进行分组。 文件夹还可以定义内部作业可见的属性,使您能够简化分支和/或工作流管理。
- CloudBees Folders 插件允许您在每个文件夹的基础上设置安全权限(基于角色的访问控制插件)。 角色可以在嵌套文件夹层次结构中继承(或过滤掉)。 例如:工程部门文件夹可以给予所有工程师广泛的权限,但项目Foo子文件夹只允许某些工程师进行修改。
- 文件夹然后允许您快速完整地克隆一个文件夹与其子文件夹。
- 文件夹是命名空间感知的。 因此,您可以拥有位于不同层级下的相同名称的作业。
5. Promoted Builds插件
- 这个插件允许您通过引入promotion“促销”的概念来区分好的构建和坏的构建。简单地说,如果Promoted Builds通过了额外的标准(例如设置为下游作业的更全面的测试)则是一个成功的构建。
- 您使用Promoted的典型情况是有多个“测试”作业挂接为“构建”作业的下游作业。
- 然后,您将配置构建作业,以便在所有测试作业成功传递时升级构建。这允许您保持构建作业运行速度快(以便开发人员在构建失败时获得更快的反馈),并且您仍然可以与构建编译运行的问题进行区分。
- 在构建配置时勾选这个选项

- promoted builds的例子
- 工件存储 - 您可能不想在每个版本上将工件推送到您的主要工件存储库。通过构建促销,只有当工件符合某些标准时,才能推送。例如,您可能只想在运行集成测试后推送它。
- Manual Promotions(手动 promotion) - 您可以选择一组可以运行Manual Promotions的人。 这样做可以在构建系统中进行“注销”。 例如,开发人员可以验证一个构建,并且只有在完全完成了工作产品时才批准它进行质量检查。 那么可以再增加一个promotion活动来进行质量保证。
- 工件的聚合 - 如果您有一个软件版本由几个不直接相关的工件组成,这些工件位于单独的作业中,则可能需要将经过验证的质量的所有工件聚合到分发位置。 要做到这一点,您可以创建一个新的作业,为每个要聚合的项目添加“从另一个作业复制工件”(可通过“复制工件插件”获得))。要获得一定的升级,请在副本中选择“使用固定链接” 工件步骤,则您的promoted builds应显示在要复制的项目列表中。
6. Dingding Notification 插件
允许用户通过Dingding-钉钉发送构建通知
1. 在钉钉创建一个钉钉机器人
1. 安装插件后,每个作业都可以添加一个后期制作步骤,选择’叮当通知配置’

7. Dingding Json Pusher插件
- 允许用户将存储在JSON文件中的复杂消息推送到多个Dingding组。
- Dingding支持的任何格式消息都可以由此插件推送。
- 支持Jenkins管道。
- 支持Jenkins工作DSL。
本文详细介绍了 Jenkins 的几个常用插件,包括 Subversion Plugin 的后提交钩子功能,Kerberos SSO 插件的用户认证机制,CloudBees Folders Plugin 对项目组织的管理,Promoted Builds 插件如何区分优质构建,以及 Dingding Notification 和 Dingding Json Pusher 插件在构建通知和复杂消息推送中的应用。
3966

被折叠的 条评论
为什么被折叠?



