7
votes

Comment installer un pip dans une image Docker avec une étape de pipeline Jenkins?

J'ai ce Dockerfile

The directory '/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting pip
  Downloading https://files.pythonhosted.org/packages/d8/f3/413bab4ff08e1fc4828dfc59996d721917df8e8583ea85385d51125dceff/pip-19.0.3-py2.py3-none-any.whl (1.4MB)
Installing collected packages: pip
  Found existing installation: pip 19.0.2
Uninstalling pip-19.0.2:
Could not install packages due to an EnvironmentError: [Errno 13] 
Permission denied: '/usr/local/bin/pip'
Consider using the `--user` option or check the permissions.

et ce Jenkinsfile

pipeline {
agent {
    dockerfile {
        filename 'Dockerfile'
    }
}
stages {
    stage('Install') {
        steps {
            sh 'pip install --upgrade pip'
        }
    }
}
Cela provoque l'erreur suivante:
FROM python:3.7

CMD ["/bin/bash"]

J'ai essayé d'utiliser le --user , sans succès.

J'ai eu de la chance en utilisant args --user 0: 0 sur la déclaration docker jenkinsfile, mais cela crée des répertoires et des fichiers appartenant à root qui ne peuvent pas être supprimés par l'utilisateur Jenkins lors de la prochaine exécution.

Je ne veux pas faire l ' pip install sur le Dockerfile car en réalité l'étape d'installation exécute un fichier make au lieu de la simplification que j'ai utilisée ci-dessus, que je veux utiliser dans d'autres contextes.

J'ai également vu des conseils pour changer la var d'environnement HOME , et cela semble corriger les 2 premiers avertissements concernant le directoy parent n'appartenant pas à l'utilisateur actuel , mais pas la partie Errno 13 .


2 commentaires

Pourquoi ne pas faire cela dans la création de l'image avant son utilisation comme agent Jenkins? Ce serait les meilleures pratiques autour de cela et résoudre votre problème.


@MattSchuchard Comme je l'ai mentionné, je ne veux pas faire l'installation pip sur le Dockerfile car en réalité l'étape d'installation exécute un fichier make au lieu de la simplification que j'ai utilisée ci-dessus, que je veux utiliser dans d'autres contextes.


4 Réponses :


0
votes

Il semble que le problème soit davantage lié aux utilisateurs. Lorsque votre agent docker s'exécute avec l'utilisateur root et que vous mettez en scène cmd est en cours d'exécution avec l'utilisateur respectif configuré dans Jenkins (est-ce root?)

Créez un utilisateur similaire dans votre fichier docker et attribuez le conteneur en cours d'exécution à cet utilisateur.

Dockerfile

   FROM python:3.7

   ARG Jenkins_user=XXXXXX

   RUN useradd -ms /bin/bash $Jenkins_user

   USER $Jenkins_user

   CMD ["/bin/bash"] 

Modifié: Ici Jenkins_user sera avec lequel pip cmd s'exécute dans le conteneur. Pour vérifier l'utilisateur, vous pouvez mettre

sh 'echo $ USER'

Dans la section de l'étape d'installation. Et puis mettez à jour Dokerfile avec l'utilisateur exact.


0 commentaires

2
votes

Comme je l'ai mentionné dans ce commentaire , la solution devrait être d'ajouter un utilisateur approprié dans le conteneur. Jenkins utilise 984: 984 pour uid / gid sur ma machine (mais peut être différent sur la vôtre - connectez-vous à l'hôte sur lequel Jenkins s'exécute et exécutez sudo -u jenkins id -a code > pour les détecter), vous devez donc le répliquer dans le conteneur qui devrait être exécuté par Jenkins:

sh 'rm -f modified_file'

Bien sûr, puisque vous n'êtes pas la racine utilisateur dans le conteneur, créez un environnement virtuel:

$ docker run --user 0:984 ...

ou utilisez l'argument --user :

$ docker run --rm -it jenkins/python /bin/bash
jenkins@d0dc87c39810:~$ pip install --user --upgrade pip
jenkins@d0dc87c39810:~$ pip install --user numpy

etc.


Alternativement, vous pouvez (mais dans la plupart des cas ne devriez pas) entrer le conteneur en tant que root code >, mais avec le groupe jenkins :

$ docker run --rm -it jenkins/python /bin/bash
jenkins@d0dc87c39810:~$ python -m venv myenv
jenkins@d0dc87c39810:~$ source myenv/bin/activate
jenkins@d0dc87c39810:~$ pip install numpy

De cette façon, même si les fichiers modifiés changeront toujours le propriétaire, leur propriété de groupe sera toujours intacte, donc Jenkins pourra nettoyer les fichiers (ou vous pouvez le faire vous-même, via

FROM python:3.7

RUN mkdir /home/jenkins
RUN groupadd -g 984 jenkins
RUN useradd -r -u 984 -g jenkins -d /home/jenkins jenkins
RUN chown jenkins:jenkins /home/jenkins
USER jenkins
WORKDIR /home/jenkins

CMD ["/bin/bash"]

dans le Jenkinsfile .


2 commentaires

n'a pas fonctionné. Lors de l'exécution du dockerfile avec args '--user jenkins: jenkins' , ceci se produit: [Pipeline] sh sh: 1: impossible de créer /var/lib/jenkins/workspace/template.test4@ tmp / durable-07c23a‌ a9 / jenkins-log.txt: Autorisation refusée sh: 1: impossible de créer /var/lib/jenkins/workspace/template.test4@tmp/durable-07c23a‌ a9 / jenkins-result.tx‌ t .tmp: Autorisation refusée ce ne sont que les 2 premières erreurs, beaucoup d'erreurs similaires pour toujours, ont dû abandonner. sans l'argument --user, il n'a toujours aucune permission


J'ai vérifié mes hôtes CentOS / Fedora, il semble que Jenkins ait 984: 984 pour uid / gid. Vérifiez la mise à jour dans la réponse avec une commande pour les vérifier sur la vôtre.



-1
votes

Utilisation de python standard: image 3.8

stage('Unit test') {
    steps {
        sh '''
            python -m venv .venv
            . .venv/bin/activate
            pip intall -r requirements.txt
            pytest -v
        '''
     }
}


0 commentaires

0
votes

J'ai créé une solution dynamique pour ce problème en créant un utilisateur défini dans le conteneur Docker à l'aide de variables d'environnement de pipeline, dynamiquement . Vous pouvez trouver le modèle pour le Jenkinsfile et le Dockerfile sur mon GitHub .


0 commentaires