jenkins 添加一个maven任务的job实践

目录

新建JOB

General一般

丢弃旧的构建

参数化构建过程

添加branch参数

version参数

env参数

Source Code Management源代码

Pre Steps

Build构建

总体

自定义工作空间

重要配置文件

pom文件

Dockerfile

docker-start.sh

docker-compose.yaml

jenkins-deployment.sh

dev.env文件

Post Steps

Post-build Actions

添加Send build artifacts over SSH

SSH Server

根据参数自动选择哪个ssh server

设置label

Parameterized publishing

设置参数env

总结


添加的job是基于git、maven和docker私有仓库,实现自动构建jar包、生成docker镜像,并能够自动docker容器的过程。还可以根据选择的参数,实现检出git不同分支,生成不同版本的docker镜像,并发布到开发服务器或者测试服务器。我这边就拿一个多模块的基于maven构建的项目来说明

  1. 添加ssh server

在系统管理->系统配置->Publish over SSH, 添加一个ssh server ,需要注意的是Remote Directory要注意设置,建议设置为/, 不然通过ssh发送文件会不行,笔者就曾经漏掉这个,排查了半天

新建JOB

注意是勾选构建一个maven项目

General一般

参数化构建过程

添加branch参数

作用:branche参数用来选择构建的代码分支是dev还是test
选择添加Active Choices Parameter

勾选groovy script

groovy脚本

return[
"dev","test"
]

version参数

作用:version参数来控制docker镜像版本是latest还是1.0。
添加Active Choices Reactive Parameter,能够根据别的参数改变自己的值

version参数会根据branch参数变化值 ,注意在    Referenced parameters项填入branch

groovy脚本

dev=["latest"]
test=["1.0"]

if (branch.equals("dev")) {
  return dev
} else if (branch.equals("test")) {
  return test
} else {
  return ["latest"]
}

env参数

作用:env参数把程序发布到哪台主机

添加Extended Choice Parameter类型参数,参数类型是Radio Buttions

choose source for value和chose source for value description分别写入dev,test和开发环境,测试环境。注意多个选项之前用逗号隔开,是delimter指定的

Source Code Management源代码

要把构建的源代码放在这边设置,选择
Multiple SCMs,再选择git来检出,因为这个项目有依赖多个子项目,这个选项可以设置多个git源代码

注意在Branch Specifier (blank for 'any')中写入*/${branch}, 这是之前设置的branch参数

注意设置检出项目的子目录,点击   Additional Behaviours     -> Check out to a sub-directory,再在 Local subdirectory for repo 写入要检出代码存放的目录

Pre Steps

这边就是构建上面检出的主项目所依赖的其他项目的源代码

脚本如下

java -version
sudo sed -i '$d' /etc/hosts
echo $env

if [ "$env" == "test" ]
then
echo 'test'
sudo sed -i '$a192.168.133.X imageserver' /etc/hosts

else
echo "++++dev++++"
sudo sed -i '$a192.168.133.X imageserver' /etc/hosts
fi



docker login imageserver:8082 -u用户名 -p密码

cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-common
mvn clean install  -Dmaven.test.skip=true

cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-system
	
mvn clean package install -pl nledu-iotbd-system-fegin  -am  -Dmaven.test.skip=true


cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-ci
	
mvn clean package install -pl nledu-iotbd-ci-fegin -am  -Dmaven.test.skip=true

mvn clean package install -pl nledu-iotbd-ci-stream -am  -Dmaven.test.skip=true

cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-vm
	
mvn clean package install -pl nledu-iotbd-vm-fegin  -am  -Dmaven.test.skip=true

cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-websocket

mvn clean package install -pl nledu-iotdb-websocket-feign  -am  -Dmaven.test.skip=true


cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-vm
	
mvn clean package install -pl nledu-iotbd-vm-fegin  -am  -Dmaven.test.skip=true

说一下下面脚本的作用

sudo sed -i '$d' /etc/hosts

就是/etc/hosts删除最后一行

sudo sed -i '$a192.168.133.X imageserver' /etc/hosts

就是往/etc/hosts文件最后一行添加192.168.133.93 imageserver

上面的脚本,其实就是切换不同的docker仓库,因为开发服务器和测试服务器的docker 仓库地址不同,通过修改hosts文件来切换

Build构建

总体

root pom就是主项目的pom文件路径

golas and options脚本就是构建主项目,如下

clean package  docker:build -DpushImageTag  -Dmaven.test.skip=true -Ddocker.image.version=${version}

${version}是version参数传进去的值

自定义工作空间

点击高级,设置自己的工作空间,工作空间的设置对于Send build artifacts over SSH非常重要,Send build artifacts over SSH的source files的地址就是基于这个工作的相对目录,所以最好要设置。

选择Use custom workspace,在Directory写入工作空间目录

重要配置文件

主项目的源代码目录的docker目录下有4个跟构建相关的脚本,以及docker-compose.yaml要用到的参数脚本dev.env,都给粘出来,供参考

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nledu-iotbd-ci</artifactId>
        <groupId>com.newland.iotbd.ci</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.newland.iotbd.ci.core</groupId>
    <artifactId>nledu-iotbd-ci-core</artifactId>

    <properties>

        <docker.image.prefix>imageserver:8082/iotbd</docker.image.prefix>
        <docker.image.version>${project.version}</docker.image.version>
        <itext.version>7.1.12</itext.version>
    </properties>

    <dependencies>

      

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.newland.iotbd.ci.core.NleduIotbdCICoreApplication</mainClass>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>.</Class-Path>
                            <Timestamp>${maven.build.timestamp}</Timestamp>
                        </manifestEntries>
                    </archive>
                    <!-- <excludes>
                         <exclude>**/*.properties</exclude>
                         <exclude>**/*.xml</exclude>
                     </excludes>-->
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <finalName>${project.artifactId}</finalName>
                    <descriptors>
                        <descriptor>src/main/resources/assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}:${docker.image.version}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <!-- <dockerHost>http://imageserver:2375</dockerHost>-->
                    <!--强制覆盖 镜像-->
                    <forceTags>true</forceTags>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <!-- <include>${project.build.finalName}-all.tar.gz</include>-->
                        </resource>
                    </resources>

                    <imageTags>
                        <imageTag>${docker.image.version}</imageTag>
                    </imageTags>
                    <!-- push -->
                    <serverId>docker-registry</serverId>
                    <registryUrl>http://${docker.image.prefix}</registryUrl>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Dockerfile

# FROM imageserver:6000/java:8
#FROM imageserver:8082/iotbd/centos8-jdk11.0.7:2020.08.10
FROM imageserver:8082/iotbd/centos8-jdk11.0.7:20200901
MAINTAINER yuxs "yuxs@newlandcomputer.com"
RUN mkdir -p /app
WORKDIR /app
ADD nledu-iotbd-ci-core-all.tar.gz .
COPY docker-start.sh ./nledu-iotbd-ci-core/
RUN mkdir -p log
ENV TZ Asia/Shanghai
EXPOSE 8806

ENTRYPOINT ["/bin/bash","/app/nledu-iotbd-ci-core/docker-start.sh"]

docker-start.sh

用来容器里头启动java服务

#!/bin/bash
APP_ENV=${appenv:-dev}
APP_NAME=${appname}
APP_VERSION=${appversion:-1.0-SNAPSHOT}
LOG_MAX_SIZE=${log_max_size:-20MB}

# change directory to program dir
FWDIR="$(cd `dirname $0`; pwd)"
cd ${FWDIR}

if [ ! -d ${FWDIR}/java.pid ]; then
    touch ${FWDIR}/java.pid
fi

OSUSER=$(id -nu)
PSNUM=$(cat ${FWDIR}/java.pid)
if [[ "$PSNUM" -ne "" ]]; then
    echo ${APP_NAME}" has been started! stop first."
    exit;
fi

echo "Running in docker!"
      #-XX:+UseCGroupMemoryLimitForHeap \
      #-XX:+UnlockExperimentalVMOptions \
      #-XX:MaxRAMFraction=1  \

if [ $skywalking -eq 1 ]; then
    java  -DSW_AGENT_NAME=${APP_NAME} \
          -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=${skywalking_url}:${skywalking_port} \
          -DSW_LOGGING_LEVEL=debug \
          -javaagent:\/app\/skywalking\/agent\/skywalking-agent.jar \
          -XX:+UnlockExperimentalVMOptions \
          -XX:MaxRAMPercentage=90.0  \
          -XX:+HeapDumpOnOutOfMemoryError \
          -XX:HeapDumpPath=/app/${APP_NAME}/log/ \
          -Dspring.profiles.active=${APP_ENV} \
          -Dapp.name=${APP_NAME} \
          -Dapp.env=${APP_ENV} \
          -Dmax.size=${LOG_MAX_SIZE} \
          -Duser.dir=${FWDIR} \
          -jar ${APP_NAME}-${APP_VERSION}.jar
else
  java  -XX:+UnlockExperimentalVMOptions \
      -XX:MaxRAMPercentage=90.0  \
      -XX:+HeapDumpOnOutOfMemoryError \
      -XX:HeapDumpPath=/app/${APP_NAME}/log/ \
      -Dspring.profiles.active=${APP_ENV} \
      -Dapp.name=${APP_NAME} \
      -Dapp.env=${APP_ENV} \
      -Dmax.size=${LOG_MAX_SIZE} \
      -Duser.dir=${FWDIR} -jar ${APP_NAME}-${APP_VERSION}.jar
fi

#java  -XX:+UnlockExperimentalVMOptions \
#      -XX:MaxRAMPercentage=90.0  \
#      -XX:+HeapDumpOnOutOfMemoryError \
#      -XX:HeapDumpPath=/app/${APP_NAME}/log/ \
#      -Dspring.profiles.active=${APP_ENV} \
#      -Dapp.name=${APP_NAME} \
#      -Dapp.env=${APP_ENV} \
#      -Dmax.size=${LOG_MAX_SIZE} \
#      -javaagent:/home/agent/skywalking-agent.jar \
#      -Dskywalking.agent.service_name=${APP_NAME} \
#      -Dskywalking.collector.backend_service=${skywalking_url}:${skywalking_port} \
#      -Duser.dir=${FWDIR} -jar ${APP_NAME}-${APP_VERSION}.jar
#      #-XshowSettings:vm -version \
#      #-XX:+PrintFlagsFinal -version | grep -Ei "maxheapsize|maxram"

docker-compose.yaml

version: '3'
services:
  app-name:
    container_name: app-name
    image: imageserver:8082/iotbd/app-name:image-version
    restart: on-failure
    privileged: true
    environment:
      appenv: app-env
      appname: app-name
      appversion: 1.0-SNAPSHOT
    env_file:
      - /home/deploy_script/app-env.env
    ports:
      - 8806:8806
      - 9991:9991
    volumes:
      - /home/log/app-name:/app/app-name/log
    deploy:
      resources:
        limits:
          memory: 2G
    network_mode: "host"

注意container_name、image、environment这几项的值最后会被Post Steps步骤脚本替换。这所以这么设计,是因为脚本可以复用,项目的具体名称可以通过sed命令来替换,替换过的docker-compose.yaml如下,注意观察

version: '3'
services:
  nledu-iotbd-ci-core:
    container_name: nledu-iotbd-ci-core
    image: imageserver:8082/iotbd/nledu-iotbd-ci-core:latest
    restart: on-failure
    privileged: true
    environment:
      appenv: dev
      appname: nledu-iotbd-ci-core
      appversion: 1.0-SNAPSHOT
    env_file:
      - /home/deploy_script/dev.env
    ports:
      - 8806:8806
      - 9991:9991
    volumes:
      - /home/log/nledu-iotbd-ci-core:/app/nledu-iotbd-ci-core/log
    deploy:
      resources:
        limits:
          memory: 2G
network_mode: "host"

jenkins-deployment.sh

用来启动docker

#!/bin/bash
export version=xxxVersion
export app_name=xxxapp_name
export app_env=xxxapp_env

sed -i "s/app-name/$app_name/g" ./docker-compose.yaml
sed -i "s/image-version/$version/g" ./docker-compose.yaml
sed -i "s/app-env/$app_env/g" ./docker-compose.yaml


re=`docker images -f "dangling=true" -q`
if [ -n "$re" ];then
  docker rmi  -f `docker images -f "dangling=true" -q`
else
  echo ''
fi

docker-compose --compatibility down

re1=`docker images imageserver:8082/iotbd/$app_name:$version -q`
if [ -n "$re1" ];then
  docker rmi imageserver:8082/iotbd/$app_name:$version
else
  echo ''
fi



docker-compose --compatibility up -d
# 打印日志很好用
docker-compose --compatibility  logs -f $app_name &
#kubectl create -f deployment-$app_name.yaml

dev.env文件

这个是环境变量文件,是docker-compose.yaml指定的环境变量文件

# 注册服务器
nledu-iotbd-discovery1=192.168.133.X
nledu-iotbd-discovery1-port=8765
app.discovery.enabled=true


Post Steps

这步是构建镜像后的辅助工作,如删除dangling镜像,替换jenkins-deployment.sh的一些值

脚本

cd /var/lib/jenkins2/workspace/iotbd/nledu-iotbd-ci/nledu-iotbd-ci-core
#ls
#docker save -o  ./target/nledu-etmlab-hc-education:$version.tar imageserver:8082/nledu-etmlab-hc-education:$version
sed -i 's/xxxVersion/'$version'/g'  ./src/main/docker/jenkins-deployment.sh 
sed -i 's/xxxapp_name/nledu-iotbd-ci-core/g'  ./src/main/docker/jenkins-deployment.sh 
sed -i 's/xxxapp_env/'$env'/g'  ./src/main/docker/jenkins-deployment.sh 

re=`docker images -f "dangling=true" -q`
if [ -n "$re" ];then
  docker rmi  -f `docker images -f "dangling=true" -q`
else
  echo ''
fi

Post-build Actions

添加Send build artifacts over SSH

SSH Server

#!bin/sh
mkdir -p  /home/deploy_script2/nledu-iotbd-ci/nledu-iotbd-ci-core/
cd /home/deploy_script2/nledu-iotbd-ci/nledu-iotbd-ci-core/
ls
echo "============upload over=============="
chmod +x jenkins-deployment.sh 
docker login imageserver:8082 -u用户名 -p密码
./jenkins-deployment.sh

while true
do
 re1=`curl  http://127.0.0.1:8806/actuator/health`
if [ $? -eq 0 ];then
  echo "+++++++++++"$re1
  break
fi
sleep 2
  
done

这里头会自动检测服务是否正常启动的脚本,注意观察

点击高级

勾选exec in pty ,不然执行脚本的时候不会自动退出

根据参数自动选择哪个ssh server

由于我这边添加了开发服务器和测试服务器,构建的时候,选择可以选择哪个环境来部署,就是通过env参数来控制的。

设置label

Name下的高级

label填入dev或者test,dev表示开发服务器,test表示测试服务器

Parameterized publishing

这个用来设置哪个参数来控制要发布的服务器, 这边是env参数。点Send build artifacts over SSH下的高级,如图所示

设置参数env

总结

最后选择保存就行了。
效果如图所示,选择branch为dev ,version变成latest,branch选择test,version变成1.0。env勾选开发环境就是部署到开发服务器,选择测试环境就是部署到测试服务器

测试

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您需要完成以下步骤来创建一个Jenkins + Vue的操作数据看板项目: 1. 创建一个Maven项目 ``` mvn archetype:generate -DgroupId=com.example -DartifactId=jenkins-dashboard -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false ``` 2. 添加以下依赖项到pom.xml文件中: ``` <dependencies> <dependency> <groupId>com.offbytwo.jenkins</groupId> <artifactId>jenkins-client</artifactId> <version>0.3.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> ``` 3. 创建一个名为“JenkinsClientService”的Java类,并添加以下代码: ``` import com.offbytwo.jenkins.JenkinsServer; import com.offbytwo.jenkins.model.Build; import com.offbytwo.jenkins.model.BuildResult; import com.offbytwo.jenkins.model.BuildWithDetails; import com.offbytwo.jenkins.model.Job; import org.springframework.stereotype.Service; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service public class JenkinsClientService { private JenkinsServer jenkins; public JenkinsClientService() throws URISyntaxException { jenkins = new JenkinsServer(new URI("http://localhost:8080"), "admin", "admin"); } public List<String> getJobs() throws IOException { Map<String, Job> jobs = jenkins.getJobs(); return jobs.values().stream().map(Job::getName).collect(Collectors.toList()); } public BuildWithDetails getLastBuild(String jobName) throws IOException { Job job = jenkins.getJob(jobName); Build lastBuild = job.getLastBuild(); return lastBuild.details(); } public BuildResult getBuildResult(String jobName, int buildNumber) throws IOException { Job job = jenkins.getJob(jobName); Build build = job.getBuildByNumber(buildNumber); return build.details().getResult(); } } ``` 请将“http://localhost:8080”,“admin”和“admin”替换为您的Jenkins服务器URL,用户名和密码。 4. 创建一个名为“JenkinsController”的Java类,并添加以下代码: ``` import com.offbytwo.jenkins.model.BuildResult; import com.offbytwo.jenkins.model.BuildWithDetails; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.List; @RestController public class JenkinsController { @Autowired private JenkinsClientService jenkinsClient; @GetMapping("/jobs") public List<String> getJobs() throws IOException { return jenkinsClient.getJobs(); } @GetMapping("/jobs/{jobName}/lastBuild") public BuildWithDetails getLastBuild(@PathVariable String jobName) throws IOException { return jenkinsClient.getLastBuild(jobName); } @GetMapping("/jobs/{jobName}/builds/{buildNumber}/result") public BuildResult getBuildResult(@PathVariable String jobName, @PathVariable int buildNumber) throws IOException { return jenkinsClient.getBuildResult(jobName, buildNumber); } } ``` 5. 创建一个名为“app.js”的Vue文件,并添加以下代码: ``` <template> <div id="app"> <h1>Jenkins Dashboard</h1> <ul> <li v-for="job in jobs" :key="job"> <h2>{{ job }}</h2> <p>Last build status: {{ getLastBuildStatus(job) }}</p> <button @click="buildJob(job)">Build now</button> </li> </ul> </div> </template> <script> import axios from 'axios'; export default { name: 'app', data() { return { jobs: [] } }, mounted() { axios.get('/jobs') .then(response => { this.jobs = response.data; }); }, methods: { getLastBuildStatus(jobName) { axios.get(`/jobs/${jobName}/lastBuild`) .then(response => { return response.data.result; }); }, buildJob(jobName) { axios.post(`/jobs/${jobName}/build`) .then(response => { console.log(response.data); }); } } } </script> ``` 6. 创建一个名为“index.html”的文件并添加以下代码: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Jenkins Dashboard</title> </head> <body> <div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="app.js"></script> </body> </html> ``` 7. 创建一个名为“App.java”的Java类,并添加以下代码: ``` import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } ``` 8. 运行以下命令启动应用程序: ``` mvn spring-boot:run ``` 现在,您已经创建了一个Jenkins + Vue操作数据看板项目。您可以通过在浏览器中打开“http://localhost:8080”来查看该应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值