在"全局属性"中的Jenkins配置(http:// JenkinsURL/configure)中,我定义了一些"环境变量".
如何在Groovy Script控制台(http:// JenkinsURL/script)中访问它们?
我试图找到合适的解决方案(例如,在Jenkins构建步骤(Windows)中从Groovy脚本中访问构建环境变量的解决方案)但似乎它们都不适用于我.
我试过例如:
System.getenv("myVar")
Run Code Online (Sandbox Code Playgroud)
和
manager.build.getEnvironment(listener).get('myVar') //no manager error
Run Code Online (Sandbox Code Playgroud)
和
import jenkins.model.Jenkins
Jenkins.instance.getProperty('myVar') //No signature of method: hudson.model.Hudson.getProperty() is applicable for argument types: (java.lang.String)
Run Code Online (Sandbox Code Playgroud)
和
import jenkins.model.Jenkins
Jenkins.instance.ParameterValue("DEV_local")
Run Code Online (Sandbox Code Playgroud)
Cra*_*ger 14
它并不像您想象的那么简单,就像 Jenkins 中的所有内容一样。它似乎没有公开一个简单的 API 来获取当前执行上下文的最终有效环境,至少没有向脚本控制台公开。
这是您可以直接使用的打包版本,或者您可以进行一些修改以捆绑到vars/管道全局库中的类中。
import jenkins.model.Jenkins
import hudson.model.Node
import hudson.slaves.EnvironmentVariablesNodeProperty
import hudson.EnvVars
EnvVars getCombinedNodeEnvironment(Node node) {
/*
* Start with env-vars defined by the shell the JVM
* was started from and env-vars set as system properties.
*/
def combined = new EnvVars(node.toComputer().getEnvironment())
/*
* Apply environment variables from jenkins global settings
* ("Manage Jenkins" -> "Configure System" -> "Global Properties"
* -> "Environment Variables")
*/
combined.overrideExpandingAll(Jenkins.instance.
getGlobalNodeProperties().
get(EnvironmentVariablesNodeProperty).
getEnvVars() ?: new EnvVars())
/*
* Apply environment variables from node specific settings
* ("Manage Jenkins" -> "Manage Nodes and Clouds"
* -> {nodename} -> "Configure" -> "Node Properties"
* -> "Environment Variables")
*/
combined.overrideExpandingAll((node.
getNodeProperty(EnvironmentVariablesNodeProperty)?.
getEnvVars()) ?: new EnvVars())
/*
* Important: This environment map will NOT contain job-level,
* or run-level properties, nor anything set via build steps etc.
*/
return combined
}
EnvVars getCombinedNodeEnvironment(String nodename) {
if (nodename == 'master' || !nodename)
return getCombinedNodeEnvironment(Jenkins.instance)
else
return getCombinedNodeEnvironment(Jenkins.instance.getNode(nodename))
}
Run Code Online (Sandbox Code Playgroud)
用法:
getCombinedNodeEnvironment('somenode').expand('$JENKINS_HOME/$USER/$SOME_NODE_VARIABLE')
getCombinedNodeEnvironment('').SOME_ENV_VAR_ON_MASTER
Run Code Online (Sandbox Code Playgroud)
相关课程:
hudson.model.Nodejenkins.model.Jenkinshudson.EnvVarshudson.slaves.EnvironmentVariablesNodePropertyhudson.util.DescribableListarasio 的答案是一个好的开始,但假设 envvars 属性位于全局属性的索引 0 处是不正确的。该方法还忽略特定节点上本地设置的环境变量。
至少应该读作
jenkins.instance.Jenkins.instance.
getGlobalNodeProperties().
get(hudson.slaves.EnvironmentVariablesNodeProperty).
getEnvVars()
Run Code Online (Sandbox Code Playgroud)
即在结果中按类查找属性DescribableList,而不是假设索引。
但是,这只能从全局 jenkins 配置中的“环境变量”列表中获取环境变量- 它不会显示系统环境变量,也不会显示特定于节点的环境变量。
请继续阅读。
如果您使用 Groovy Pipeline,大多数时候您可以只使用env“变量”(请参阅管道帮助中的“全局变量参考”),它将统一环境公开为属性。如上所述,这不能直接从脚本控制台运行,但在其余时间,这是执行操作的适当方法。
您还可以env.getEnvironment()在管道脚本中使用来获取统一实例EnvVars,该实例用于字符串中环境变量的占位符替换,例如env.getEnvironment().expand('${FOO} $BAR')。(为此,您需要脚本安全权限,但最好将其放在全局库的帮助程序中vars/)。
大多数时候这就足够了。
我只是开始深入研究环境结构的细节,因为我需要扩展包含环境变量的字符串,因为它们将在不同的节点上扩展。这不是一个常见的用例。
这是最终的秘诀,但是我们是如何到达那里的,不同的环境变量集从哪里来,为什么?
对于以下代码示例,假设有这种常见的前奏,主要是为了节省每个示例中的重复。
/* Jenkins uses '' for the master node */
nodenames = ['', 'some-other-node-name']
/* Imports used in various examples */
import jenkins.model.Jenkins
import hudson.slaves.EnvironmentVariablesNodeProperty
import hudson.EnvVars
nodes = nodenames.collect { nodename ->
(!nodename || nodename == 'master') ?
Jenkins.instance : Jenkins.instance.getNode(nodename)
import static groovy.json.JsonOutput.toJson
import static groovy.json.JsonOutput.prettyPrint
def eachNode(Closure c) {
nodes.collectEntries { node -> [node.nodeName, c(node, node.nodeName) ] }
def fmtEnv(desc,m) {
print "\n\n${desc}\n----\n" + m.collect { k, v -> "${k?:'master'}:\n\t${trimKeys(v)}" }.join('\n')
}
def trimKeys(l) {
if (l == null)
return l
if (l in Map)
l = l.keySet()
l = l - ['_', 'OLDPWD', 'PWD', 'SSH_CLIENT', 'JAVA_HOME', 'LANG', 'LOGNAME', 'MAIL', 'MANPATH', 'S_COLORS', 'SHLVL', 'XDG_RUNTIME_DIR', 'XDG_SESSION_ID']
l.sort()
}
Run Code Online (Sandbox Code Playgroud)
nodes现在包含jenkins.model.Jenkins主节点和hudson.model.Node工作节点。
eachNode生成节点名称到环境变量键缩写列表的映射,只是为了使示例更简短且更易于阅读。不要在您的代码中使用它。
为了帮助阐明这些示例的结果,我NODE1_SPECIFIC_ENVVAR在“管理 Jenkins”->“管理节点和云”-> [节点名称] -> 配置 -> 环境变量下的 Node1 节点设置中进行了配置。
在同一位置的主节点条目上,我已经配置MASTER_SPECIFIC_ENVVAR
在“管理詹金斯”->“配置系统”->“全局属性”->“环境变量”中,我添加了“ALL_NODES_ENVVAR”。
我没有费心在 JVM 级别为节点和主节点设置自定义环境变量。
现在,让我们以不同的方式探索环境。
在 master 上,System.getenv()仅显示 JVM 启动时设置的环境变量或作为系统属性设置的环境变量:
fmtEnv('System.getenv()', ['': System.getenv()])
/*
master:
[HOME, JENKINS_HOME, PATH, SHELL, USER]
*/
Run Code Online (Sandbox Code Playgroud)
因此,每个节点、詹金斯本身或每个作业都没有配置任何配置。
Jenkins 在其 API 中公开每个节点上设置的基本环境变量。System.getEnv()我认为这与在目标节点 JVM 上执行时返回的结果相同:
fmtEnv('toComputer.getEnvironment()', eachNode() {
node, name -> node.toComputer().getEnvironment()
})
/*
master:
[HOME, JENKINS_HOME, PATH, SHELL, USER]
ci-node-qa-fsn1-01:
[HOME, PATH, SHELL, SSH_CONNECTION, USER]
*/
Run Code Online (Sandbox Code Playgroud)
请注意 Jenkins 中缺少全局或特定于节点的环境变量设置。
fmtEnv('master getGlobalNodeProperties', ['':
Jenkins.instance.
getGlobalNodeProperties().
get(EnvironmentVariablesNodeProperty).
getEnvVars()
])
/*
master getGlobalNodeProperties
----
master:
[ALL_NODES_ENVVAR]
*/
Run Code Online (Sandbox Code Playgroud)
因此,这里我们只看到全局配置的环境属性,而不是特定于节点的属性、系统属性或主机环境变量。
fmtEnv('node getNodeProperty', eachNode() {
node, name -> node.getNodeProperty(EnvironmentVariablesNodeProperty)?.getEnvVars()
})
/*
master:
[MASTER_SPECIFIC_ENVVAR]
ci-node-qa-fsn1-01:
[NODE1_SPECIFIC_ENVVAR]
*/
Run Code Online (Sandbox Code Playgroud)
在这里,我们在“管理节点”中看到每个节点下配置的属性,但看不到主机环境变量、系统属性中的变量、标准 jenkins 作业变量或 jenkins 全局配置中配置的变量。
重要提示:如果节点上没有配置自定义环境变量,getNodeProperty(EnvironmentVariablesNodeProperty)则返回,因此您必须处理该问题。null
上面显示了如何获取EnvVars在脚本控制台上有意义的环境变量的主要来源的实例。
运行作业时还有其他来源,我在这里不考虑,例如作业属性(EnvInject 插件)、添加到所有作业的自动环境变量、withEnvironment步骤、SCM 插件注入的变量等。但是它们对于脚本控制台任务没有意义。
那么我们如何获得一个统一的环境呢?
首先,收集EnvVars环境的每个相关部分:
def node_base_env = node.toComputer().getEnvironment()
def global_env_properties = Jenkins.instance.
getGlobalNodeProperties().
get(EnvironmentVariablesNodeProperty).
getEnvVars()
def node_env_properties = node.getNodeProperty(EnvironmentVariablesNodeProperty)?.getEnvVars() ?: new EnvVars()
def merged = new EnvVars(node_base_env)
merged.overrideExpandingAll(global_env_properties)
merged.overrideExpandingAll(node_env_properties)
merged
/*
master:
[ALL_NODES_ENVVAR, HOME, JENKINS_HOME, MASTER_SPECIFIC_ENVVAR, PATH, SHELL, USER]
ci-node-qa-fsn1-01:
[ALL_NODES_ENVVAR, HOME, NODE1_SPECIFIC_ENVVAR, PATH, SHELL, SSH_CONNECTION, USER]
*/
Run Code Online (Sandbox Code Playgroud)
我很确定这会产生正确的结果。我还没有详细测试扩展处理、优先级覆盖顺序或扩展顺序。
(注意:我删除了另一个使用的示例EnvironmentExpander)。
ara*_*sio 11
您可以获得如下全局属性:
def envVars = Jenkins.instance.getGlobalNodeProperties()[0].getEnvVars()
println envVars['myVar']
Run Code Online (Sandbox Code Playgroud)
我参考了下面的链接,关于如何以编程方式设置全局属性. https://groups.google.com/forum/#!topic/jenkinsci-users/KgCGuDmED1Q
| 归档时间: |
|
| 查看次数: |
17799 次 |
| 最近记录: |