Search code examples
pythonjenkinsjenkins-pipelinecode-coverage

Jenkins sudo: a terminal is required to read the password


I have a FastAPI app for which I have configured Jenkins pipeline. When I execute unit tests with the code coverage enabled they are failing with the following error :

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

Jenkinsfile

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/*.*'
            }                    
         }        

      }
}

I have added the line sudo chown -R jenkins:jenkins ./docs/unit-tests/htmlcoverage because I was facing a permissions error to the coverage file :

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

I have also verified that coverage.xml is under root user and not the regular jenkins user (What even causes this?) :

permissions

What I have tried :

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

This results in the same error 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

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

In both cases I have done a restart of the jenkins service. The jenkins user is also already added to sudo group.

What exactly am I missing ?


Solution

  • For anyone struggling with this - the problem was with rules precedence inside /etc/sudoers.

    By default if there are multiple entries for a user inside of the /etc/sudoers file, sudo uses the last rule that applies

    The change to jenkins user was being overridden because of the rule's position in /etc/sudoers :

    WRONGWRONG

    It is wrong because jenkins user is already a member of sudo group, and thus the line jenkins ALL=(ALL) NOPASSWD: ALL will be overriden by the line

    sudo ALL=(ALL:ALL) ALL
    

    CORRECT

    CORRECT