Jenkins LTS升级后工作区Groovy脚本路径哈希值问题咨询
Jenkins LTS升级后@script路径哈希目录问题解答
优先修复方案:不要硬编码拼接脚本路径,直接使用Pipeline内置步骤获取脚本根目录,完全不需要感知哈希值的存在,兼容所有新旧版本Jenkins。
修正后的工具脚本加载阶段代码如下:
stage('Load Utilities Scripts') { checkout scm echo "${JOB_NAME}" // 直接获取当前流水线脚本所在的根工作目录,自动适配路径规则变化 def scriptBasePath = pwd(script: true) modules.messages = load "${scriptBasePath}/pipelines/utils/slack_functions.groovy" modules.ansible = load "${scriptBasePath}/pipelines/utils/ansible_functions.groovy" modules.jenkins = load "${scriptBasePath}/pipelines/utils/jenkins_functions.groovy" modules.pic_env = load "${scriptBasePath}/pipelines/utils/pic_env.groovy" modules.maven = load "${scriptBasePath}/pipelines/utils/maven_functions.groovy" modules.git = load "${scriptBasePath}/pipelines/utils/git_functions.groovy" }
问题1:如何获取路径中的哈希字符串,是否有对应内置变量?
- 没有单独暴露这个哈希值的全局内置变量,官方也不建议直接读取、拼接这个哈希值。
- 如果确实需要获取该值,可以从
pwd(script: true)返回的路径中截取最后一级目录名即可,示例:
def scriptPath = pwd(script: true) def pathHash = scriptPath.substring(scriptPath.lastIndexOf('/') + 1)
- 额外说明:原有代码中硬编码
${jenkins_home}/workspace/前缀的写法本身存在兼容问题,在自定义工作目录、代理节点构建场景下会直接失效,用pwd(script: true)可以完全规避这类问题。另外Jenkins内置的作业名变量为全大写的JOB_NAME,原有代码中的job_name属于自定义变量,非官方内置。
问题2:该令牌由哪个组件生成、生成环节是哪里?
- 生成组件:该哈希值由Pipeline: Groovy插件(插件ID:workflow-cps) 生成,是该插件在较新版本中加入的安全加固特性,Jenkins LTS 2.361.x及之后的默认版本会携带该逻辑。
- 生成环节:当流水线从SCM完成Jenkinsfile及关联脚本的检出动作后、CPS引擎加载执行脚本前,插件会为当前脚本上下文生成对应哈希值,创建隔离的脚本存放目录,再将拉取到的脚本文件存入该目录后再执行加载逻辑。
问题3:是否支持手动配置该字符串?
- 不支持手动配置固定的哈希值,插件没有提供UI、系统属性、环境变量等入口让用户自定义该值。
- 如果要完全关闭该哈希目录逻辑、回退到旧版本直接使用
${job_name}@script目录的行为,可以在Jenkins启动参数中添加系统属性:
-Dorg.jenkinsci.plugins.workflow.cps.CpsScriptScriptAtOnAgent.DISABLE_SCRIPT_HASHED_WORKSPACES=true
非常不建议关闭该特性,会大幅提升脚本污染、路径遍历攻击的风险。
问题4:该字符串的实际含义是什么?
该字符串是长度为64位的SHA-256哈希值,核心作用有两点:
- 安全隔离:阻断路径遍历类攻击,避免恶意构造的脚本路径访问工作空间外的系统文件,同时隔离不同作业、不同执行节点的脚本上下文,避免越权访问。
- 版本隔离:同个作业不同构建拉取到不同版本的流水线脚本、工具类时,会存放在独立的哈希目录下,不会因为历史构建的脚本残留导致逻辑异常,构建结束后无用的哈希目录会被Jenkins自动清理,避免工作空间冗余文件堆积。
内容的提问来源于stack exchange,提问作者nletteron
相关产品推荐
相关产品推荐

