Internship Log (Week 6, 2)

Keywords: jenkins svn xml JSON

Common plug-in additions to jenkins

1. Subversion Plugin

  1. Jenkins can pull the Subversion repository for changes, which can only happen once a minute, so you may have to wait an entire minute to find the changes. To reduce this delay, you can set up a post-commit hook so that the Subversion repository can notify Jenkins when changes are made to the repository. To do this, place the following scripts in your post-submission file (the $REPOSITORY / hooks directory):
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
  # Note the Rev = $REV parameter, which tells Jenkins to check the revised version of the hook report accurately. If you work with multiple Subversion module location definitions, this may lead to inconsistencies in detection - so it is recommended not to use'? Rev = $REV'.
  ```
  If your Jenkins uses the security option "Prevent cross-site requests from forgery attacks", the above request will be rejected by 403 errors ("No valid debris included"). The debris required in this request can be obtained from the URL http://server/crumbIssuer/api/xml (or/api/json). This can be included in the wget call above, as follows:
  ```
  --header `wget -q --output-document - \
  'http://server/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'`
  ```
  Because wget retries by default do not exceed a given timeout of 20 times, time out = 2 on a slow SVN server may cause Jenkins to scan the repository many times, further slowing down the SVN server for a period of time, leaving Jenkins unresponsive.
  The possible solution to this problem is to increase the timeout time, add a lower maximum retry number with the parameter - retries = 3, or make wget calls asynchronous (thus ignoring any communication errors) by adding 2 > & 1 & last. Too low a timeout may cause your submission to hang and throw 502 errors if you are behind the agent or submit errors, if not. Increase timeout until wget retries are no longer seen.
  ```
  #!/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"
  ```
  If the above script is enabled on your server, the "Prevent cross-site Request Forgery vulnerabilities" option is handled. If you don't have this option enabled, additional wget calls are harmless, but if you don't need them, you can delete them at will. The script also requires you to set the. netrc file in the home directory of the user running subversion to (svnserve process or httpd). For more information on. netrc file syntax, see here. The above script can easily notify multiple Jenkins servers of the same SVN submission. If you have a. netrc file, it's easy even if they have different administrative user settings. If you don't want to confuse the. netrc file, you can hard-code user and password (or API Token) information in the file and add the -- username = user and -- password = pass flags to the wget call.

#### 2. Jenkins Master/Slave Architecture
 1. When automated test cases need to be executed in multiple PC s or virtual machines, if an environment similar to tomcat+jenkins is built in each virtual machine, it will cause disadvantages such as large resource occupation per virtual machine and high cost of configuration and maintenance of the environment. At this time, Jenkins distributed construction mode can be adopted. <br>
Remote working directory: specify the working directory of the remote node machine, that is, the workspace directory < br > where the checkout code in Job is located.
Label: The unique identifier of the node, which is used to specify when building and testing only on that node is specified in Job
 1. Jenkins slave boot-up self-start
  1. To boot all users, put the shortcut of the. bat startup file under the directory' Documents and Settings All Users\\\\\\\\\\
  1. If the specified user is booted by itself, the shortcut of the. bat startup file will be put under the directory' Documents and Settings  User Name \ Start menu  Program  Start'.
1. Jenkins node monitoring
 Because of various factors such as system operation, network environment and so on, jenkins node will inevitably appear system hang-up and node drop-off. Therefore, in order to detect these situations in time, it is necessary to monitor the node.
The recommended monitoring and reconnection mechanism is https://wiki.jenkins-ci.org/display/JENKINS/Monitor+and+Restart+Offline+Slaves.
  1. Because the jenkins node monitoring uses the internal api of the jenkins called by the groovy script, the groovy plugin plug-in needs to be installed first.
  1. Create a new job named monitor in Master and set it to run every 30 minutes, for example.
  1. Add Excute system Groovy script construction steps:
<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) {  
//The variables in the parameterized build are used here. If you don't use this method, you can comment them out and use the following 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 Node Monitoring]" + slave + " slave is offline"  
//toAddress = "***@***.com;***@***.com"  
fromAddress = "***@***.com"  
host = "SMTP_SERVER"  
port = "SMTP_PORT"  
Properties props = new Properties();  
// A mail server  
props.setProperty("mail.smtp.host", "smtp.***.com");  
// Protocol for sending mail  
props.setProperty("mail.transport.protocol", "smtp");  
// Whether validation is required when connecting to the server or not, sending mail needs validation  
props.setProperty("mail.smtp.auth", "true");  
// When validation is required, the Authenticator object is automatically retrieved from Session  
Authenticator authenticator = new Authenticator() {  
@Override  
protected PasswordAuthentication getPasswordAuthentication() {  
 return new PasswordAuthentication("your user name", "your passwd"); //Enter username and password  
}  
};  
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 plug-in

  1. The plug-in reads the user's Kerberos ticket and uses it to record the user to Jenkins. It works well with Active Directory plug-ins. It can also redirect users who ignore the specified domain in the request.
  2. You can bypass the authentication of a particular request by setting the Bypass-Kerberos header in the request. Its value is irrelevant and users will be authenticated as anonymous.
  3. Plug-ins can be configured to allow unauthenticated requests and authenticate only when requested. Otherwise, authentication will be performed for each request.
    Enter System Management > Configure in System Configuration on jenkins

    Install guidelines on linux servers:

    1. The default location of krb5.conf is "/etc/krb5.conf". In addition, if the user enters additional information in the field and cannot find the file at that location, it will return to "/etc/krb5.conf" to find the file. The libdefaults section tells Spnego what type of encryption to use in the domain, and the domain tells Spnego where the key distribution center is located. The request for the provided Kerberos ticket is sent to the server. It's very important that Jenkins have permission to read this file!

      [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
      }
    2. Location of Login.conf is the most important and complex part of the setup. If this is the wrong assignment, Jenkins will immediately tell you a Servlet exception. It must point to a file on a server named "login.conf", or usually specify "jaas.conf" in a document, etc. Like the "krb5.conf" file, Jenkins has very important access to this file!

      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";
      };
    3. Jenkins has very important access to keytab files! When setting up the server, you may need to modify this keytab file on the server:

      # 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.
      

    One important thing to note is that your servlet container (such as Tomcat) needs to have enough head size. This situation varies from environment to environment, and it is not always easy to find problems when things seem wrong.

4. CloudBees Folders Plugin

  1. As the number of projects and teams increases, Jenkins'corresponding amount of work will also increase. Users find that they need to organize their projects and work to make their management easier. Jenkins does not provide built-in functionality to meet this need.
  2. The CloudBees Folders plug-in allows you to organize jobs into hierarchical folders, just as you organize files in a file system directory. This allows you to group related jobs together and then group departments, projects, and jobs in specific folders. Folders can also define properties visible to internal jobs, enabling you to simplify branching and/or workflow management.
  3. The CloudBees Folders plug-in allows you to set security permissions (role-based access control plug-ins) on a per-folder basis. Roles can be inherited (or filtered) in a nested folder hierarchy. For example, the engineering department folder can give all engineers extensive authority, but the Foo subfolder of the project only allows some engineers to modify.
  4. Folders then allow you to quickly and completely clone a folder and its subfolders.
  5. Folders are namespace aware. Therefore, you can have jobs with the same name at different levels.

5. Promoted Builds plug-in

  1. This plug-in allows you to distinguish between good and bad builds by introducing the concept of promotion "promotion". Simply put, if Promoted Builds passes additional standards, such as a more comprehensive test set for downstream jobs, it is a successful build.
  2. Typically, when you use Promoted, you have multiple "test" jobs hooked up to downstream jobs for "build" jobs.
  3. Then, you will configure the build job to upgrade the build when all test jobs are successfully delivered. This allows you to keep the build job running fast (so that developers can get faster feedback when the build fails), and you can still distinguish between build compilation and run problems.
  4. Check this option when building the configuration
  5. Example of promoted builds
    1. Storage of artifacts - You may not want to push artifacts to your main work repository in each version. By building promotions, only when the workpiece meets certain criteria can it be pushed. For example, you might just want to push it after running the integration test.
    2. Manual Promotions - You can choose a group of people who can run Manual Promotions. This can be "logged out" in the build system. For example, a developer can validate a build and approve it for quality checks only when the work product is fully completed. Then another promotion activity can be added to ensure quality.
    3. Aggregation of artifacts - If you have a software version consisting of several artifacts that are not directly related and are located in a separate job, you may need to aggregate all artifacts of validated quality into a distribution location. To do this, you can create a new job by adding "Copy artifacts from another job" (available through the Copy Artifact Plug-in) for each project to be aggregated. To get a certain upgrade, select the "Use Fixed Links" artifact step in the copy, and your promoted builds should be displayed in the list of items to be copied.

6. Dingding Notification Plug-in

Allow users to send build notifications through Dingding-pins
1. Create a nail robot in nails

1. After installing the plug-in, each job can add a post-production step and select the "jingle notification configuration"

7. Dingding Json Pusher plug-in

  1. Allows users to push complex messages stored in JSON files to multiple Dingding groups.
  2. Any format message supported by Dingding can be pushed by this plug-in.
  3. Support the Jenkins pipeline.
  4. Support Jenkins working DSL.

Posted by mainewoods on Mon, 20 May 2019 15:16:07 -0700