Golang编译失败问题排查与解决方法

Golang编译失败问题排查与解决方法 你好, 我正在处理一个关于 Jenkins 流水线的项目,但在最后一个阶段遇到了错误 “failed to initialize build cache at /.cache/go-build: mkdir /.cache: permission denied”。 请帮忙。

我的 Jenkinsfile

    #!/usr/bin/env groovy
   // The above line is used to trigger correct syntax highlighting.
   pipeline {
   agent any    
    stages {
    stage('Build & Test') {   
        // Use golang.
        agent { docker { image 'golang' } }

        steps {                                           
            // Create our project directory.
            sh 'cd ${GOPATH}/src'
            sh 'mkdir -p ${GOPATH}/src/PROJECT_DEVOPS'

            // Copy all files in our Jenkins workspace to our project directory.                
            sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/PROJECT_DEVOPS'
            // Build the app.
            sh 'go build'     
            
        }            
    }
}

更多关于Golang编译失败问题排查与解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

是的,我也这么认为,但我不知道该怎么做

更多关于Golang编译失败问题排查与解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


将这些变量设置为一个可写入的位置。

说实话,我是一名初级开发者,我明白您说的意思,但我不知道如何在 Jenkins 上实现它。

我对Jenkins也不太了解,不过如果你是一名初级开发者,应该会有一位指定的高级开发者,他的职责就是帮助你处理这类问题。

作为一个快速的解决方案,你可以在运行的shell脚本中直接使用 export 命令。

// 代码部分保持原样,不翻译

我的初步猜测是,Jenkins工作节点运行的环境既没有设置XDG_CACHE_DIR,也没有设置HOME。因此,由于XDG未设置,系统会使用$HOME/.cache作为后备方案。但由于HOME同样未设置,它扩展成了/.cache,而通常没有人对此目录拥有写入权限。

不过,这只是基于XDG规范的一个假设。

这并非一个确切的答案,但希望能有所帮助……你至少有两个选择。一是设置 GOCACHE="${WORKSPACE}"(Jenkins 中每个构建可写区域的名称)。在 1.12 版本之前,你可以设置 GOCACHE=off,但现在不行了。

使用 dir() 可能也会对你有益,类似这样:

run: {
runSafely ‘mkdir src’
dir(‘src’) {
git(url: ‘git@github.com:your/project.git’, branch: ‘master’,
credentialsId: yourCredentialsId())
sh “./scripts/build”
}
},

然后让你的构建脚本执行任何你需要的操作,因为它可以在 dir() 目录内进行写入。

希望对你有帮助。

这个错误是由于容器内用户权限不足导致的。Golang 容器默认以非 root 用户运行,无法在根目录创建 .cache 文件夹。

以下是解决方案:

方法1:设置正确的GOCACHE目录(推荐)

修改你的 Jenkinsfile,在 go build 前设置 GOCACHE 环境变量:

pipeline {
    agent any    
    stages {
        stage('Build & Test') {   
            agent { docker { image 'golang' } }
            
            environment {
                GOCACHE = '/go/.cache/go-build'
            }

            steps {                                           
                sh 'cd ${GOPATH}/src'
                sh 'mkdir -p ${GOPATH}/src/PROJECT_DEVOPS'
                sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/PROJECT_DEVOPS'
                sh 'cd ${GOPATH}/src/PROJECT_DEVOPS && go build'     
            }            
        }
    }
}

方法2:使用 root 用户运行容器

修改容器配置,使用 root 用户:

stage('Build & Test') {   
    agent { 
        docker { 
            image 'golang'
            args '-u root:root'  // 以 root 用户运行
        } 
    }
    
    steps {
        sh 'cd ${GOPATH}/src'
        sh 'mkdir -p ${GOPATH}/src/PROJECT_DEVOPS'
        sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/PROJECT_DEVOPS'
        sh 'cd ${GOPATH}/src/PROJECT_DEVOPS && go build'
    }            
}

方法3:创建缓存目录并设置权限

在构建步骤前创建缓存目录:

steps {                                           
    sh 'cd ${GOPATH}/src'
    sh 'mkdir -p ${GOPATH}/src/PROJECT_DEVOPS'
    sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/PROJECT_DEVOPS'
    
    // 创建缓存目录并设置权限
    sh 'mkdir -p /.cache/go-build'
    sh 'chmod 777 /.cache'
    
    sh 'cd ${GOPATH}/src/PROJECT_DEVOPS && go build'     
}

方法4:使用更完整的 Go 环境配置

environment {
    GOPATH = '/go'
    GOCACHE = '/go/.cache/go-build'
    GO111MODULE = 'auto'
}

steps {
    sh '''
        mkdir -p /go/src/PROJECT_DEVOPS
        cp -r ${WORKSPACE}/* /go/src/PROJECT_DEVOPS
        cd /go/src/PROJECT_DEVOPS
        go build -v
    '''
}

方法5:使用自定义 Dockerfile

创建自定义的 Golang 镜像:

FROM golang:latest
RUN mkdir -p /.cache/go-build && chmod 777 /.cache

然后在 Jenkinsfile 中使用这个镜像:

agent { docker { image 'your-custom-golang-image' } }

推荐使用方法1,这是最符合 Golang 容器最佳实践的方式。Golang 容器默认用户是 go(UID 1000),应该避免在根目录创建文件。

回到顶部