当前位置: 首页 > 知识库问答 >
问题:

如何在Groovy脚本控制台中获取Jenkins环境变量?

沈德寿
2023-03-14

在“全局属性”中的 Jenkins 配置 (http://JenkinsURL/configure) 中,我定义了一些“环境变量”。

如何在Groovy脚本控制台(http://JenkinsURL/script)中访问它们?

我试图找到合适的解决方案(例如:在Jenkins构建步骤(Windows)中从groovy脚本中访问构建环境变量),但似乎没有一个适合我。

我尝试过例如:

System.getenv("myVar")

manager.build.getEnvironment(listener).get('myVar') //no manager error

import jenkins.model.Jenkins
Jenkins.instance.getProperty('myVar') //No signature of method: hudson.model.Hudson.getProperty() is applicable for argument types: (java.lang.String)

import jenkins.model.Jenkins
Jenkins.instance.ParameterValue("DEV_local")

共有3个答案

祁正阳
2023-03-14

您可以使用< code>System来获取环境变量

def env = System.getenv()
println(env['JENKINS_HOME'])

(另请参阅http://@ myJenkHostname @/env-vars . html(其中< code>@myJenkHostname@是您的Jenkins主机名)以获取内置环境变量列表。)

斜瑞
2023-03-14

这并不像你想象的那么简单,就像詹金斯的一切一样。它似乎没有公开一个简单的API来获得当前执行上下文的最终有效环境,至少没有向脚本控制台公开。

这里有一个打包的版本,您可以直接使用,也可以稍加修改,捆绑到管道全局库中的< code>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))
}

用法:

getCombinedNodeEnvironment('somenode').expand('$JENKINS_HOME/$USER/$SOME_NODE_VARIABLE')

getCombinedNodeEnvironment('').SOME_ENV_VAR_ON_MASTER

相关类:

  • hudson.model.Node
  • Jenkins.model.Jenkins
  • 哈德森。环境变量
  • hudson.slaves.EnvironmentVariablesNodeProperty
  • hudson.util.DescibleList

arasio 的答案是一个好的开始,但假设 envvars 属性将位于全局属性的索引 0 是不正确的。该方法还会忽略在特定节点上本地设置的环境变量。

至少应该是这样的

jenkins.instance.Jenkins.instance.
   getGlobalNodeProperties().
   get(hudson.slaves.EnvironmentVariablesNodeProperty).
   getEnvVars() 

即在描述列表结果中按类查找属性,而不是假设索引。

但是,这只会从全局jenkins配置中的“环境变量”列表中获取环境变量——它不会显示系统环境变量,也不会显示特定于节点的环境变量。

请继续阅读。

如果您使用的是Groovy管道,大多数时候您只需使用env“变量”(请参见管道帮助中的“全局变量引用”),它将统一环境公开为属性。如上所述,这不会直接从脚本控制台工作,但在其他时间,这是正确的做法。

您也可以使用<code>env。管道脚本中的getEnvironment(),以获得统一的EnvVarsinstance,该实例用于字符串中env-vars的占位符替换,例如env.getEnvironmental()。展开(“${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()
}

现在包含了jenkins.model.Jenkinsmaster和hudson.model.Node工作节点。

eachNode生成节点名称到环境变量键缩写列表的映射,只是为了使示例更简短、更易于阅读。不要在代码中使用它。

为了帮助澄清这些示例的结果,我在 node1 的节点设置中的“管理 Jenkins”下配置了NODE1_SPECIFIC_ENVVAR -

在相同位置的主节点条目上,我已经配置了< code > MASTER _ SPECIFIC _ env var

在“管理詹金斯”中-

我没有费心在JVM级别为节点和master设置自html" target="_blank">定义环境变量。

现在,让我们以不同的方式探索环境。

在master上,< code>System.getenv()仅显示JVM启动时设置的环境变量或系统属性:

fmtEnv('System.getenv()', ['': System.getenv()])

/* 
master:
    [HOME, JENKINS_HOME, PATH, SHELL, USER]
*/

因此,没有为每个节点、在jenkins中全局或每个作业配置任何内容。

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]
*/

请注意,Jenkins中没有设置全局或特定于节点的环境变量。

fmtEnv('master getGlobalNodeProperties', ['': 
  Jenkins.instance.
     getGlobalNodeProperties().
     get(EnvironmentVariablesNodeProperty).
     getEnvVars()
])

/*
master getGlobalNodeProperties
----
master:
    [ALL_NODES_ENVVAR]
*/

因此,此处我们仅看到全局配置的环境属性,而看不到特定于节点的属性、系统属性或主机环境变量。

fmtEnv('node getNodeProperty', eachNode() {
  node, name -> node.getNodeProperty(EnvironmentVariablesNodeProperty)?.getEnvVars()
})

/*
master:
    [MASTER_SPECIFIC_ENVVAR]
ci-node-qa-fsn1-01:
    [NODE1_SPECIFIC_ENVVAR]
*/

在这里,我们看到在“管理节点”中的每个节点下配置的属性,但不是主机环境变量、系统属性中的变量、标准jenkins作业变量或jenkins全局配置中配置的变量。

重要提示:如果节点上没有配置自定义环境变量,getNodeProperty(EnvironmentVariablesNodeProperty)将返回 null,因此您必须处理该变量。

上面显示了如何为在脚本控制台上有意义的环境变量的主要来源获取< code>EnvVars实例。

在运行作业时,我不考虑其他来源,例如作业属性(EnvInject插件)、添加到所有作业的自动环境变量、<code>withEnvironment</code>步骤、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]
 */

我很确定这会产生正确的结果。我还没有详细测试扩展处理、优先级覆盖顺序或扩展顺序。

(注意:我删除了另一个使用EnvironmentExpander的示例)。

锺宜
2023-03-14

您可以像这样获得全局属性:

import jenkins.model.Jenkins
def envVars = Jenkins.instance.getGlobalNodeProperties()[0].getEnvVars() 
println envVars['myVar']

我参考了下面的链接,关于如何以编程方式设置全局属性。https://groups.google.com/forum/#!topic/jenkinsci-users/KgCGuDmED1Q

 类似资料:
  • 问题内容: 在“全局属性”中的Jenkins配置(http:// JenkinsURL/configure)中,我定义了一些“环境变量”。 如何在Groovy脚本控制台(http:// JenkinsURL / script)中访问它们? 我试图找到合适的解决方案(例如:[在Jenkins构建步骤(Windows)中从groovy脚本访问构建环境变量中]提到的解决方案),但似乎它们都不适合我。 我

  • 我为这个问题搜索了很多,但在任何地方都找不到可行的解决方案。有人能帮我吗?我想通过jenkins脚本控制台获取现有的环境变量值。

  • 我需要从Jenkins作业中获取脚本路径。 请查看下面的屏幕截图,以便更清楚地了解需求。 我已经登录谷歌,获取了一些Groovy控制台脚本,其中列出了每个作业的详细信息。 通过使用jenkins.model.Jenkins.getJobNames()方法,我能够得到Jenkins中的所有作业,但实际上需要的是获得Scriptpath值,在每个作业中提到。 哪个Jenkins类/方法可以提供这些细节

  • 我们有一个Jenkins构建,它在Jenkins1.596.2上成功运行,我们正在迁移到运行Jenkins2.60.1的新构建机器 作为构建配置的一部分,我们有一个可扩展的Choice参数,并使用系统Groovy Choice参数作为选择提供者。然后,我们使用Groovy脚本获取选择列表。 此Groovy脚本需要访问Jenkins构建环境变量之一,该变量设置在构建配置的全局属性部分(在环境变量下)

  • 我创建了一个java程序来进行ssh连接,并使用scp进行文件传输。我在jenkins中添加了用户名、主机名和密码作为环境变量。我需要在java程序中访问这些环境变量的值。 我尝试在我的java文件中使用以下选项,但它不起作用。 由于一些安全问题,我无法使用EnvironmentInjectorPlugin。你能给我指一下正确的方向吗。

  • 我必须从我的 Groovy 脚本访问一个环境变量。我没有使用詹金斯。如何获取变量?