import hudson.plugins.throttleconcurrents.*
import jenkins.model.Jenkins
import groovy.json.JsonSlurper
import hudson.EnvVars;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
import hudson.util.DescribableList;
import jenkins.model.Jenkins;
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.TimeUnit;
@NonCPS
def createEnvironmentVariable(String key, String value){
println ("Creating Environment Variable QUOTA with value:" + value)
Jenkins instance = Jenkins.getInstance();
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties = instance.getGlobalNodeProperties();
List<EnvironmentVariablesNodeProperty> envVarsNodePropertyList = globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class);
EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = null;
EnvVars envVars = null;
if ( envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0 ) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty);
envVars = newEnvVarsNodeProperty.getEnvVars();
} else {
envVars = envVarsNodePropertyList.get(0).getEnvVars();
}
envVars.put(key, value)
instance.save()
}
createEnvironmentVariable("QUOTA", "100")
这段代码的作用是在 Jenkins Master 上设置一个全局环境变量,所有 Agent(节点)和后续的 Pipeline 都可以访问它。以下是详细解析:
1. 代码作用
这段 Groovy 脚本定义了一个函数 createEnvironmentVariable(String key, String value)
,用于在 Jenkins 全局配置 中添加或修改一个环境变量(key=value
)。
- 运行位置:在 Jenkins Master 上执行(因为
Jenkins.getInstance()
只能在 Master 上调用)。 - 影响范围:设置的环境变量对所有 Agent(节点)和后续的 Pipeline 构建生效(类似于
Jenkins → 系统管理 → 系统配置 → 全局属性 → 环境变量
)。
2. 代码逻辑解析
def createEnvironmentVariable(String key, String value) {
println("Creating Environment Variable ${key} with value: ${value}")
// 1. 获取 Jenkins 实例
Jenkins instance = Jenkins.getInstance();
// 2. 获取全局节点属性配置
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties = instance.getGlobalNodeProperties();
// 3. 检查是否已存在环境变量配置
List<EnvironmentVariablesNodeProperty> envVarsNodePropertyList = globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class);
EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = null;
EnvVars envVars = null;
// 4. 如果没有环境变量配置,则新建一个
if (envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty); // 添加到全局配置
envVars = newEnvVarsNodeProperty.getEnvVars(); // 获取内部的 EnvVars 对象
} else {
// 5. 如果已存在,直接使用第一个配置
envVars = envVarsNodePropertyList.get(0).getEnvVars();
}
// 6. 添加或更新环境变量
envVars.put(key, value);
// 7. 保存配置(否则不会生效)
instance.save();
}
关键点
Jenkins.getInstance()
- 只能在 Jenkins Master 上运行,Agent 上调用会报错。
- 用于获取 Jenkins 的全局配置对象。
globalNodeProperties
- 存储 Jenkins 的全局配置(如环境变量、工具位置等)。
- 这里操作的是
EnvironmentVariablesNodeProperty
,即全局环境变量。
EnvVars
- 类似
Map<String, String>
,存储键值对形式的环境变量。 - 通过
envVars.put(key, value)
添加或修改变量。
- 类似
instance.save()
- 必须调用,否则修改不会持久化到 Jenkins 配置文件(
config.xml
)。
- 必须调用,否则修改不会持久化到 Jenkins 配置文件(
3. 如何使用
(1) 在 Jenkins Pipeline 中调用
pipeline {
agent any
stages {
stage('Set Global Env Var') {
steps {
script {
// 调用函数设置全局变量
createEnvironmentVariable("QUOTA", "100")
echo "Global variable QUOTA set to 100"
}
}
}
}
}
(2) 在 Jenkins 脚本控制台(Script Console)中运行
- 进入 Jenkins → 系统管理 → 脚本命令行(
/script
)。 - 直接粘贴函数定义并调用:
createEnvironmentVariable("QUOTA", "100")
- 验证是否生效:
println(Jenkins.instance.getGlobalNodeProperties().getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)[0].getEnvVars())
4. 注意事项
- 权限要求
- 需要 管理员权限(因为修改的是全局配置)。
- 在 Pipeline 中使用时,确保脚本有
Jenkins.ADMINISTER
权限(通常需要@Library
或script
块)。
- 变量生效时机
- 设置后,新的 Pipeline 构建才能读取到变量(已运行的构建不会自动更新)。
- 如果需要在当前 Pipeline 内立即使用,建议同时通过
environment { ... }
或withEnv
设置。
- 替代方案
- 如果只是临时变量,建议用
withEnv
(仅影响当前步骤):withEnv(["QUOTA=100"]) { sh 'echo $QUOTA' // 仅在此代码块内生效 }
- 如果只是临时变量,建议用
5. 总结
- 用途:在 Jenkins Master 上设置全局环境变量,供所有 Agent 和 Pipeline 使用。
- 典型场景:动态配置全局参数(如服务地址、限流阈值、功能开关)。
- 慎用:滥用全局变量可能导致配置混乱,建议优先使用 Pipeline 局部变量或
credentials
。
如果有进一步问题(如权限管理、变量覆盖优先级等),可以继续探讨!