使用jenkins share library 中resource资源当作配置文件时环境变量作用域问题,以及出现的特殊现象

使用jenkins share library 中resource资源当作配置文件时环境变量作用域问题,以及出现的特殊现象

详细代码传送门 github链接

废话不多说,先上代码

#!groovy
@Library("jenkinslibrary") _ 


//变量使用测试

String aaa = "this is global string,can use to any where"
bbb = "this is global string too,can use to any where"
def ccc = "this also is global string,can use to any where"

pipeline{
    agent any
	stages{
    	stage("region1"){
    	    steps{
    	    	script{
					def serviceEnvConfig = libraryResource "com/javaProject/preProd/conf/test.groovy"
					writeFile encoding: 'UTF-8', file: 'service.groovy', text: serviceEnvConfig
				
					load 'service.groovy'
					

					String ddd = "only this region can use, can not use to another regions"
					
					def eee = "only this region can use too, can not use to another regions"
					
					fff = "i am the global var,can use to any where"
					
					env.ggg = ["this","is","string","not","list"]  //使用env变量,只能设置string类型数据,即使填写的是列表,也会转换为string
					
					
					///println
					println(ddd)
					println(eee)
					
					
    	    	}
    	    }
    	}
    	stage("region2"){
    	    steps{
    	    	script{
					println(aaa)
					println(bbb)
					println(ccc)
					
					println(env.ggg.getClass())   //string
					println(ggg.getClass())			//string

					dir(WORKSPACE){
					    String regiontest = "this var only use in this brackets"
					    println(regiontest)
					}

					// println(regiontest)  //exception
					//println(ddd)     //exception
					println(abc)
					println(abcPms)
					println(abcPms02)
					println(testString)
					println(testString02)
					println("addrString: " + addrString.getClass())
					println("addrlist: " + addrlist.getClass())
					
					//使用resource当作配置文件库时,出现的特殊现象
					dockerFile = libraryResource "com/javaProject/preProd/dockerfile/common.dockerfile"
					sh "echo \"${deploymentYamlFile}\" > test.yaml"   // 注意观察 test.yaml 和 test1.yaml 区别
					env.harbor_host = harbor_host
					env.JDK_V = JDK_V
					env.Port = Port
					env.dockerFile_start = dockerFile_start
					sh "echo \"${deploymentYamlFile}\" > test1.yaml"   // 注意观察 test.yaml 和 test1.yaml 区别
					sh """
						a=`ls /root/*`
						echo \$a
						"""
                                    // 注意 \$a
					
    	    	}
    	    }
    	}
    }
}

文件 com/javaProject/preProd/conf/test.groovy

addr = ["10.5","10.5","10.7"]
addr.each{println it}

numlist = [10,11,12]
numlist.each{println it}



//this is list
addrlist = ["10.0.0.1","10.0.0.2","10.0.0.3"]
//this is string type
env.addrString = ["10.0.0.1","10.0.0.2","10.0.0.3"]

String smallScope = "smallScope: only this file can use" //带String时,jenkinsfile引用会抛异常,本文件内可用
def smallScope02 = "smallScope2: only this file can use" //带def时,jenkinsfile引用会抛异常,本文件内可用

abc = "abc: this is global String"

abcPms = " ${abc} , abcPms: and test abc parmas"
abcPms02 = abc + ", abcPms02: and test abc parmas"

testString = "${smallScope},testString: can use in here"
testString02 = smallScope + ",testString: can use in here"


println(smallScope)
println(abc)
println(abcPms)
println(abcPms02)
println(testString)
println(testString02)
println(smallScope02)
println("addrString: " + addrString.getClass())
println("addrlist: " + addrlist.getClass())

//实例
harbor_host = "10.0.0.1"
JDK_V = "8"
Service = "test"
Port = "32161"
java_Xms = "1g"
java_Xmx = "1g"
java_Xmn = "512m"
MemConf = "-Xms${java_Xms} -Xmx${java_Xmx} -Xmn${java_Xmn}"
JAVA_OPTS = "-server ${MemConf} -XX:SurvivorRatio=8 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/ -Xloggc:/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M"
dockerFile_start = "java ${JAVA_OPTS} -Dserver.port=${Port} -Djava.security.egd=file:/dev/./urandom -jar /opt/${Service}.jar"

文件 com/javaProject/preProd/dockerfile/common.dockerfile

FROM ${harbor_host}/ehome/java:${JDK_V}
MAINTAINER deployer
WORKDIR ${target_dir}/target/
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
COPY *.jar /opt/${Service}.jar
EXPOSE ${Port}
ENTRYPOINT ${dockerFile_start}

直接上结论:

  • 在pipeline 外部使用环境变量,无论带变量类型定义还是不带,都是全局的
  • 在pipeline内部定义的变量,带类型定义的变量作用域只有当前大括号内能生效,出去就无效,resource中同样适用
  • 在pipeline内部定义的变量,不带类型定义的变量作用域是全局的。resource中同样适用
  • 在env.中定义的变量,一律为String类型,即使以[vars]括起来也会全部变为String类型
  • sh命令执行时使用${var}获取的是groovy变量,如果执行命令过程中生成了shell变量,调用时需要"$",添加反斜杠.
  • 通常情况下:sh 中都可以引用groovy的变量,即加env.或者不加都可获取
  • 本条是重点:当引用resource中文件时,如果文件中包含变量,并且不是groovy文件例如yaml文件,jenkins无法转化其中的变量为具体值,此时只能使用shell方式转化,但shell只识别env中的环境变量,换句话说,不带env前缀定义的变量,统统不能用在文件生成时

请自行测试查看测试结果,这里不贴log日志了

1赞