J'ai le Jenkinsfile suivant:

def notifySlack = { String color, String message ->
    slackSend(color: color, message: "${message}: Job ${env.JOB_NAME} [${env.BUILD_NUMBER}] (${env.BUILD_URL})")
}

node {
    try {
        notifySlack('#FFFF00', 'STARTED')
        stage('Checkout project') {
            checkout scm
        }
        scalaImage = docker.image('<myNexus>/centos-sbt:2.11.8')
        stage('Test project') {
            docker.withRegistry('<myNexus>', 'jenkins-nexus') {
                scalaImage.inside('-v /var/lib/jenkins/.ivy2:/root/.ivy2') { c ->
                    sh 'sbt clean test'
                }
            }
        }
        if (env.BRANCH_NAME == 'master') {
            stage('Release new version') {
                docker.withRegistry('<myNexus>', 'jenkins-nexus') {
                    scalaImage.inside('-v /var/lib/jenkins/.ivy2:/root/.ivy2') { c ->
                        sh 'sbt release'
                    }
                }
            }
        }
        notifySlack('#00FF00', 'SUCCESSFUL')
    } catch (e) {
        currentBuild.result = "FAILED"
        notifySlack('#FF0000', 'FAILED')
        throw e
    }

}

Malheureusement, lorsque j'atteins la ligne sbt clean test, je me retrouve avec l'erreur suivante:

java.lang.IllegalArgumentException: URI has a query component
    at java.io.File.<init>(File.java:427)
    at sbt.IO$.uriToFile(IO.scala:160)
    at sbt.IO$.toFile(IO.scala:135)
    at sbt.Classpaths$.sbt$Classpaths$$bootRepository(Defaults.scala:1942)
    at sbt.Classpaths$$anonfun$appRepositories$1.apply(Defaults.scala:1912)
    at sbt.Classpaths$$anonfun$appRepositories$1.apply(Defaults.scala:1912)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:34)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at sbt.Classpaths$.appRepositories(Defaults.scala:1912)
    at sbt.Classpaths$$anonfun$58.apply(Defaults.scala:1193)
    at sbt.Classpaths$$anonfun$58.apply(Defaults.scala:1190)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
    at sbt.EvaluateSettings$MixedNode.evaluate0(INode.scala:175)
    at sbt.EvaluateSettings$INode.evaluate(INode.scala:135)
    at sbt.EvaluateSettings$$anonfun$sbt$EvaluateSettings$$submitEvaluate$1.apply$mcV$sp(INode.scala:69)
    at sbt.EvaluateSettings.sbt$EvaluateSettings$$run0(INode.scala:78)
    at sbt.EvaluateSettings$$anon$3.run(INode.scala:74)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Si j'exécute le simple docker run ... suivi de docker exec, j'obtiens ce que je veux mais j'aimerais travailler avec la fonctionnalité Jenkins définie.

Cela semble donc être un problème SBT. J'utilise la version 0.13.16 dans l'image du docker. D'après ce que je comprends, le classpath contient un paramètre de requête que SBT:

  • n'aime pas
  • ne sait pas comment gérer
  • est illégal

Je n'ai mis moi-même aucun paramètre de requête de ce type, alors j'ai pensé que cette méthode .inside le faisait. J'ai vérifié le env dans le conteneur et trouvé une seule entrée RUN_CHANGES_DISPLAY_URL=<my_ip>/job/scheduler/job/fix-jenkins-pipeline/23/display/redirect?page=changes. J'ai essayé de unset mais je n'y suis pas parvenu.

Je suis à court d'idées et je ne suis pas vraiment sûr d'être dans la bonne direction. Toute aide serait appréciée.

12
zaxme 16 nov. 2017 à 13:40

4 réponses

Meilleure réponse

Donc, après des recherches longues et fastidieuses, ce qui a finalement fonctionné pour moi, c'est de définir explicitement le dossier .sbt et .ivy2 comme celui-ci dans le conteneur du docker:

sbt -Dsbt.global.base=.sbt -Dsbt.boot.directory=.sbt -Dsbt.ivy.home=.ivy2 clean test

Cela empêche en quelque sorte sbt de générer le dossier ? et place directement les dossiers susmentionnés à la racine de l'extraction du répertoire.

11
zaxme 24 nov. 2017 à 09:29

Le problème est que jenkins exécute un utilisateur spécifique à l'intérieur du conteneur. Mais le passer outre fait l'affaire.

withDockerContainer(args: "-u root -v ${HOME}/.sbt:/root/.sbt -v ${HOME}/.ivy2:/root/.ivy2 -e HOME=/root",
            image: 'xyz/sbt:v') {
0
Spangaer 1 févr. 2019 à 20:36

J'ai passé beaucoup de temps à retracer cela à travers le code.

Il semble que la solution la plus simple consiste simplement à passer -Duser.home=<path> à sbt, ou à le définir dans la variable d'environnement SBT_OPTS; alors tout le reste des répertoires sera construit comme si le <path> était le répertoire personnel de l'utilisateur.

0
Loki 6 déc. 2017 à 21:54

J'ai corrigé cela en définissant le répertoire de cache ivys -> Comment remplacer l'emplacement de Ivy's Cache?

Le problème était qu'il n'était pas défini et par défaut il crée un dossier ? qui en retour ne peut pas être géré par sbt lui-même.

J'ai créé un Dockerfile personnalisé pour avoir plus de contrôle sur sbt. Voici les étapes que j'ai exécutées pour résoudre le problème:

J'ai créé un fichier appelé ivysettings.xml avec le contenu suivant:

<ivysettings>
    <properties environment="env" />
    <caches defaultCacheDir="/home/jenkins/.ivy2/cache" />
</ivysettings>

Et un Dockerfile:

FROM openjdk:8

RUN wget -O- "http://downloads.lightbend.com/scala/2.11.11/scala-2.11.11.tgz" \
    | tar xzf - -C /usr/local --strip-components=1

RUN curl -Ls https://git.io/sbt > /usr/bin/sbt && chmod 0755 /usr/bin/sbt

RUN adduser -u 1000 --disabled-password --gecos "" jenkins

ADD ./files/ivysettings.xml /home/jenkins/.ivy2/ivysettings.xml
RUN chown -R jenkins:jenkins /home/jenkins

USER jenkins

CMD ["sbt"]

J'ai ensuite poussé l'image dans notre référentiel docker privé et notre pipeline fonctionne enfin!

0
Julian Pieles 17 nov. 2017 à 18:24
47327495