Jenkins sudo:需要一个终端来读取密码

问题描述 投票:0回答:1

我有一个 FastAPI 应用程序,我已经为其配置了 Jenkins 管道。当我在启用代码覆盖率的情况下执行单元测试时,它们失败并出现以下错误:

Started by user gold
Obtained Jenkinsfile from git https://github.com/edtshuma/devsecops-labs.git
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/Python-DevSecOps
....
....
[Pipeline] sh
+ pip install -r requirements.txt
....
Requirement already satisfied: uvicorn==0.20.0 in ./.pyenv-usr-bin-python3.8/lib/python3.8/site-packages (from -r requirements.txt (line 41)) (0.20.0)
Requirement already satisfied: watchfiles==0.18.1 in ./.pyenv-usr-bin-python3.8/lib/python3.8/site-packages (from -r requirements.txt (line 42)) (0.18.1)
Requirement already satisfied: websockets==10.4 in ./.pyenv-usr-bin-python3.8/lib/python3.8/site-packages (from -r requirements.txt (line 43)) (10.4)
+ sudo chown -R jenkins:jenkins ./docs/unit-tests/htmlcoverage
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
[Pipeline] }
[Pipeline] // withPythonEnv

詹金斯文件

pipeline {
 agent any
  
triggers {
    githubPush()
}
stages {
    
    stage('Setup'){
       steps{
       withPythonEnv('/usr/bin/python3.8') {
            sh 'echo "Job is starting" '
        }            
        }
     }    
stage('Unit Tests'){ 
           steps{
               withPythonEnv('/usr/bin/python3.8') {
                 sh '''pip install -r requirements.txt
                       sudo chown -R jenkins:jenkins ./docs/unit-tests/htmlcoverage
                       pytest -v --junitxml=docs/unit-tests/htmlcoverage/coverage.xml --cov-report xml --cov app.main
                '''
             }           
            }                    
         }                
       stage('Publish Test Report'){ 
           steps{
              cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: 'coverage*.xml', conditionalCoverageTargets: '70, 0, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '80, 0, 0', maxNumberOfBuilds: 0, methodCoverageTargets: '80, 0, 0', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false
              archiveArtifacts artifacts: 'docs/unit-tests/htmlcoverage/*.*'
            }                    
         }        

      }
}

我添加了行 sudo chown -R jenkins:jenkins ./docs/unit-tests/htmlcoverage 因为我面临覆盖文件的权限错误:

INTERNALERROR> PermissionError: [Errno 13] Permission denied: 'coverage.xml'

我还验证了 coverage.xml 在 root 用户下,而不是普通的 jenkins 用户(甚至是什么原因造成的?):

我尝试过的:

echo “jenkins ALL=(ALL) NOPASSWD: ALL” >> /etc/sudoers

这导致相同的错误

sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper

echo “jenkins ALL= NOPASSWD: ALL” >> /etc/sudoers

这也会导致同样的错误

sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper

在这两种情况下,我都重新启动了 jenkins 服务。 jenkins 用户也已经添加到 sudo 组。

我到底错过了什么?

python jenkins jenkins-pipeline code-coverage
1个回答
0
投票

docs
文件夹是root权限的,需要root权限清理,可以添加一个临时stage来清理,如下所示,一旦你确定你的管道不会使用root,你可以删除临时stage

stage('Clean Test Report') {
    steps {
        sh '''
            docker run -t \
                -u root \
                -v "$(pwd)":/"$(pwd)" \
                --entrypoint='' \
                <what ever a docker image> \
                rm -rf docs
        '''
    }
}

stage('Unit Tests'){ 
   steps{
       withPythonEnv('/usr/bin/python3.8') {
         sh '''
            ls -al
            pip install -r requirements.txt
            pytest -v \
                --junitxml=docs/unit-tests/htmlcoverage/coverage.xml \
                --cov-report xml \
                --cov app.main
        '''
     }           
    }                    
}

要防止管道以 root 身份运行容器,您可以执行以下操作

# run container in sh step
docker run \
  -u $(id -u):$(id -g) \
  -v /etc/passwd:/etc/passwd \
  <other options as you need>

# run container by docker global variable
container = docker.image(<image>).run('-u $(id -u):$(id -g) -v /etc/passwd:/etc/passwd -t', 'cat')

# specify agent to docker container, it runs container as current host user by default
agent {
   docker {
     args: '-v/etc/passwd:/etc/passwd'
   }   
}

agent {
   dockerfile {
     args: '-v/etc/passwd:/etc/passwd'
   }   
}
© www.soinside.com 2019 - 2024. All rights reserved.