├── .gitignore ├── Dockerfile ├── README.md ├── config ├── default-auth.yaml ├── jenkins.yaml ├── job-dsl-seed.yaml └── secrets.yaml ├── docker-compose.yaml ├── env ├── jobs.groovy ├── jobs ├── bisect.jpl ├── build-trigger.jpl ├── build.jpl ├── monitor.jpl ├── rootfs-builder.jpl ├── rootfs-trigger.jpl └── test-runner.jpl ├── plugins-base.txt ├── plugins-extra.txt ├── restart-compose.sh ├── scripts ├── buildroot-builder.sh ├── kernel-arch-complete.sh └── push-source.py └── src └── org └── kernelci └── util └── Job.groovy /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG jenkins_docker_image=jenkins/jenkins:latest 2 | FROM $jenkins_docker_image 3 | 4 | ARG config=/config 5 | COPY plugins*.txt /usr/share/jenkins/ref/ 6 | RUN cat /usr/share/jenkins/ref/plugins*.txt > /usr/share/jenkins/ref/plugins-all.txt 7 | RUN /bin/jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins-all.txt 8 | COPY $config /config/ 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Jenkins Docker container with Config-as-Code 2 | ============================================ 3 | 4 | This repository contains the [Jenkins 5 | Config-as-Code](https://www.jenkins.io/projects/jcasc/) (JCasC) YAML needed to 6 | create a pre-configured Jenkins Docker container, and the `job-dsl` Groovy code 7 | for generating the KernelCI jobs. There are some sample `docker-compose` 8 | environment files with variables used for production, staging, and development. 9 | 10 | ## Prerequisites 11 | 12 | This Jenkins project is used to run a full KernelCI pipeline automatically. It 13 | needs at least a 14 | [`kernelci-backend`](https://github.com/kernelci/kernelci-backend) instance to 15 | be able to publish kernel builds, and typically at least one 16 | [LAVA](https://www.lavasoftware.org/) lab instance to run tests. Installing 17 | those things is not covered here, please refer to their corresponding 18 | documentation. 19 | 20 | ## Configuration 21 | 22 | * Copy the `env` file to `.env` and edit it with your own settings 23 | * Add any extra plugins (`github-auth`, `openstack` etc) to the 24 | [`plugins-extra.txt`](plugins-extra.txt) file and they will be included in 25 | the build. 26 | * Add your LAVA lab credentials in [`config/secrets.yaml`](config/secrets.yaml) 27 | * Any CasC YAML files that exist in the `config` directory will also be 28 | loaded, so you can create your own. 29 | * Jenkins nodes should be configured in `config/nodes.yaml` (you will have to 30 | create this). 31 | * Add any extra parameters you've used in your config to `.env`. 32 | * Edit the `ADMIN_PASSWORD` in `.env`. 33 | 34 | ## Usage 35 | 36 | Then the container can be used using regular `docker-compose` commands. Here 37 | are a few examples: 38 | * `docker-compose up --build` 39 | * **action**: start the container in the foreground 40 | * **notes**: useful when testing the configuration 41 | 42 | * `docker-compose up --build -d` 43 | * **action**: start the container in the background 44 | * **notes**: typical usage to keep the service running 45 | 46 | * `docker-compose stop` 47 | * **action**: stop the container 48 | * **notes**: useful when editing the configuration 49 | 50 | * `docker-compose down` 51 | * **action**: destroy the container 52 | * **notes**: WARNING: any jobs data or manual Jenkins configuration will be 53 | lost 54 | 55 | * `docker-compose logs -f jenkins` 56 | * **action**: read the Jenkins logs 57 | * **notes**: useful for monitoring activity 58 | 59 | * `docker-compose exec jenkins bash` 60 | * **action**: start an interactive shell in the running container 61 | * **notes**: useful to debug problems by accessing files directly 62 | 63 | Initially a single job is created, this is the DSL seed job which can be used 64 | to create all the other ones defined in [`jobs.groovy`](jobs.groovy). Open the 65 | Jenkins web UI and start this job to see the other ones listed below appear on 66 | the Jenkins instance. 67 | 68 | ## Jenkins jobs 69 | 70 | All the automated jobs on kernelci.org are run in Jenkins. Some legacy scripts 71 | are still being used in "freestyle" projects but they are gradually being 72 | replaced with Pipeline jobs. Each Pipeline job has a `.jpl` file located in 73 | the `jenkins` directory: 74 | 75 | * [`jenkins/monitor.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/monitor.jpl) to monitor kernel branches and detect new revisions 76 | * [`jenkins/build-trigger.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/build-trigger.jpl) to trigger all the builds for a kernel revision 77 | * [`jenkins/build.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/build.jpl) to build a single kernel 78 | * [`jenkins/test-runner.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/test-runner.jpl) to run tests for a single kernel build 79 | * [`jenkins/bisect.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/bisect.jpl) to run automated test bisections 80 | * [`jenkins/rootfs-trigger.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/rootfs-trigger.jpl) to trigger a series of rootfs image builds 81 | * [`jenkins/rootfs-builder.jpl`](https://github.com/kernelci/kernelci-jenkins/tree/master/jobs/rootfs-builder.jpl) to build a single rootfs image 82 | 83 | In addition to the job files, there are also some common library files located 84 | in the 85 | [`src/org/kernelci`](https://github.com/kernelci/kernelci-core/tree/master/src/org/kernelci) 86 | directory. 87 | -------------------------------------------------------------------------------- /config/default-auth.yaml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | authorizationStrategy: 3 | loggedInUsersCanDoAnything: 4 | allowAnonymousRead: true 5 | securityRealm: 6 | local: 7 | allowsSignup: false 8 | enableCaptcha: false 9 | users: 10 | - id: "admin" 11 | password: "${ADMIN_PASSWORD}" 12 | -------------------------------------------------------------------------------- /config/jenkins.yaml: -------------------------------------------------------------------------------- 1 | # jenkins base config 2 | jenkins: 3 | systemMessage: "KernelCI Jenkins configuration\n\n" 4 | numExecutors: 1 5 | labelString: "" 6 | scmCheckoutRetryCount: 0 7 | mode: NORMAL 8 | 9 | security: 10 | globaljobdslsecurityconfiguration: 11 | useScriptSecurity: false 12 | 13 | # kernelci pipeline library 14 | unclassified: 15 | globalLibraries: 16 | libraries: 17 | - defaultVersion: "${KCI_JENKINS_BRANCH}" 18 | name: "kernelci" 19 | retriever: 20 | modernSCM: 21 | scm: 22 | git: 23 | remote: "${KCI_JENKINS_URL}" 24 | 25 | location: 26 | adminAddress: info@kernelci.org 27 | url: "${JENKINS_URL}" 28 | 29 | # jenkins needs too know git is installed 30 | tool: 31 | git: 32 | installations: 33 | - home: "git" 34 | name: "Default" 35 | -------------------------------------------------------------------------------- /config/job-dsl-seed.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | job('job-dsl') { 4 | scm { 5 | git { 6 | branch('${KCI_JENKINS_BRANCH}') 7 | remote { 8 | url('${KCI_JENKINS_URL}') 9 | } 10 | } 11 | } 12 | triggers { 13 | scm('H/5 * * * *') 14 | } 15 | steps { 16 | dsl { 17 | external('jobs.groovy') 18 | removeAction('DELETE') 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/secrets.yaml: -------------------------------------------------------------------------------- 1 | credentials: 2 | system: 3 | domainCredentials: 4 | - credentials: 5 | - string: 6 | description: "COMPANY LAVA Token" 7 | id: "lab-company-lava-api" 8 | scope: GLOBAL 9 | secret: "${LAVA_COMPANY_TOKEN}" 10 | - string: 11 | description: "KernelCI API Upload token" 12 | id: "api-token" 13 | scope: GLOBAL 14 | secret: "${KCI_API_TOKEN}" 15 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | jenkins: 4 | environment: 5 | - ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} 6 | - CASC_JENKINS_CONFIG=/config/ 7 | - PLUGINS_FORCE_UPGRADE=true 8 | env_file: 9 | - .env 10 | build: 11 | context: . 12 | args: 13 | jenkins_docker_image: ${JENKINS_DOCKER_IMAGE:-jenkins/jenkins:latest} 14 | config: ${CASC_JENKINS_CONFIG_SOURCE:-/config} 15 | ports: 16 | - "${JENKINS_PORT:-8080}:8080" 17 | - "50000:50000" 18 | -------------------------------------------------------------------------------- /env: -------------------------------------------------------------------------------- 1 | # kernelci-core repo 2 | KCI_CORE_BRANCH=master 3 | KCI_CORE_URL=https://github.com/kernelci/kernelci-core 4 | 5 | # kernelci-jenkins repo 6 | KCI_JENKINS_BRANCH=master 7 | KCI_JENKINS_URL=https://github.com/kernelci/kernelci-jenkins 8 | 9 | # kernelci-backend API and storage 10 | KCI_API_URL=https:// 11 | KCI_API_TOKEN= 12 | KCI_API_TOKEN_ID=kci-api-token 13 | KCI_STORAGE_URL=http:// 14 | 15 | # bisection 16 | KCI_BISECTION_CALLBACK_ID=kernel-ci-bisection-webhook 17 | KCI_BISECTION_EMAIL_RECIPIENTS= 18 | KCI_BISECTION_TREES_WHITELIST=mainline stable next 19 | KCI_BISECTION_LABS_WHITELIST= 20 | 21 | # common job parameters 22 | KCI_CONFIG_LIST=kernelci_staging 23 | KCI_LABS_LIST= 24 | KCI_CALLBACK_ID=kernel-ci-callback 25 | KCI_DOCKER_BASE=kernelci/ 26 | 27 | # system 28 | JENKINS_URL=https://:8080 29 | JENKINS_PORT=8002 30 | JENKINS_DOCKER_IMAGE=jenkins/jenkins:2.222.4 31 | ADMIN_PASSWORD= 32 | CASC_JENKINS_CONFIG_SOURCE=/data/ 33 | -------------------------------------------------------------------------------- /jobs.groovy: -------------------------------------------------------------------------------- 1 | def KCI_CORE_BRANCH = System.getenv("KCI_CORE_BRANCH") 2 | def KCI_CORE_URL = System.getenv("KCI_CORE_URL") 3 | def KCI_STORAGE_URL = System.getenv("KCI_STORAGE_URL") 4 | def KCI_STORAGE_CONFIG = System.getenv("KCI_STORAGE_CONFIG") 5 | def KCI_STORAGE_CRED = System.getenv("KCI_STORAGE_CRED") 6 | def KCI_DB_CONFIG = System.getenv("KCI_DB_CONFIG") 7 | def KCI_API_URL = System.getenv("KCI_API_URL") 8 | def KCI_API_TOKEN_ID = System.getenv("KCI_API_TOKEN_ID") 9 | def KCI_DOCKER_BASE = System.getenv("KCI_DOCKER_BASE") 10 | def KCI_CONFIG_LIST = System.getenv("KCI_CONFIG_LIST") 11 | def KCI_LABS_LIST = System.getenv("KCI_LABS_LIST") 12 | def KCI_CALLBACK_ID = System.getenv("KCI_CALLBACK_ID") 13 | def KCI_BISECTION_CALLBACK_ID = System.getenv("KCI_BISECTION_CALLBACK_ID") 14 | def KCI_BISECTION_EMAIL_RECIPIENTS = System.getenv("KCI_BISECTION_EMAIL_RECIPIENTS") 15 | def KCI_BISECTION_TREES_WHITELIST = System.getenv("KCI_BISECTION_TREES_WHITELIST") 16 | def KCI_BISECTION_LABS_WHITELIST = System.getenv("KCI_BISECTION_LABS_WHITELIST") 17 | def KCI_MONITOR_CRON = System.getenv("KCI_MONITOR_CRON") 18 | def KCI_JENKINS_BRANCH = System.getenv("KCI_JENKINS_BRANCH") 19 | def KCI_JENKINS_ROOTFS_BRANCH = System.getenv("KCI_JENKINS_ROOTFS_BRANCH") 20 | def KCI_JENKINS_URL = System.getenv("KCI_JENKINS_URL") 21 | 22 | pipelineJob('kernel-tree-monitor') { 23 | definition { 24 | cpsScm { 25 | lightweight(true) 26 | scm { 27 | git { 28 | branch(KCI_JENKINS_BRANCH) 29 | remote { 30 | url(KCI_JENKINS_URL) 31 | } 32 | } 33 | } 34 | scriptPath('jobs/monitor.jpl') 35 | } 36 | if (KCI_MONITOR_CRON) { 37 | triggers { 38 | cron(KCI_MONITOR_CRON) 39 | } 40 | } 41 | } 42 | logRotator { 43 | daysToKeep(7) 44 | numToKeep(200) 45 | } 46 | parameters { 47 | stringParam('CONFIG_LIST', KCI_CONFIG_LIST, 'List of build configs to check instead of all the ones in build-configs.yaml.') 48 | stringParam('KCI_API_URL', KCI_API_URL, 'URL of the KernelCI back-end API.') 49 | stringParam('KCI_API_TOKEN_ID', KCI_API_TOKEN_ID, 'Identifier of the KernelCI backend API token stored in Jenkins.') 50 | stringParam('KCI_STORAGE_CONFIG', KCI_STORAGE_CONFIG, 'Name of the KernelCI storage configuration.') 51 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the build images.') 52 | } 53 | } 54 | 55 | pipelineJob('kernel-build-trigger') { 56 | definition { 57 | cpsScm { 58 | lightweight(true) 59 | scm { 60 | git { 61 | branch(KCI_JENKINS_BRANCH) 62 | remote { 63 | url(KCI_JENKINS_URL) 64 | } 65 | } 66 | } 67 | scriptPath('jobs/build-trigger.jpl') 68 | } 69 | } 70 | configure { project -> 71 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 72 | 'switch'('on') 73 | } 74 | } 75 | logRotator { 76 | daysToKeep(7) 77 | numToKeep(48) 78 | } 79 | parameters { 80 | stringParam('BUILD_CONFIG', '', 'Name of the build configuration.') 81 | stringParam('COMMIT_ID', '', 'Git commit SHA1 at the revision of the snapshot') 82 | booleanParam('PUBLISH', true, 'Publish build results via the KernelCI backend API') 83 | booleanParam('EMAIL', true, 'Send build results via email') 84 | stringParam('LABS_WHITELIST', KCI_LABS_LIST, 'List of labs to include in the tests, all labs will be tested by default.') 85 | stringParam('KCI_API_URL', KCI_API_URL, 'URL of the KernelCI Backend API') 86 | stringParam('KCI_API_TOKEN_ID', KCI_API_TOKEN_ID, 'Identifier of the KernelCI backend API token stored in Jenkins.') 87 | stringParam('KCI_STORAGE_CONFIG', KCI_STORAGE_CONFIG, 'Name of the KernelCI storage configuration.') 88 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the build images.') 89 | booleanParam('ALLOW_REBUILD', false, 'Allow building the same revision again.') 90 | } 91 | } 92 | 93 | pipelineJob('kernel-build') { 94 | definition { 95 | cpsScm { 96 | lightweight(true) 97 | scm { 98 | git { 99 | branch(KCI_JENKINS_BRANCH) 100 | remote { 101 | url(KCI_JENKINS_URL) 102 | } 103 | } 104 | } 105 | scriptPath('jobs/build.jpl') 106 | } 107 | } 108 | configure { project -> 109 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 110 | 'switch'('on') 111 | } 112 | } 113 | logRotator { 114 | daysToKeep(2) 115 | numToKeep(4096) 116 | } 117 | parameters { 118 | stringParam('ARCH', '', 'CPU architecture as understood by the Linux kernel build system') 119 | stringParam('DEFCONFIG', '', 'Linux kernel defconfig to build') 120 | stringParam('SRC_TARBALL', '', 'URL of the kernel source tarball') 121 | stringParam('BUILD_CONFIG', '', 'Name of the build configuration') 122 | stringParam('GIT_DESCRIBE', '', "Output of 'git describe' at the revision of the snapshot") 123 | stringParam('GIT_DESCRIBE_VERBOSE', '', "Verbose output of 'git describe' at the revision of the snapshot") 124 | stringParam('COMMIT_ID', '', 'Git commit SHA1 at the revision of the snapshot') 125 | stringParam('BUILD_ENVIRONMENT', 'gcc-8', 'Name of the build environment') 126 | stringParam('NODE_LABEL', '', 'Label to use to choose a node on which to run this job') 127 | booleanParam('PUBLISH', true, 'Publish build results via the KernelCI backend API') 128 | booleanParam('EMAIL', true, 'Send build results via email') 129 | stringParam('KCI_DB_CONFIG', KCI_DB_CONFIG, 'Value to use with the --db-config argument') 130 | stringParam('KCI_API_URL', KCI_API_URL, 'URL of the KernelCI back-end API.') 131 | stringParam('KCI_API_TOKEN_ID', KCI_API_TOKEN_ID, 'Identifier of the KernelCI backend API token stored in Jenkins.') 132 | stringParam('KCI_STORAGE_URL', KCI_STORAGE_URL, 'URL of the KernelCI storage server.') 133 | stringParam('KCI_STORAGE_CONFIG', KCI_STORAGE_CONFIG, 'Name of the KernelCI storage configuration.') 134 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the build images.') 135 | stringParam('PARALLEL_BUILDS', '4', 'Number of kernel builds to run in parallel') 136 | } 137 | } 138 | 139 | job('kernel-arch-complete') { 140 | label('build-complete') 141 | logRotator { 142 | daysToKeep(7) 143 | numToKeep(100) 144 | } 145 | wrappers { 146 | preBuildCleanup() 147 | credentialsBinding { 148 | string('EMAIL_AUTH_TOKEN', KCI_API_TOKEN_ID) 149 | } 150 | } 151 | parameters { 152 | stringParam('TREE_NAME', '', 'Name of the tree to be tested') 153 | stringParam('GIT_DESCRIBE', '', "Output of 'git describe' at the revision of the snapshot") 154 | booleanParam('PUBLISH', true, 'Publish build results via the KernelCI backend API') 155 | booleanParam('EMAIL', true, 'Send build results via email') 156 | stringParam('BRANCH', '', '') 157 | stringParam('API', KCI_API_URL, 'URL of the KernelCI backend API.') 158 | } 159 | steps { 160 | shell(""" 161 | #!/bin/bash 162 | 163 | set -e 164 | 165 | rm -rf kernelci-jenkins 166 | git clone --depth 1 -b ${KCI_JENKINS_BRANCH} ${KCI_JENKINS_URL} 167 | ./kernelci-jenkins/scripts/kernel-arch-complete.sh 168 | """) 169 | } 170 | } 171 | 172 | pipelineJob('test-runner') { 173 | definition { 174 | cpsScm { 175 | lightweight(true) 176 | scm { 177 | git { 178 | branch(KCI_JENKINS_BRANCH) 179 | remote { 180 | url(KCI_JENKINS_URL) 181 | } 182 | } 183 | } 184 | scriptPath('jobs/test-runner.jpl') 185 | } 186 | } 187 | configure { project -> 188 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 189 | 'switch'('on') 190 | } 191 | } 192 | logRotator { 193 | daysToKeep(1) 194 | numToKeep(1024) 195 | } 196 | parameters { 197 | stringParam('LABS', '', 'Names of the labs where to submit tests') 198 | stringParam('TRIGGER_JOB_NAME', 'kernel-build-trigger', 'Name of the parent trigger job') 199 | stringParam('TRIGGER_JOB_NUMBER', '', 'Number of the parent trigger job') 200 | stringParam('BUILD_JOB_NAME', 'kernel-build', 'Name of the job that built the kernel') 201 | stringParam('BUILD_JOB_NUMBER', '', 'Number of the job that built the kernel') 202 | stringParam('KCI_STORAGE_URL', KCI_STORAGE_URL, 'URL of the KernelCI storage server.') 203 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the build images.') 204 | stringParam('CALLBACK_ID', KCI_CALLBACK_ID, 'Identifier of the callback to look up an authentication token') 205 | stringParam('CALLBACK_URL', KCI_API_URL, 'Base URL where to send the callbacks') 206 | } 207 | } 208 | 209 | pipelineJob('rootfs-build-trigger') { 210 | definition { 211 | cpsScm { 212 | lightweight(true) 213 | scm { 214 | git { 215 | branch(KCI_JENKINS_ROOTFS_BRANCH) 216 | remote { 217 | url(KCI_JENKINS_URL) 218 | } 219 | } 220 | } 221 | scriptPath('jobs/rootfs-trigger.jpl') 222 | } 223 | } 224 | configure { project -> 225 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 226 | 'switch'('on') 227 | } 228 | } 229 | logRotator { 230 | daysToKeep(7) 231 | numToKeep(200) 232 | } 233 | parameters { 234 | stringParam('KCI_CORE_URL', KCI_CORE_URL, 'URL of the kernelci-core repository.') 235 | stringParam('KCI_CORE_BRANCH', KCI_CORE_BRANCH, 'Name of the branch to use in the kernelci-core repository.') 236 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the rootfs build images.') 237 | stringParam('ROOTFS_CONFIG','','Name of the rootfs configuration, all rootfs will be built by default. Cannot be used with ROOTFS_TYPE') 238 | stringParam('ROOTFS_ARCH','','List of the rootfs arch configs, all given archs will be built by default.') 239 | stringParam('ROOTFS_TYPE','','List of the rootfs type config, all types will be built by default. Cannot be used with ROOTFS_CONFIG') 240 | stringParam('PIPELINE_VERSION','','Unique string identifier for the series of rootfs build jobs.') 241 | } 242 | } 243 | 244 | pipelineJob('rootfs-builder') { 245 | definition { 246 | cpsScm { 247 | lightweight(true) 248 | scm { 249 | git { 250 | branch(KCI_JENKINS_ROOTFS_BRANCH) 251 | remote { 252 | url(KCI_JENKINS_URL) 253 | } 254 | } 255 | } 256 | scriptPath('jobs/rootfs-builder.jpl') 257 | } 258 | } 259 | configure { project -> 260 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 261 | 'switch'('on') 262 | } 263 | } 264 | logRotator { 265 | daysToKeep(7) 266 | numToKeep(200) 267 | } 268 | parameters { 269 | stringParam('KCI_API_TOKEN_ID', KCI_API_TOKEN_ID, 'Identifier of the KernelCI backend API token stored in Jenkins.') 270 | stringParam('KCI_STORAGE_CONFIG', KCI_STORAGE_CONFIG, 'Name of the KernelCI storage configuration.') 271 | stringParam('KCI_CORE_URL', KCI_CORE_URL, 'URL of the kernelci-core repository.') 272 | stringParam('KCI_CORE_BRANCH', KCI_CORE_BRANCH, 'Name of the branch to use in the kernelci-core repository.') 273 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the rootfs build images.') 274 | stringParam('ROOTFS_CONFIG','','Name of the rootfs configuration, all rootfs will be built by default.') 275 | stringParam('ROOTFS_ARCH','','Name of the rootfs arch config, all given arch will be built by default.') 276 | stringParam('ROOTFS_TYPE','debos','Name of the rootfs type which can be debos or buildroot.') 277 | stringParam('PIPELINE_VERSION','','Unique string identifier for the series of rootfs build jobs.') 278 | } 279 | } 280 | 281 | /* 282 | pipelineJob('lava-bisection') { 283 | definition { 284 | cpsScm { 285 | lightweight(true) 286 | scm { 287 | git { 288 | branch(KCI_JENKINS_BRANCH) 289 | remote { 290 | url(KCI_JENKINS_URL) 291 | } 292 | } 293 | } 294 | scriptPath('jobs/bisect.jpl') 295 | } 296 | } 297 | configure { project -> 298 | project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty' { 299 | 'switch'('on') 300 | } 301 | } 302 | logRotator { 303 | daysToKeep(7) 304 | numToKeep(200) 305 | } 306 | parameters { 307 | stringParam('KERNEL_URL', '', 'URL of the kernel Git repository') 308 | stringParam('KERNEL_BRANCH', '', 'Name of the branch to bisect in the kernel Git repository') 309 | stringParam('KERNEL_TREE', '', 'Name of the kernel Git repository (tree)') 310 | stringParam('KERNEL_NAME', '', 'Identifier of the kernel (typically `git describe`)') 311 | stringParam('GOOD_COMMIT', '', 'Good known Git revision (SHA1 or any valid reference)') 312 | stringParam('BAD_COMMIT', '', 'Bad known Git revision (SHA1 or any valid reference)') 313 | stringParam('REF_KERNEL_URL', 314 | 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git', 315 | 'URL of the reference kernel Git repository used to find merge bases') 316 | stringParam('REF_KERNEL_BRANCH', 'master', 'Name of the branch from the reference kernel Git repository') 317 | stringParam('REF_KERNEL_TREE', 'mainline', 'Name of the reference kernel Git repository') 318 | stringParam('ARCH', '', 'CPU architecture as understood by the Linux kernel build system') 319 | stringParam('DEFCONFIG', 'defconfig', 'Name of the Linux kernel defconfig') 320 | stringParam('TARGET', '', 'Name of the device type to test (typically LAVA device type name)') 321 | stringParam('BUILD_ENVIRONMENT', '', 'Name of the build environment') 322 | stringParam('LAB', '', 'Name of the lab in which to run the bisection tests') 323 | stringParam('TEST_PLAN_VARIANT', '', 'Name of the KernelCI test plan variant (e.g. baseline_qemu)') 324 | stringParam('TEST_CASE', '', 'Test case path in dotted syntax (e.g. baseline.dmesg.crit)') 325 | stringParam('TEST_RUNS', '1', 'Number of LAVA jobs to run before considering pass or fail.') 326 | stringParam('KCI_API_URL', KCI_API_URL, 'URL of the KernelCI back-end API.') 327 | stringParam('KCI_API_TOKEN_ID', KCI_API_TOKEN_ID, 'Identifier of the KernelCI backend API token stored in Jenkins.') 328 | stringParam('KCI_STORAGE_CONFIG', KCI_STORAGE_CONFIG, 'Name of the KernelCI storage configuration.') 329 | stringParam('KCI_STORAGE_URL', KCI_STORAGE_URL, 'URL of the KernelCI storage server.') 330 | stringParam('KCI_DB_CONFIG', KCI_DB_CONFIG, 'Value to use with the --db-config argument') 331 | stringParam('DOCKER_BASE', KCI_DOCKER_BASE, 'Dockerhub base address used for the build images.') 332 | stringParam('LAVA_CALLBACK', KCI_BISECTION_CALLBACK_ID, 'Description of the LAVA auth token to look up and use in LAVA callbacks') 333 | stringParam('EMAIL_RECIPIENTS', KCI_BISECTION_EMAIL_RECIPIENTS, 'List of recipients for all emails generated by this job') 334 | stringParam('LABS_WHITELIST', KCI_BISECTION_LABS_WHITELIST, 'If defined, jobs will abort if the LAB is not on that list.') 335 | stringParam('TREES_WHITELIST', KCI_BISECTION_TREES_WHITELIST, 'If defined, jobs will abort if the KERNEL_TREE is not on that list.') 336 | } 337 | } 338 | */ -------------------------------------------------------------------------------- /jobs/bisect.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2017-2021 Collabora Limited 5 | Author: Guillaume Tucker 6 | 7 | This module is free software; you can redistribute it and/or modify it under 8 | the terms of the GNU Lesser General Public License as published by the Free 9 | Software Foundation; either version 2.1 of the License, or (at your option) 10 | any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this library; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* ---------------------------------------------------------------------------- 23 | * Jenkins parameters 24 | 25 | The following parameters need to be defined in the Jenkins pipeline job, with 26 | typical default values in brackets: 27 | 28 | KERNEL_URL 29 | URL of the kernel Git repository 30 | KERNEL_BRANCH 31 | Name of the branch to bisect in the kernel Git repository 32 | KERNEL_TREE 33 | Name of the kernel Git repository (tree) 34 | KERNEL_NAME 35 | Identifier of the kernel (typically `git describe`) 36 | GOOD_COMMIT 37 | Good known Git revision (SHA1 or any valid reference) 38 | BAD_COMMIT 39 | Bad known Git revision (SHA1 or any valid reference) 40 | REF_KERNEL_URL (git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git) 41 | URL of the reference kernel Git repository used to find merge bases 42 | REF_KERNEL_BRANCH (master) 43 | Name of the branch from the reference kernel Git repository 44 | REF_KERNEL_TREE (mainline) 45 | Name of the reference kernel Git repository 46 | ARCH 47 | CPU architecture as understood by the Linux kernel build system 48 | DEFCONFIG (defconfig) 49 | Name of the Linux kernel defconfig 50 | TARGET 51 | Name of the device type to test (typically LAVA device type name) 52 | BUILD_ENVIRONMENT 53 | Name of the build environment 54 | LAB 55 | Name of the lab in which to run the bisection tests 56 | TEST_PLAN_VARIANT 57 | Name of the KernelCI test plan variant (e.g. baseline_qemu) 58 | TEST_CASE 59 | Test case path in dotted syntax (e.g. baseline.dmesg.crit) 60 | TEST_RUNS (1) 61 | Number of LAVA jobs to run before considering pass or fail. 62 | KCI_API_URL (https://api.kernelci.org) 63 | URL of the KernelCI backend API 64 | KCI_API_TOKEN_ID 65 | Identifier of the KernelCI backend API token stored in Jenkins 66 | KCI_STORAGE_CONFIG (storage.kernelci.org) 67 | Name of the KernelCI storage configuration 68 | KCI_STORAGE_URL (https://storage.kernelci.org/) 69 | URL of the KernelCI storage server 70 | KCI_DB_CONFIG (kernelci.org) 71 | Name of the database config (--db-config argument) 72 | DOCKER_BASE (kernelci/) 73 | Dockerhub base address used for the build images 74 | LAVA_CALLBACK (kernel-ci-callback) 75 | Description of the LAVA auth token to look up and use in LAVA callbacks 76 | EMAIL_RECIPIENTS 77 | List of recipients for all emails generated by this job 78 | LABS_WHITELIST 79 | If defined, jobs will abort if the LAB is not on that list. 80 | TREES_WHITELIST 81 | If defined, jobs will abort if the KERNEL_TREE is not on that list. 82 | 83 | */ 84 | 85 | 86 | @Library('kernelci') _ 87 | import org.kernelci.util.Job 88 | 89 | /* Working around some seemingly broken Python set-up... */ 90 | def eggCache() { 91 | def egg_cache = env.WORKSPACE + "/python-egg-cache" 92 | sh(script: "mkdir -p ${egg_cache}") 93 | return egg_cache 94 | } 95 | 96 | /* ---------------------------------------------------------------------------- 97 | * git utilities 98 | */ 99 | 100 | def getSHA(kdir) { 101 | def sha 102 | 103 | dir(kdir) { 104 | sha = sh(script: "git rev-parse HEAD", returnStdout: true) 105 | } 106 | 107 | return sha 108 | } 109 | 110 | def gitDescribe(kdir) { 111 | def describe 112 | 113 | dir(kdir) { 114 | describe = sh(script: "git describe", returnStdout: true).trim() 115 | } 116 | 117 | return describe 118 | } 119 | 120 | def createTag(kdir, iteration) { 121 | def tag = gitDescribe(kdir) 122 | 123 | dir(kdir) { 124 | tag += "-${env.JOB_NAME}-${currentBuild.number}-${iteration}" 125 | sh(script: "git tag -a ${tag} -m ${tag} HEAD") 126 | } 127 | 128 | return tag 129 | } 130 | 131 | def removeTag(kdir, tag) { 132 | dir(kdir) { 133 | sh(script: "git tag -d ${tag}") 134 | } 135 | } 136 | 137 | def checkoutRevision(git_dir, git_rev) { 138 | dir(git_dir) { 139 | sh(script: """ 140 | git clean -fd && \ 141 | git checkout --detach ${git_rev} 142 | """) 143 | } 144 | } 145 | 146 | def setRemote(kdir, name, url) { 147 | dir(kdir) { 148 | sh(script: """ 149 | if git remote | grep -e '^${name}\$'; then 150 | git remote set-url ${name} ${url} 151 | git remote update ${name} 152 | git remote prune ${name} 153 | else 154 | git remote add ${name} ${url} 155 | git remote update ${name} 156 | fi 157 | """) 158 | } 159 | } 160 | 161 | /* ---------------------------------------------------------------------------- 162 | * cloning projects 163 | */ 164 | 165 | def cloneLinux(kdir) { 166 | print("""\ 167 | Initialising kernel tree 168 | url: ${params.KERNEL_URL} 169 | branch: ${params.KERNEL_BRANCH} 170 | path: ${kdir}""") 171 | 172 | def is_git = !sh(returnStatus: true, script: "test -d ${kdir}/.git") 173 | def is_valid = (is_git && 174 | !sh(returnStatus: true, script: "cd ${kdir}; git status")) 175 | 176 | if (is_valid) { 177 | setRemote(kdir, params.KERNEL_TREE, params.KERNEL_URL) 178 | } else { 179 | if (is_git) { 180 | print("Broken Git clone, recreating ${kdir}") 181 | sh(script: "rm -rf ${kdir}") 182 | } 183 | 184 | sh(script: """ 185 | git clone ${params.KERNEL_URL} ${kdir} \ 186 | -b ${params.KERNEL_BRANCH} \ 187 | -o ${params.KERNEL_TREE} 188 | """) 189 | } 190 | 191 | dir(kdir) { 192 | sh(script: """ 193 | git config user.name 'kernelci.org bot' 194 | git config user.email bot@kernelci.org 195 | git reset --hard 196 | echo 'build-*' > .git/info/exclude 197 | git clean -fd 198 | git bisect reset || echo -n 199 | git checkout --detach HEAD || echo -n 200 | git branch -D ${params.KERNEL_BRANCH} || echo -n 201 | for t in \$(git tag -l | grep ${env.JOB_NAME}); do git tag -d \$t; done 202 | git fetch ${params.KERNEL_TREE} ${params.KERNEL_BRANCH} --tags -f 203 | git checkout ${params.BAD_COMMIT} -b ${params.KERNEL_BRANCH} 204 | git symbolic-ref HEAD refs/heads/${params.KERNEL_BRANCH} 205 | """) 206 | } 207 | } 208 | 209 | /* ---------------------------------------------------------------------------- 210 | * kernel build 211 | */ 212 | 213 | def buildKernel(kdir) { 214 | def output = "${kdir}/build-${params.ARCH}-${params.BUILD_ENVIRONMENT}" 215 | sh(script: "rm -f ${env._BMETA_JSON}") 216 | sh(script: "rm -f ${env._ARTIFACTS_JSON}") 217 | 218 | sh(script: """\ 219 | for d in \$(find ${kdir} -name "build-*" -type d); do 220 | [ "\$d" = "${output}" ] || rm -rf "\$d" 221 | done 222 | """) 223 | 224 | sh(script: """\ 225 | kci_build \ 226 | generate_defconfig_fragments \ 227 | --defconfig=${params.DEFCONFIG} \ 228 | --kdir=${kdir} \ 229 | """) 230 | 231 | def expanded_defconfig = sh(script: """\ 232 | kci_build \ 233 | expand_fragments \ 234 | --defconfig=${params.DEFCONFIG} \ 235 | """, returnStdout: true).trim() 236 | 237 | sh(script: """\ 238 | kci_build \ 239 | init_bmeta \ 240 | --kdir=${kdir} \ 241 | --output=${output} \ 242 | --tree-name=${params.KERNEL_TREE} \ 243 | --tree-url=${params.KERNEL_URL} \ 244 | --install \ 245 | --branch=${params.KERNEL_BRANCH} \ 246 | --arch=${params.ARCH} \ 247 | --build-env=${params.BUILD_ENVIRONMENT} \ 248 | """) 249 | 250 | sh(script: """\ 251 | kci_build \ 252 | make_config \ 253 | --kdir=${kdir} \ 254 | --output=${output} \ 255 | --install \ 256 | --defconfig=${expanded_defconfig} \ 257 | """) 258 | 259 | sh(script: """\ 260 | kci_build \ 261 | fetch_firmware \ 262 | --kdir=${kdir} \ 263 | --output=${output} \ 264 | --install \ 265 | """) 266 | 267 | sh(script: """\ 268 | kci_build \ 269 | make_kernel \ 270 | --kdir=${kdir} \ 271 | --output=${output} \ 272 | --install \ 273 | """) 274 | 275 | sh(script: """\ 276 | kci_build \ 277 | make_modules \ 278 | --kdir=${kdir} \ 279 | --output=${output} \ 280 | --install \ 281 | """) 282 | 283 | sh(script: """\ 284 | kci_build \ 285 | make_dtbs \ 286 | --kdir=${kdir} \ 287 | --output=${output} \ 288 | --install \ 289 | """) 290 | 291 | sh(script: """\ 292 | kci_build \ 293 | make_kselftest \ 294 | --kdir=${kdir} \ 295 | --output=${output} \ 296 | --install \ 297 | """) 298 | 299 | withCredentials([string(credentialsId: params.KCI_API_TOKEN_ID, 300 | variable: 'SECRET')]) { 301 | sh(script: """\ 302 | kci_build \ 303 | push_kernel \ 304 | --kdir=${kdir} \ 305 | --storage-config=${KCI_STORAGE_CONFIG} \ 306 | --storage-cred=${SECRET} \ 307 | --output=${output} \ 308 | """) 309 | } 310 | 311 | dir("${output}/_install_") { 312 | stash(name: env._BMETA_JSON, includes: env._BMETA_JSON) 313 | stash(name: env._ARTIFACTS_JSON, includes: env.ARTIFACTS_JSON) 314 | } 315 | } 316 | 317 | def buildRevision(kdir, git_rev, name) { 318 | checkoutRevision(kdir, git_rev) 319 | def tag = createTag(kdir, name) 320 | buildKernel(kdir) 321 | return tag 322 | } 323 | 324 | /* ---------------------------------------------------------------------------- 325 | * kernel test with LAVA v2 326 | */ 327 | 328 | def fetchLabInfo() { 329 | def token = "${params.LAB}-lava-api" 330 | def retry = 3 331 | 332 | while (retry--) { 333 | try { 334 | withCredentials([string(credentialsId: token, 335 | variable: 'SECRET')]) { 336 | sh(script: """\ 337 | kci_test \ 338 | get_lab_info \ 339 | --runtime-config=${params.LAB} \ 340 | --runtime-json=${env._LAB_JSON} \ 341 | --user=kernel-ci \ 342 | --runtime-token=${SECRET} \ 343 | """) 344 | retry = 0 345 | } 346 | } catch (error) { 347 | if (retry) 348 | print("Error with ${lab}: ${error}, retrying...") 349 | else 350 | throw error 351 | } 352 | } 353 | stash(name: env._LAB_JSON, includes: env._LAB_JSON) 354 | } 355 | 356 | def submitJob(describe, hook) { 357 | sh(script: """\ 358 | rm -f ${env._BMETA_JSON} \ 359 | rm -f ${env._ARTIFACTS_JSON} \ 360 | rm -f ${env._LAB_JSON} \ 361 | """) 362 | unstash(env._BMETA_JSON) 363 | unstash(env._ARTIFACTS_JSON) 364 | unstash(env._LAB_JSON) 365 | 366 | def egg_cache = eggCache() 367 | def token = "${params.LAB}-lava-api" 368 | 369 | /* ToDo: deal with params.LAVA_PRIORITY or drop it */ 370 | 371 | withCredentials([string(credentialsId: token, variable: 'SECRET')]) { 372 | sh(script: """ \ 373 | kci_test \ 374 | generate \ 375 | --install-path=. \ 376 | --storage=${params.KCI_STORAGE_URL} \ 377 | --db-config=${KCI_DB_CONFIG} \ 378 | --runtime-json=${env._LAB_JSON} \ 379 | --runtime-config=${params.LAB} \ 380 | --user=kernel-ci \ 381 | --runtime-token=${SECRET} \ 382 | --callback-id=${params.LAVA_CALLBACK} \ 383 | --callback-url=${hook.getURL()} \ 384 | --callback-dataset=results \ 385 | --callback-type=custom \ 386 | --target=${params.TARGET} \ 387 | --plan=${params.TEST_PLAN_VARIANT} \ 388 | > job.yaml 389 | """) 390 | 391 | sh(script: """ \ 392 | kci_test \ 393 | submit \ 394 | --runtime-config=${params.LAB} \ 395 | --user=kernel-ci \ 396 | --runtime-token=${SECRET} \ 397 | --jobs=job.yaml \ 398 | """) 399 | } 400 | } 401 | 402 | def getResult(hook) { 403 | echo "Waiting for job results..." 404 | def status = null 405 | def data = waitForWebhook(hook) 406 | def json_file = 'callback.json' 407 | writeFile(file: json_file, text: data) 408 | def token = "${params.LAB}-bisection-webhook" 409 | withCredentials([string(credentialsId: token, variable: 'SECRET')]) { 410 | def egg_cache = eggCache() 411 | status = sh(returnStatus: true, script: """ 412 | PYTHON_EGG_CACHE=${egg_cache} \ 413 | kci-bisect-lava-v2-callback \ 414 | --token=${SECRET} \ 415 | --test-case=${params.TEST_CASE} \ 416 | ${json_file} 417 | """) 418 | } 419 | sh(script: "rm -f ${json_file}") 420 | 421 | return status 422 | } 423 | 424 | def runTest(describe, expected=0, runs=0) { 425 | if (!runs) 426 | runs = params.TEST_RUNS.toInteger() 427 | 428 | def status = null 429 | 430 | for (int i = 1; i <= runs; i++) { 431 | echo "Run ${i} / ${runs}" 432 | 433 | def retries = 3 434 | 435 | while (retries) { 436 | def hook = registerWebhook() 437 | submitJob(describe, hook) 438 | status = getResult(hook) 439 | 440 | if (status == 1) 441 | retries -= 1 442 | else 443 | break 444 | } 445 | 446 | if (status != expected) 447 | break 448 | } 449 | 450 | return status 451 | } 452 | 453 | /* ---------------------------------------------------------------------------- 454 | * bisection 455 | */ 456 | 457 | def findMergeBase(kdir, good, bad) { 458 | def base = good 459 | 460 | dir(kdir) { 461 | def good_base = sh( 462 | returnStatus: true, 463 | script: "git merge-base --is-ancestor ${base} HEAD") 464 | 465 | if (good_base != 0) { 466 | def ref_url = params.REF_KERNEL_URL 467 | def ref_tree = params.REF_KERNEL_TREE 468 | def ref_branch = params.REF_KERNEL_BRANCH 469 | 470 | if (!(ref_url && ref_tree && ref_branch)) { 471 | ref_config = sh(script: """\ 472 | kci_build \ 473 | get_reference \ 474 | --tree-name ${params.KERNEL_TREE} \ 475 | --branch ${params.KERNEL_BRANCH}""", returnStdout: true).trim().tokenize("\n") 476 | if (ref_config.size() > 0) { 477 | ref_url = ref_config[0] 478 | ref_tree = ref_config[1] 479 | ref_branch = ref_config[2] 480 | } 481 | } 482 | def ref = "${ref_tree}/${ref_branch}" 483 | print("Good commit not in current branch, finding base in ${ref}") 484 | 485 | print("""\ 486 | Reference: 487 | Tree: ${ref_tree} 488 | URL: ${ref_url} 489 | Branch: ${ref_branch}""") 490 | 491 | setRemote(kdir, ref_tree, ref_url) 492 | base = sh(script: "git merge-base ${bad} ${ref}", 493 | returnStdout: true).trim() 494 | print("Merge base: ${base}") 495 | } 496 | } 497 | 498 | return base 499 | } 500 | 501 | def bisectStart(kdir, good, bad) { 502 | def status = null 503 | 504 | dir(kdir) { 505 | status = sh(returnStatus: true, script: """ 506 | git bisect start 507 | git bisect good ${good} 508 | git bisect bad ${bad} 509 | """) 510 | } 511 | 512 | return (status == 0) ? true : false 513 | } 514 | 515 | def bisectNext(kdir, status) { 516 | dir(kdir) { 517 | sh(script: "git clean -fd") 518 | 519 | switch (status) { 520 | case 0: 521 | sh(script: "git bisect good") 522 | break 523 | case 2: 524 | sh(script: "git bisect bad") 525 | break 526 | case 1: 527 | echo "Iteration failed, skipping" 528 | sh(script: "git bisect skip") 529 | break 530 | default: 531 | echo "Unexpected status, skipping" 532 | sh(script: "git bisect skip") 533 | break 534 | } 535 | } 536 | } 537 | 538 | /* ---------------------------------------------------------------------------- 539 | * Results 540 | */ 541 | 542 | def pushResults(kdir, checks, params_summary) { 543 | def subject = "\ 544 | ${params.KERNEL_TREE}/${params.KERNEL_BRANCH} bisection: \ 545 | ${params.TEST_CASE} on ${params.TARGET}" 546 | 547 | withCredentials([string(credentialsId: params.KCI_API_TOKEN_ID, 548 | variable: 'SECRET')]) { 549 | def egg_cache = eggCache() 550 | sh(script: """ 551 | PYTHON_EGG_CACHE=${egg_cache} \ 552 | kci-bisect-push-results \ 553 | --token=${SECRET} \ 554 | --api=${params.KCI_API_URL} \ 555 | --lab=${params.LAB} \ 556 | --arch=${params.ARCH} \ 557 | --defconfig=${params.DEFCONFIG} \ 558 | --build-environment=${params.BUILD_ENVIRONMENT} \ 559 | --target=${params.TARGET} \ 560 | --tree=${params.KERNEL_TREE} \ 561 | --kernel=${params.KERNEL_NAME} \ 562 | --branch=${params.KERNEL_BRANCH} \ 563 | --bisect-type=test \ 564 | --test-case=${params.TEST_CASE} \ 565 | --good=${params.GOOD_COMMIT} \ 566 | --bad=${params.BAD_COMMIT} \ 567 | --verify=${checks['verify']} \ 568 | --revert=${checks['revert']} \ 569 | --kdir=${kdir} \ 570 | --subject=\"${subject}\" \ 571 | --to=\"${params.EMAIL_RECIPIENTS}\" \ 572 | --no-auto-recipients \ 573 | """) 574 | } 575 | } 576 | 577 | /* ---------------------------------------------------------------------------- 578 | * pipeline 579 | */ 580 | 581 | def runCheck(kdir, git_commit, name, run_status, runs=0) { 582 | def check = null 583 | def tag = null 584 | 585 | lock("${env.NODE_NAME}-build-lock") { 586 | timeout(time: 60, unit: 'MINUTES') { 587 | try { 588 | tag = buildRevision(kdir, git_commit, name) 589 | check = true 590 | } catch (error) { 591 | check = false 592 | } 593 | } 594 | } 595 | 596 | if (!check) 597 | return false 598 | 599 | def describe = gitDescribe(kdir) 600 | 601 | timeout(time: 120, unit: 'MINUTES') { 602 | def status = runTest(describe, run_status, runs) 603 | check = (status == run_status ? true : false) 604 | } 605 | 606 | removeTag(kdir, tag) 607 | 608 | return check 609 | } 610 | 611 | def checkAbort(passed, message) { 612 | if (!passed) { 613 | echo message 614 | currentBuild.result = 'ABORTED' 615 | } 616 | 617 | return passed 618 | } 619 | 620 | def bisection(kdir, checks) { 621 | def check = null 622 | def good = null 623 | def bad = null 624 | 625 | stage("Init") { 626 | timeout(time: 30, unit: 'MINUTES') { 627 | parallel( 628 | lab_info: { fetchLabInfo() }, 629 | kdir: { cloneLinux(kdir) }, 630 | ) 631 | } 632 | 633 | bad = params.BAD_COMMIT 634 | good = findMergeBase(kdir, params.GOOD_COMMIT, bad) 635 | } 636 | 637 | stage("Check pass") { 638 | check = runCheck(kdir, good, 'pass', 0) 639 | } 640 | if (!checkAbort(check, "Good revision check failed")) 641 | return check 642 | 643 | stage("Check fail") { 644 | check = runCheck(kdir, bad, 'fail', 2) 645 | } 646 | if (!checkAbort(check, "Bad revision check failed")) 647 | return check 648 | 649 | stage("Start") { 650 | timeout(time: 5, unit: 'MINUTES') { 651 | check = bisectStart(kdir, good, bad) 652 | } 653 | } 654 | if (!checkAbort(check, 655 | "Failed to start bisection, commits range may be invalid.")) 656 | return check 657 | 658 | def previous = good 659 | def current = getSHA(kdir) 660 | def iteration = 1 661 | 662 | while (previous != current) { 663 | def tag = createTag(kdir, iteration) 664 | def status = null 665 | 666 | echo "Iteration #${iteration}: ${tag}" 667 | 668 | lock("${env.NODE_NAME}-build-lock") { 669 | stage("Build ${iteration}") { 670 | timeout(time: 60, unit: 'MINUTES') { 671 | try { 672 | buildKernel(kdir) 673 | status = 0 674 | } catch (error) { 675 | status = 1 676 | } 677 | } 678 | } 679 | } 680 | 681 | if (status == 0) { 682 | def describe = gitDescribe(kdir) 683 | 684 | stage("Test ${iteration}") { 685 | timeout(time: 120, unit: 'MINUTES') { 686 | status = runTest(describe) 687 | } 688 | } 689 | } 690 | 691 | removeTag(kdir, tag) 692 | 693 | stage("Next") { 694 | timeout(time: 5, unit: 'MINUTES') { 695 | bisectNext(kdir, status) 696 | } 697 | } 698 | 699 | previous = current 700 | current = getSHA(kdir) 701 | iteration += 1 702 | } 703 | 704 | stage("Verify") { 705 | check = runCheck(kdir, 'refs/bisect/bad', 'verify', 2, 3) 706 | checks['verify'] = check ? 'PASS' : 'FAIL' 707 | } 708 | if (!checkAbort(check, "Result check failed")) 709 | return check 710 | 711 | stage("Revert") { 712 | dir(kdir) { 713 | sh(script: "git revert refs/bisect/bad") 714 | } 715 | check = runCheck(kdir, 'HEAD', 'revert', 0, 3) 716 | checks['revert'] = check ? 'PASS' : 'FAIL' 717 | } 718 | if (!check) 719 | echo "Warning: revert check failed" 720 | 721 | return true 722 | } 723 | 724 | node("docker && bisection") { 725 | /* Global pipeline constants */ 726 | env._BMETA_JSON = "bmeta.json" 727 | env._ARTIFACTS_JSON = "artifacts.json" 728 | env._LAB_JSON = "lab-info.json" 729 | 730 | def j = new Job() 731 | def kdir = "${env.WORKSPACE}/linux" 732 | def checks = [:] 733 | def docker_image = null 734 | 735 | def params_summary = """\ 736 | Tree: ${params.KERNEL_TREE} 737 | URL: ${params.KERNEL_URL} 738 | Branch: ${params.KERNEL_BRANCH} 739 | Kernel: ${params.KERNEL_NAME} 740 | Target: ${params.TARGET} 741 | Lab: ${params.LAB} 742 | Defconfig: ${params.DEFCONFIG} 743 | Compiler: ${params.BUILD_ENVIRONMENT} 744 | Test plan: ${params.TEST_PLAN_VARIANT} 745 | Test case: ${params.TEST_CASE}""" 746 | print("""\ 747 | Good: ${params.GOOD_COMMIT} 748 | Bad: ${params.BAD_COMMIT} 749 | ${params_summary}""") 750 | 751 | if (params.LABS_WHITELIST) { 752 | def labs = params.LABS_WHITELIST.tokenize(' ') 753 | 754 | if (!labs.contains(params.LAB)) { 755 | echo "Lab not on whitelist, aborting." 756 | currentBuild.result = 'ABORTED' 757 | return 758 | } 759 | } 760 | 761 | if (params.TREES_WHITELIST) { 762 | def trees = params.TREES_WHITELIST.tokenize(' ') 763 | 764 | if (!trees.contains(params.KERNEL_TREE)) { 765 | echo "Tree not on whitelist, aborting." 766 | currentBuild.result = 'ABORTED' 767 | return 768 | } 769 | } 770 | 771 | j.dockerPullWithRetry("${params.DOCKER_BASE}kernelci").inside('--init') { 772 | build_env_docker_image = j.dockerImageName( 773 | params.BUILD_ENVIRONMENT, params.ARCH) 774 | docker_image = "${params.DOCKER_BASE}${build_env_docker_image}" 775 | } 776 | 777 | j.dockerPullWithRetry(docker_image).inside('--init') { 778 | try { 779 | def valid_bisect = bisection(kdir, checks) 780 | if (!valid_bisect) 781 | return 782 | } catch (err) { 783 | currentBuild.result = "FAILURE" 784 | 785 | def tree_branch = "${params.KERNEL_TREE}/${params.KERNEL_BRANCH}" 786 | def subject = "bisection error: #${env.BUILD_NUMBER} \ 787 | ${tree_branch} ${params.LAB} ${params.TARGET}" 788 | def body = """\ 789 | ${env.BUILD_URL} 790 | 791 | ${params_summary} 792 | 793 | ${err} 794 | """ 795 | emailext(subject: subject, body: body, to: params.EMAIL_RECIPIENTS) 796 | 797 | throw err 798 | } 799 | 800 | stage("Report") { 801 | pushResults(kdir, checks, params_summary) 802 | } 803 | } 804 | } 805 | -------------------------------------------------------------------------------- /jobs/build-trigger.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2018-2022 Collabora Limited 5 | Author: Guillaume Tucker 6 | 7 | This module is free software; you can redistribute it and/or modify it under 8 | the terms of the GNU Lesser General Public License as published by the Free 9 | Software Foundation; either version 2.1 of the License, or (at your option) 10 | any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this library; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* ---------------------------------------------------------------------------- 23 | * Jenkins parameters 24 | 25 | BUILD_CONFIG 26 | Name of the build configuration 27 | COMMIT_ID 28 | Git commit SHA1 at the revision of the snapshot 29 | PUBLISH (boolean) 30 | Publish build results via the KernelCI backend API 31 | EMAIL (boolean) 32 | Send build results via email 33 | LABS_WHITELIST 34 | List of labs to include in the tests, all labs will be tested by default. 35 | KCI_API_URL (https://api.kernelci.org) 36 | URL of the KernelCI backend API 37 | KCI_API_TOKEN_ID 38 | Identifier of the KernelCI backend API token stored in Jenkins 39 | KCI_STORAGE_CONFIG (storage.kernelci.org) 40 | Name of the KernelCI storage configuration 41 | DOCKER_BASE (kernelci/) 42 | Dockerhub base address used for the build images 43 | ALLOW_REBUILD (false) 44 | Allow building the same revision again. 45 | */ 46 | 47 | @Library('kernelci') _ 48 | import org.kernelci.util.Job 49 | 50 | def updateRepo(config, mirror, kdir, opts) { 51 | sh(script: """\ 52 | kci_build \ 53 | update_mirror \ 54 | --build-config=${config} \ 55 | --mirror=${mirror} \ 56 | """) 57 | 58 | while (true) { 59 | try { 60 | sh(script: """\ 61 | kci_build \ 62 | update_repo \ 63 | --build-config=${config} \ 64 | --kdir=${kdir} \ 65 | --mirror=${mirror} \ 66 | """) 67 | break 68 | } catch (error) { 69 | print("Failed to update repo: ${error}") 70 | print("Removing clone and retrying") 71 | sh(script: "rm -rf ${kdir}") 72 | sleep 1 73 | } 74 | } 75 | 76 | def describe_raw = sh(script: """\ 77 | kci_build \ 78 | describe \ 79 | --build-config=${config} \ 80 | --kdir=${kdir} \ 81 | """, returnStdout: true).trim() 82 | def describe_list = describe_raw.tokenize('\n') 83 | opts['commit'] = describe_list[0] 84 | opts['describe'] = describe_list[1] 85 | opts['describe_verbose'] = describe_list[2] 86 | } 87 | 88 | def pushTarball(config, kdir, opts) { 89 | withCredentials([string(credentialsId: params.KCI_API_TOKEN_ID, 90 | variable: 'SECRET')]) { 91 | opts['tarball_url'] = sh(script: """\ 92 | kci_build \ 93 | push_tarball \ 94 | --build-config=${config} \ 95 | --kdir=${kdir} \ 96 | --storage-config=${params.KCI_STORAGE_CONFIG} \ 97 | --api=${params.KCI_API_URL} \ 98 | --db-token=${SECRET} \ 99 | """, returnStdout: true).trim() 100 | } 101 | } 102 | 103 | def listConfigs(config, kdir, config_list) { 104 | sh(script: """\ 105 | kci_build \ 106 | generate_fragments \ 107 | --build-config=${config} \ 108 | --kdir=${kdir} \ 109 | """) 110 | 111 | def kernel_config_list_raw = sh(script: """\ 112 | kci_build \ 113 | list_kernel_configs \ 114 | --build-config=${config} \ 115 | --kdir=${kdir} \ 116 | """, returnStdout: true).trim() 117 | def kernel_config_list = kernel_config_list_raw.tokenize('\n') 118 | 119 | for (String kernel_config_raw: kernel_config_list) { 120 | def data = kernel_config_raw.tokenize(' ') 121 | def arch = data[0] 122 | def defconfig = data[1] 123 | def build_env = data[2] 124 | config_list.add([arch, defconfig, build_env]) 125 | } 126 | } 127 | 128 | def listArchitectures(config) { 129 | def arch_list = [] 130 | 131 | def raw_variants = sh( 132 | script: """\ 133 | kci_build \ 134 | list_variants \ 135 | --build-config=${config} \ 136 | """, returnStdout: true).trim() 137 | def variants = raw_variants.tokenize('\n') 138 | 139 | for (String variant: variants) { 140 | def raw_variant_arch_list = sh( 141 | script: """\ 142 | kci_build \ 143 | arch_list \ 144 | --build-config=${config} \ 145 | --variant=${variant} \ 146 | """, returnStdout: true).trim() 147 | def variant_arch_list = raw_variant_arch_list.tokenize('\n') 148 | 149 | for (String arch: variant_arch_list) 150 | if (!arch_list.contains(arch)) 151 | arch_list.add(arch) 152 | } 153 | 154 | return arch_list 155 | } 156 | 157 | def addBuildOpts(config, opts) { 158 | opts['config'] = config 159 | 160 | def opts_raw = sh( 161 | script: """\ 162 | kci_build \ 163 | tree_branch \ 164 | --build-config=${config} \ 165 | """, returnStdout: true).trim() 166 | def opt_list = opts_raw.tokenize('\n') 167 | opts['tree'] = opt_list[0] 168 | opts['git_url'] = opt_list[1] 169 | opts['branch'] = opt_list[2] 170 | } 171 | 172 | def getLabsWithTests(build_job_name, number, labs) { 173 | def artifacts = "${env.WORKSPACE}/artifacts-${build_job_name}-${number}" 174 | def lab_list = [] 175 | 176 | dir(artifacts) { 177 | copyArtifacts( 178 | projectName: build_job_name, 179 | selector: specific("${number}") 180 | ) 181 | } 182 | 183 | def labs_info = "${env.WORKSPACE}/labs" 184 | 185 | for (lab in labs) { 186 | def lab_json = "${labs_info}/${lab}.json" 187 | 188 | def raw_jobs = sh(script: """\ 189 | #!/bin/sh -e 190 | kci_test \ 191 | list_jobs \ 192 | --runtime-config=${lab} \ 193 | --runtime-json=${lab_json} \ 194 | --install-path=${artifacts} \ 195 | """, returnStdout: true).trim() 196 | 197 | if (raw_jobs) 198 | lab_list.push(lab) 199 | } 200 | 201 | sh(script: "rm -rf ${artifacts}") 202 | 203 | return lab_list 204 | } 205 | 206 | def scheduleTests(build_job_name, build_job_number, labs) { 207 | def labs_str = "" 208 | for (lab in labs) 209 | labs_str += "${lab} " 210 | 211 | def str_params = [ 212 | 'LABS': labs_str.trim(), 213 | 'TRIGGER_JOB_NAME': env.JOB_NAME, 214 | 'TRIGGER_JOB_NUMBER': env.BUILD_NUMBER, 215 | 'BUILD_JOB_NAME': build_job_name, 216 | 'BUILD_JOB_NUMBER': "${build_job_number}", 217 | ] 218 | def params = [] 219 | 220 | def j = new Job() 221 | j.addStrParams(params, str_params) 222 | build(job: 'test-runner', parameters: params, propagate: false) 223 | } 224 | 225 | def buildKernelStep(job, arch, defconfig, build_env, opts, labs) { 226 | def node_label = "k8s" 227 | def parallel_builds = "4" 228 | 229 | if (defconfig.matches(".*allmodconfig.*") || defconfig.matches("^gki_defconfig.*")) { 230 | node_label = "k8s-big" 231 | parallel_builds = "" 232 | } else if (defconfig.matches("^defconfig.*") && arch == "arm64") { 233 | node_label = "k8s-medium" 234 | parallel_builds = "" 235 | } else if (defconfig.matches(".*kselftest.*")) { 236 | node_label = "k8s-medium" 237 | parallel_builds = "" 238 | } 239 | 240 | def str_params = [ 241 | 'ARCH': arch, 242 | 'DEFCONFIG': defconfig, 243 | 'GIT_DESCRIBE': opts['describe'], 244 | 'GIT_DESCRIBE_VERBOSE': opts['describe_verbose'], 245 | 'COMMIT_ID': opts['commit'], 246 | 'SRC_TARBALL': opts['tarball_url'], 247 | 'BUILD_CONFIG': opts['config'], 248 | 'BUILD_ENVIRONMENT': build_env, 249 | 'NODE_LABEL': node_label, 250 | 'PARALLEL_BUILDS': parallel_builds, 251 | 'KCI_API_URL': "${params.KCI_API_URL}", 252 | 'KCI_API_TOKEN_ID': "${params.KCI_API_TOKEN_ID}", 253 | 'KCI_STORAGE_CONFIG': "${params.KCI_STORAGE_CONFIG}", 254 | 'DOCKER_BASE': "${params.DOCKER_BASE}", 255 | ] 256 | def job_params = [] 257 | 258 | def j = new Job() 259 | j.addStrParams(job_params, str_params) 260 | 261 | return { 262 | def res = build(job: job, parameters: job_params, propagate: false) 263 | print("${res.number}: ${arch} ${defconfig} ${build_env} ${res.result}") 264 | /* 265 | if (res.result == "SUCCESS") { 266 | def test_labs = getLabsWithTests(job, res.number, labs) 267 | if (test_labs) { 268 | scheduleTests(job, res.number, test_labs) 269 | } 270 | } 271 | */ 272 | } 273 | } 274 | 275 | def buildsComplete(job, opts) { 276 | def str_params = [ 277 | 'TREE_NAME': opts['tree'], 278 | 'GIT_DESCRIBE': opts['describe'], 279 | 'BRANCH': opts['branch'], 280 | ] 281 | def bool_params = [ 282 | 'EMAIL': params.EMAIL, 283 | 'PUBLISH': params.PUBLISH, 284 | ] 285 | def job_params = [] 286 | 287 | def j = new Job() 288 | j.addStrParams(job_params, str_params) 289 | j.addBoolParams(job_params, bool_params) 290 | build(job: job, parameters: job_params) 291 | } 292 | 293 | node("docker && build-trigger") { 294 | def j = new Job() 295 | def kdir = "${env.WORKSPACE}/configs/${params.BUILD_CONFIG}" 296 | def mirror = "${env.WORKSPACE}/linux.git" 297 | def labs_info = "${env.WORKSPACE}/labs" 298 | def docker_image = "${params.DOCKER_BASE}kernelci" 299 | def opts = [:] 300 | def configs = [] 301 | def buildStatus = null 302 | 303 | print("""\ 304 | Config: ${params.BUILD_CONFIG} 305 | Commit: ${params.COMMIT_ID} 306 | Container: ${docker_image}""") 307 | 308 | j.dockerPullWithRetry(docker_image).inside('--init') { 309 | def labs = [] 310 | 311 | stage("Labs") { 312 | sh(script: "rm -rf ${labs_info}; mkdir -p ${labs_info}") 313 | 314 | def raw_lab_names = sh( 315 | script: "kci_test list_labs", returnStdout: true).trim() 316 | def all_lab_names = raw_lab_names.tokenize('\n') 317 | def labs_list = [] 318 | 319 | if (params.LABS_WHITELIST) { 320 | def whitelist = params.LABS_WHITELIST.tokenize(' ') 321 | 322 | for (lab in all_lab_names) 323 | if (whitelist.contains(lab)) 324 | labs_list.add(lab) 325 | } else { 326 | labs_list = all_lab_names 327 | } 328 | 329 | for (lab in labs_list) { 330 | def lab_json = "${labs_info}/${lab}.json" 331 | def token = "${lab}-lava-api" 332 | def retry = 3 333 | while (retry--) { 334 | try { 335 | withCredentials([string(credentialsId: token, 336 | variable: 'SECRET')]) { 337 | sh(script: """\ 338 | kci_test \ 339 | get_lab_info \ 340 | --runtime-config=${lab} \ 341 | --runtime-json=${lab_json} \ 342 | --user=kernel-ci \ 343 | --runtime-token=${SECRET} \ 344 | """) 345 | } 346 | labs.add(lab) 347 | retry = 0 348 | } catch (error) { 349 | print("Error with ${lab}: ${error}") 350 | } 351 | } 352 | } 353 | } 354 | 355 | dir(labs_info) { 356 | archiveArtifacts("*.json") 357 | } 358 | 359 | stage("Repo") { 360 | updateRepo(params.BUILD_CONFIG, mirror, kdir, opts) 361 | } 362 | 363 | if (params.ALLOW_REBUILD != true) { 364 | if (opts['commit'] != params.COMMIT_ID) { 365 | print("Commit mismatch: ${params.COMMIT_ID} ${opts['commit']}") 366 | currentBuild.result = 'ABORTED' 367 | return 368 | } 369 | } 370 | 371 | stage("Tarball") { 372 | pushTarball(params.BUILD_CONFIG, kdir, opts) 373 | } 374 | 375 | stage("Configs") { 376 | listConfigs(params.BUILD_CONFIG, kdir, configs) 377 | } 378 | 379 | stage("Build") { 380 | def builds = [:] 381 | def i = 0 382 | 383 | addBuildOpts(params.BUILD_CONFIG, opts) 384 | 385 | for (x in configs) { 386 | def arch = x[0] 387 | def defconfig = x[1] 388 | def build_env = x[2] 389 | 390 | def step_name = "${i} ${arch} ${defconfig} ${build_env}" 391 | print(step_name) 392 | 393 | builds[step_name] = buildKernelStep( 394 | "kernel-build", arch, defconfig, build_env, opts, labs) 395 | 396 | i += 1 397 | } 398 | 399 | try { 400 | parallel(builds) 401 | } catch (err) { 402 | print("Builds failed: ${err}") 403 | buildStatus = "FAILURE" 404 | } 405 | } 406 | 407 | stage("Complete") { 408 | buildsComplete("kernel-arch-complete", opts) 409 | } 410 | 411 | if (buildStatus) 412 | currentBuild.result = buildStatus; 413 | } 414 | } 415 | -------------------------------------------------------------------------------- /jobs/build.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2018-2021 Collabora Limited 5 | Author: Guillaume Tucker 6 | 7 | This module is free software; you can redistribute it and/or modify it under 8 | the terms of the GNU Lesser General Public License as published by the Free 9 | Software Foundation; either version 2.1 of the License, or (at your option) 10 | any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this library; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* ---------------------------------------------------------------------------- 23 | * Jenkins parameters 24 | 25 | ARCH 26 | CPU architecture as understood by the Linux kernel build system 27 | DEFCONFIG 28 | Linux kernel defconfig to build 29 | SRC_TARBALL 30 | URL of the kernel source tarball 31 | BUILD_CONFIG 32 | Name of the build configuration 33 | GIT_DESCRIBE 34 | Output of 'git describe' at the revision of the snapshot 35 | GIT_DESCRIBE_VERBOSE 36 | Verbose output of 'git describe' at the revision of the snapshot 37 | COMMIT_ID 38 | Git commit SHA1 at the revision of the snapshot 39 | BUILD_ENVIRONMENT 40 | Name of the build environment 41 | NODE_LABEL 42 | Label to use to choose a node on which to run this job 43 | PUBLISH (boolean) 44 | Publish build results via the KernelCI backend API 45 | EMAIL (boolean) 46 | Send build results via email 47 | KCI_DB_CONFIG (kernelci.org) 48 | Name of the --db-config value to use with kci_data 49 | KCI_API_URL (https://api.kernelci.org) 50 | URL of the KernelCI backend API 51 | KCI_API_TOKEN_ID 52 | Identifier of the KernelCI backend API token stored in Jenkins 53 | KCI_STORAGE_URL (https://storage.kernelci.org/) 54 | URL of the KernelCI storage server 55 | KCI_STORAGE_CONFIG (storage.kernelci.org) 56 | Name of the KernelCI storage configuration 57 | DOCKER_BASE (kernelci/) 58 | Dockerhub base address used for the build images 59 | PARALLEL_BUILDS 60 | Number of kernel builds to run in parallel 61 | 62 | */ 63 | 64 | 65 | @Library('kernelci') _ 66 | import org.kernelci.util.Job 67 | 68 | /* K8S build */ 69 | node("docker" && params.NODE_LABEL) { 70 | def j = new Job() 71 | def k8s_context = "${env.K8S_CONTEXT}" 72 | def docker_image = null 73 | 74 | print("""\ 75 | Config: ${params.BUILD_CONFIG} 76 | CPU arch: ${params.ARCH} 77 | Describe: ${params.GIT_DESCRIBE} 78 | Revision: ${params.COMMIT_ID} 79 | Defconfig: ${params.DEFCONFIG} 80 | Compiler: ${params.BUILD_ENVIRONMENT} 81 | K8S ctx: ${k8s_context}""") 82 | 83 | docker_image = "${params.DOCKER_BASE}k8s:kernelci" 84 | j.dockerPullWithRetry(docker_image).inside("--init -v $HOME/.kube:/.kube-host:ro -v $HOME/.config/gcloud:/.config/gcloud -v $HOME/.azure:/.azure") { 85 | build_env_docker_image = j.dockerImageName( 86 | params.BUILD_ENVIRONMENT, params.ARCH 87 | ) 88 | env.KUBECONFIG="/tmp/.kube/config" 89 | env.USE_GKE_GCLOUD_AUTH_PLUGIN="true" 90 | 91 | stage("Init") { 92 | /* Remove old bmeta.json and etc, as jenkins make workspace persistent, even it is not mapped as volume in docker */ 93 | sh(script: "rm -rf *") 94 | /* Copy host kubernetes configs */ 95 | sh(script: "mkdir /tmp/.kube") 96 | sh(script: "cp -r /.kube-host/config /tmp/.kube") 97 | /* temporary hack to retrieve fresh credentials for kubectl from all clusters, hardcoded now */ 98 | print("K8S: Updating kubectl credentials") 99 | sh(script: "gcloud container clusters get-credentials kci-eu-west1 --region europe-west1-d") 100 | sh(script: "gcloud container clusters get-credentials kci-eu-west4 --region europe-west4-c") 101 | sh(script: "gcloud container clusters get-credentials kci-us-central1 --region us-central1-c") 102 | sh(script: "gcloud container clusters get-credentials kci-big-us-east4 --region us-east4-c") 103 | sh(script: "gcloud container clusters get-credentials kci-us-west1 --region us-west1-a") 104 | 105 | /* list clusters to init/refresh auth credentials */ 106 | print("K8S: Google Cloud clusters available:") 107 | /* Following commands are informational, 108 | not critical for the job, so return code can be ignored 109 | */ 110 | sh(script: "gcloud container clusters list || exit 0") 111 | print("K8S: Azure clusters available:") 112 | sh(script: "az aks list -o table || exit 0") 113 | print("K8S context: ${k8s_context}. Current nodes:") 114 | sh(script: "kubectl --context ${k8s_context} get nodes || exit 0") 115 | } 116 | 117 | stage("Build") { 118 | timeout(time: 45, unit: 'MINUTES') { 119 | def k8s_job = sh(script: """\ 120 | DOCKER_IMAGE=${build_env_docker_image} \ 121 | /etc/kernelci/k8s/gen.py""", returnStdout: true).trim() 122 | 123 | /* submit */ 124 | sh(script: "kubectl --context ${k8s_context} apply -f ${k8s_job}.yaml") 125 | sh(script: "kubectl --context ${k8s_context} describe -f ${k8s_job}.yaml || exit 0") 126 | 127 | /* Wait for pod to finish (will also dump logs and remove job) */ 128 | sh(script: """ 129 | /etc/kernelci/k8s/wait.py \ 130 | --context ${k8s_context} \ 131 | --job-name ${k8s_job} \ 132 | | tee ${k8s_job}.log""") 133 | 134 | /* Find upload path */ 135 | upload_path_line = sh(script: "grep \"^Upload path:\" ${k8s_job}.log", 136 | returnStdout: true).trim().tokenize(':') 137 | if (upload_path_line.size() > 0) { 138 | upload_path = upload_path_line[1].trim() 139 | print("Upload path: ${upload_path}") 140 | 141 | sh(script: "wget -q ${KCI_STORAGE_URL}/${upload_path}/bmeta.json") 142 | sh(script: "wget -q ${KCI_STORAGE_URL}/${upload_path}/steps.json") 143 | sh(script: "wget -q ${KCI_STORAGE_URL}/${upload_path}/artifacts.json") 144 | archiveArtifacts("*.json") 145 | } 146 | } 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /jobs/monitor.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2018-2022 Collabora Limited 5 | Author: Guillaume Tucker 6 | 7 | This module is free software; you can redistribute it and/or modify it under 8 | the terms of the GNU Lesser General Public License as published by the Free 9 | Software Foundation; either version 2.1 of the License, or (at your option) 10 | any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this library; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* ---------------------------------------------------------------------------- 23 | * Jenkins parameters 24 | 25 | The following parameters need to be defined in the Jenkins pipeline job, with 26 | typical default values in brackets: 27 | 28 | CONFIG_LIST 29 | List of build configs to check instead of all the ones in build-configs.yaml 30 | KCI_API_URL (https://api.kernelci.org) 31 | URL of the KernelCI backend API 32 | KCI_API_TOKEN_ID 33 | Identifier of the KernelCI backend API token stored in Jenkins 34 | KCI_STORAGE_CONFIG (storage.kernelci.org) 35 | Name of the KernelCI storage configuration 36 | DOCKER_BASE (kernelci/) 37 | Dockerhub base address used for the build images 38 | */ 39 | 40 | @Library('kernelci') _ 41 | import org.kernelci.util.Job 42 | 43 | def updateLastCommit(config, commit) { 44 | withCredentials([string(credentialsId: params.KCI_API_TOKEN_ID, 45 | variable: 'SECRET')]) { 46 | sh(script: """\ 47 | kci_build \ 48 | update_last_commit \ 49 | --build-config=${config} \ 50 | --commit=${commit} \ 51 | --api=${params.KCI_API_URL} \ 52 | --db-token=${SECRET} \ 53 | """) 54 | } 55 | } 56 | 57 | def checkConfig(config) { 58 | def retry = 3 59 | def commit = null 60 | 61 | while (retry--) { 62 | try { 63 | commit = sh( 64 | script: """ 65 | kci_build \ 66 | check_new_commit \ 67 | --build-config=${config} \ 68 | --storage-config=${params.KCI_STORAGE_CONFIG} \ 69 | """, returnStdout: true).trim() 70 | retry = 0 71 | } catch (error) { 72 | 73 | if (retry) { 74 | print("Failed to check ${config}, retyring: ${error}") 75 | sleep(1) 76 | } else { 77 | print("ERROR: All attempts failed with ${config}") 78 | } 79 | } 80 | } 81 | 82 | if (!commit) { 83 | print("${config}: no new commit") 84 | return 85 | } 86 | 87 | print("${config}: triggering build with commit ${commit}") 88 | 89 | updateLastCommit(config, commit) 90 | 91 | def job = "kernel-build-trigger" 92 | def str_params = [ 93 | 'BUILD_CONFIG': config, 94 | 'COMMIT_ID': commit, 95 | ] 96 | def job_params = [] 97 | def j = new Job() 98 | j.addStrParams(job_params, str_params) 99 | 100 | build(job: job, parameters: job_params, propagate: false, wait: false) 101 | } 102 | 103 | node("docker && monitor") { 104 | def j = new Job() 105 | def docker_image = "${params.DOCKER_BASE}kernelci" 106 | 107 | print("""\ 108 | Storage: ${params.KCI_STORAGE_CONFIG} 109 | Container: ${docker_image}""") 110 | 111 | j.dockerPullWithRetry(docker_image).inside('--init') { 112 | stage("Monitor") { 113 | def config_list = null 114 | def config_jobs = [:] 115 | 116 | if (params.CONFIG_LIST != "") { 117 | config_list = params.CONFIG_LIST.tokenize(' ') 118 | } else { 119 | def raw_configs = sh(script: "kci_build list_configs", 120 | returnStdout: true).trim() 121 | config_list = raw_configs.tokenize('\n') 122 | } 123 | 124 | for (String config: config_list) { 125 | def config_name = config 126 | config_jobs[config_name] = { 127 | checkConfig(config_name) 128 | } 129 | } 130 | 131 | parallel(config_jobs) 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /jobs/rootfs-builder.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2020-2022 Collabora Limited 5 | Author: Lakshmipathi Ganapathi 6 | Author: Guillaume Tucker 7 | Author: Denys Fedoryshchenko 8 | 9 | This module is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU Lesser General Public License as published by the Free 11 | Software Foundation; either version 2.1 of the License, or (at your option) 12 | any later version. 13 | 14 | This library is distributed in the hope that it will be useful, but WITHOUT 15 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 17 | details. 18 | 19 | You should have received a copy of the GNU Lesser General Public License 20 | along with this library; if not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | /* ---------------------------------------------------------------------------- 25 | * Jenkins parameters 26 | 27 | KCI_CORE_URL (https://github.com/kernelci/kernelci-core.git) 28 | URL of the kernelci-core repository 29 | KCI_CORE_BRANCH (master) 30 | Name of the branch to use in the kernelci-core repository 31 | KCI_STORAGE_CONFIG (storage.kernelci.org) 32 | Name of the KernelCI storage configuration 33 | KCI_API_TOKEN_ID 34 | Identifier of the KernelCI backend API token stored in Jenkins 35 | DOCKER_BASE 36 | Dockerhub base address used for the build images 37 | ROOTFS_CONFIG 38 | Configuration name to build RootFS images 39 | ROOTFS_ARCH 40 | RootFS image architecture 41 | PIPELINE_VERSION 42 | Unique string identifier for the series of rootfs build jobs 43 | */ 44 | 45 | 46 | @Library('kernelci') _ 47 | import org.kernelci.util.Job 48 | 49 | def build(config, arch, pipeline_version, kci_core, rootfs_type) { 50 | dir(kci_core) { 51 | sh(script: """\ 52 | ./kci_rootfs \ 53 | build \ 54 | --rootfs-config ${config} \ 55 | --arch ${arch} \ 56 | --data-path config/rootfs/${rootfs_type} \ 57 | --output ${pipeline_version} 58 | """) 59 | } 60 | } 61 | 62 | def upload(config, pipeline_version, kci_core, rootfs_type, arch) { 63 | rootfs_upload_path = "images/rootfs/debian/${config}/${pipeline_version}" 64 | print("\n Uploading rootfs_type: ${rootfs_type}") 65 | 66 | if (rootfs_type == "buildroot") { 67 | rootfs_upload_path = "images/rootfs/buildroot/${config}/${pipeline_version}" 68 | } 69 | 70 | dir(kci_core) { 71 | withCredentials([string(credentialsId: params.KCI_API_TOKEN_ID, 72 | variable: 'API_TOKEN')]) { 73 | sh(script: """\ 74 | ./kci_rootfs \ 75 | upload \ 76 | --storage-config ${KCI_STORAGE_CONFIG} \ 77 | --storage-cred ${API_TOKEN} \ 78 | --rootfs-dir ${pipeline_version}/_install_/${config} \ 79 | --upload-path ${rootfs_upload_path} 80 | """) 81 | } 82 | } 83 | } 84 | 85 | node("debos && docker") { 86 | def j = new Job() 87 | def kci_core = "${env.WORKSPACE}/kernelci-core" 88 | def config = "${params.ROOTFS_CONFIG}" 89 | def arch = "${params.ROOTFS_ARCH}" 90 | def pipeline_version = "${params.PIPELINE_VERSION}" 91 | def rootfs_type = "${params.ROOTFS_TYPE}" 92 | def docker_image = "${params.DOCKER_BASE}${rootfs_type}:kernelci" 93 | 94 | print("""\ 95 | Config: ${config} 96 | CPU arch: ${arch} 97 | Pipeline: ${pipeline_version} 98 | Docker: ${docker_image}""") 99 | 100 | if (!config || !arch || !pipeline_version) { 101 | print("Invalid parameters") 102 | currentBuild.result = 'ABORTED' 103 | return 104 | } 105 | 106 | j.dockerPullWithRetry(docker_image).inside('--init') { 107 | j.cloneKciCore(kci_core, params.KCI_CORE_URL, params.KCI_CORE_BRANCH) 108 | } 109 | 110 | j.dockerPullWithRetry(docker_image). 111 | inside(" --privileged --device /dev/kvm --init --volume /dev/shm --tmpfs /dev/shm:rw,nosuid,nodev,exec") { 112 | 113 | stage("Build") { 114 | timeout(time: 8, unit: 'HOURS') { 115 | build(config, arch, pipeline_version, kci_core, rootfs_type) 116 | } 117 | } 118 | 119 | stage("Upload") { 120 | timeout(time: 30, unit: 'MINUTES') { 121 | upload(config, pipeline_version, kci_core, rootfs_type, arch); 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /jobs/rootfs-trigger.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2020-2022 Collabora Limited 5 | Author: Lakshmipathi Ganapathi 6 | Author: Guillaume Tucker 7 | 8 | This module is free software; you can redistribute it and/or modify it under 9 | the terms of the GNU Lesser General Public License as published by the Free 10 | Software Foundation; either version 2.1 of the License, or (at your option) 11 | any later version. 12 | 13 | This library is distributed in the hope that it will be useful, but WITHOUT 14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with this library; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | /* ---------------------------------------------------------------------------- 24 | * Jenkins parameters 25 | 26 | KCI_CORE_URL (https://github.com/kernelci/kernelci-core.git) 27 | URL of the kernelci-core repository 28 | KCI_CORE_BRANCH (master) 29 | Name of the branch to use in the kernelci-core repository 30 | DOCKER_BASE 31 | Dockerhub base address used for the build images 32 | ROOTFS_CONFIG 33 | Set this to limit the rootfs builds to only one configuration 34 | Cannot be used with ROOTFS_TYPE 35 | ROOTFS_ARCH 36 | Set this to limit the rootfs builds to only one architecture 37 | ROOTFS_TYPE 38 | Set this to limit the rootfs builds only to specific type. 39 | Cannot be used with ROOTFS_CONFIG 40 | PIPELINE_VERSION 41 | Unique string identifier for the series of rootfs build jobs 42 | */ 43 | 44 | @Library('kernelci') _ 45 | import org.kernelci.util.Job 46 | 47 | def listVariants(kci_core, config_list, rootfs_config, rootfs_arch_list, rootfs_type_list) { 48 | def cli_opts = ' ' 49 | 50 | if (rootfs_config) { 51 | 52 | cli_opts += " --rootfs-config ${rootfs_config}" 53 | } 54 | 55 | for (String rootfs_arch: rootfs_arch_list) { 56 | cli_opts += " --arch ${rootfs_arch}" 57 | } 58 | 59 | for (String rootfs_type: rootfs_type_list) { 60 | cli_opts += " --rootfs-type ${rootfs_type}" 61 | } 62 | 63 | dir(kci_core) { 64 | def rootfs_config_list_raw = sh(script: """\ 65 | ./kci_rootfs \ 66 | list_variants \ 67 | ${cli_opts} 68 | """, returnStdout: true).trim() 69 | 70 | def rootfs_config_list = rootfs_config_list_raw.tokenize('\n') 71 | 72 | for (String rootfs_config_raw: rootfs_config_list) { 73 | def data = rootfs_config_raw.tokenize(' ') 74 | def config = data[0] 75 | def arch = data[1] 76 | def type = data[2] 77 | config_list.add([config, arch, type]) 78 | } 79 | } 80 | } 81 | 82 | 83 | def buildRootfsStep(job, config ,arch, rootfs_type) { 84 | def pipeline_version = params.PIPELINE_VERSION; 85 | 86 | if (!pipeline_version) { 87 | pipeline_version = VersionNumber( 88 | versionNumberString: 89 | '${BUILD_DATE_FORMATTED,"yyyyMMdd"}.${BUILDS_TODAY_Z}') 90 | } 91 | 92 | def str_params = [ 93 | 'ROOTFS_CONFIG': config, 94 | 'ROOTFS_ARCH': arch, 95 | 'ROOTFS_TYPE' : rootfs_type, 96 | 'PIPELINE_VERSION':pipeline_version, 97 | 'KCI_CORE_URL': "${params.KCI_CORE_URL}", 98 | 'KCI_CORE_BRANCH': "${params.KCI_CORE_BRANCH}", 99 | ] 100 | def job_params = [] 101 | 102 | def j = new Job() 103 | j.addStrParams(job_params, str_params) 104 | 105 | return { 106 | def res = build(job: job, parameters: job_params, propagate: false) 107 | } 108 | } 109 | 110 | 111 | node("docker && rootfs-trigger") { 112 | def j = new Job() 113 | def kci_core = "${env.WORKSPACE}/kernelci-core" 114 | def docker_image = "${params.DOCKER_BASE}kernelci" 115 | def configs = [] 116 | 117 | print("""\ 118 | Config: ${params.ROOTFS_CONFIG} 119 | CPU arch: ${params.ROOTFS_ARCH} 120 | Rootfs type: ${params.ROOTFS_TYPE} 121 | Container: ${docker_image}""") 122 | 123 | j.dockerPullWithRetry(docker_image).inside('--init') { 124 | 125 | stage("Init") { 126 | timeout(time: 15, unit: 'MINUTES') { 127 | j.cloneKciCore( 128 | kci_core, params.KCI_CORE_URL, params.KCI_CORE_BRANCH) 129 | } 130 | } 131 | 132 | stage("Configs") { 133 | def rootfs_type_list = params.ROOTFS_TYPE.tokenize(' ') 134 | def rootfs_arch_list = params.ROOTFS_ARCH.tokenize(' ') 135 | listVariants(kci_core, configs, params.ROOTFS_CONFIG, 136 | rootfs_arch_list, rootfs_type_list) 137 | } 138 | 139 | stage("Build") { 140 | def builds = [:] 141 | def i = 0 142 | 143 | for (item in configs) { 144 | def config_name = item[0] 145 | def arch = item[1] 146 | def rootfs_type = item[2] 147 | 148 | def step_name = "${i} ${config_name} ${arch} ${rootfs_type}" 149 | print(step_name) 150 | 151 | builds[step_name] = buildRootfsStep( 152 | "rootfs-builder", config_name, arch, rootfs_type) 153 | 154 | i += 1 155 | } 156 | 157 | parallel(builds) 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /jobs/test-runner.jpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | Copyright (C) 2019-2021 Collabora Limited 5 | Author: Guillaume Tucker 6 | 7 | This module is free software; you can redistribute it and/or modify it under 8 | the terms of the GNU Lesser General Public License as published by the Free 9 | Software Foundation; either version 2.1 of the License, or (at your option) 10 | any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this library; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* ---------------------------------------------------------------------------- 23 | * Jenkins parameters 24 | 25 | LABS 26 | Name of the labs where to submit tests 27 | TRIGGER_JOB_NAME 28 | Name of the parent trigger job 29 | TRIGGER_JOB_NUMBER 30 | Number of the parent trigger job 31 | BUILD_JOB_NAME 32 | Name of the job that built the kernel 33 | BUILD_JOB_NUMBER 34 | Number of the job that built the kernel 35 | KCI_STORAGE_URL (https://storage.kernelci.org/) 36 | URL of the KernelCI storage server 37 | DOCKER_BASE (kernelci/) 38 | Dockerhub base address used for the build images 39 | CALLBACK_ID (kernel-ci-callback) 40 | Identifier of the callback to look up an authentication token 41 | CALLBACK_URL (https://api.kernelci.org) 42 | Base URL where to send the callbacks 43 | */ 44 | 45 | @Library('kernelci') _ 46 | import org.kernelci.util.Job 47 | 48 | def getArtifacts(artifacts) 49 | { 50 | dir(artifacts) { 51 | copyArtifacts( 52 | projectName: params.BUILD_JOB_NAME, 53 | selector: specific("${params.BUILD_JOB_NUMBER}") 54 | ) 55 | 56 | if (params.TRIGGER_JOB_NAME) { 57 | copyArtifacts( 58 | projectName: params.TRIGGER_JOB_NAME, 59 | selector: specific("${params.TRIGGER_JOB_NUMBER}") 60 | ) 61 | } 62 | } 63 | } 64 | 65 | def generateJobs(lab, artifacts, jobs_dir) 66 | { 67 | def token = "${lab}-lava-api" 68 | 69 | withCredentials([string(credentialsId: token, variable: 'SECRET')]) { 70 | sh(script: """\ 71 | kci_test \ 72 | generate \ 73 | --install-path=${artifacts} \ 74 | --runtime-json=${artifacts}/${lab}.json \ 75 | --storage=${params.KCI_STORAGE_URL} \ 76 | --runtime-config=${lab} \ 77 | --user=kernel-ci \ 78 | --runtime-token=${SECRET} \ 79 | --output=${jobs_dir} \ 80 | --callback-id=${params.CALLBACK_ID} \ 81 | --callback-url=${params.CALLBACK_URL} \ 82 | """) 83 | } 84 | } 85 | 86 | def submitJobs(lab, jobs_dir) 87 | { 88 | def token = "${lab}-lava-api" 89 | 90 | withCredentials([string(credentialsId: token, variable: 'SECRET')]) { 91 | sh(script: """\ 92 | kci_test \ 93 | submit \ 94 | --runtime-config=${lab} \ 95 | --user=kernel-ci \ 96 | --runtime-token=${SECRET} \ 97 | --jobs=${jobs_dir}/* \ 98 | """) 99 | } 100 | } 101 | 102 | node("docker && test-runner") { 103 | def j = new Job() 104 | def jobs_dir = "${env.WORKSPACE}/jobs" 105 | def artifacts = "${env.WORKSPACE}/artifacts" 106 | def docker_image = "${params.DOCKER_BASE}kernelci" 107 | def labs = params.LABS.tokenize(' ') 108 | def labs_submit = [] 109 | 110 | print("""\ 111 | Labs: ${params.LABS} 112 | Container: ${docker_image}""") 113 | 114 | j.dockerPullWithRetry(docker_image).inside('--init') { 115 | stage("Skip") { 116 | print("Legacy setup wont execute tests") 117 | return 118 | } 119 | stage("Init") { 120 | sh(script: "rm -rf ${artifacts}") 121 | sh(script: "rm -rf ${jobs_dir}") 122 | 123 | timeout(time: 15, unit: 'MINUTES') { 124 | getArtifacts(artifacts) 125 | } 126 | 127 | print("Artifacts:") 128 | sh(script: "ls -l ${artifacts}") 129 | 130 | print("Build meta-data:") 131 | sh(script: "cat ${artifacts}/bmeta.json") 132 | } 133 | 134 | stage("Generate") { 135 | for (lab in labs) { 136 | def lab_dir = "${jobs_dir}/${lab}" 137 | generateJobs(lab, artifacts, lab_dir) 138 | labs_submit.add(lab) 139 | } 140 | } 141 | 142 | stage("Submit") { 143 | def steps = [:] 144 | def i = 0 145 | 146 | for (lab in labs_submit) { 147 | def lab_name = "${lab}" 148 | def lab_dir = "${jobs_dir}/${lab}" 149 | def step_name = "${i} ${lab}" 150 | 151 | print(step_name) 152 | 153 | steps[step_name] = { 154 | submitJobs(lab_name, lab_dir) 155 | } 156 | 157 | i += 1 158 | } 159 | 160 | parallel(steps) 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /plugins-base.txt: -------------------------------------------------------------------------------- 1 | configuration-as-code 2 | jquery-detached 3 | cloudbees-folder 4 | durable-task 5 | plain-credentials 6 | pipeline-stage-view 7 | rebuild 8 | bouncycastle-api 9 | workflow-job 10 | pipeline-model-api 11 | workflow-step-api 12 | workflow-aggregator 13 | pipeline-model-declarative-agent 14 | docker-commons 15 | authentication-tokens 16 | pipeline-model-extensions 17 | pipeline-stage-tags-metadata 18 | workflow-multibranch 19 | apache-httpcomponents-client-4-api 20 | ssh-credentials 21 | ssh-slaves 22 | ssh-agent 23 | variant 24 | lockable-resources 25 | workflow-support 26 | branch-api 27 | display-url-api 28 | workflow-durable-task-step 29 | workflow-cps-global-lib 30 | pipeline-stage-step 31 | token-macro 32 | docker-workflow 33 | git-client 34 | git-server 35 | jsch 36 | structs 37 | pipeline-rest-api 38 | git 39 | matrix-auth 40 | node-iterator-api 41 | build-timeout 42 | jdk-tool 43 | workflow-scm-step 44 | pipeline-milestone-step 45 | pipeline-build-step 46 | pipeline-input-step 47 | workflow-api 48 | jackson2-api 49 | script-security 50 | scm-api 51 | pipeline-model-definition 52 | junit 53 | pipeline-graph-analysis 54 | workflow-basic-steps 55 | credentials-binding 56 | command-launcher 57 | credentials 58 | workflow-cps 59 | job-dsl 60 | ws-cleanup 61 | copyartifact 62 | email-ext 63 | webhook-step 64 | versionnumber 65 | -------------------------------------------------------------------------------- /plugins-extra.txt: -------------------------------------------------------------------------------- 1 | timestamper 2 | -------------------------------------------------------------------------------- /restart-compose.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | echo "Shutting down Jenkins container..." 6 | docker-compose stop 7 | 8 | jenkins_container=$(docker ps | grep kernelci-jenkins_jenkins) || echo -n '' 9 | if [ -n "$jenkins_container" ]; then 10 | echo "$jenkins_container" 11 | container_id=$(echo "$jenkins_container" | cut -c-12) 12 | echo "Stopping Jenkins container: $container_id..." 13 | docker stop "$container_id" 14 | fi 15 | 16 | echo "Updating Jenkins image..." 17 | docker pull jenkins/jenkins 18 | 19 | echo "Starting Jenkins container..." 20 | docker-compose up --build -d 21 | 22 | echo "Done." 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /scripts/buildroot-builder.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | env 6 | 7 | arch=${1} 8 | frag=${2} 9 | variant=${frag:-base} 10 | 11 | # "base" is always used by default in the build script 12 | [ $frag == "base" ] && frag="" 13 | 14 | # Build 15 | ./configs/frags/build ${arch} ${frag} 16 | 17 | # Publish 18 | set -x 19 | PUBLISH_PATH=images/rootfs/buildroot/$(git describe)/${arch}/${variant} 20 | ls -l output/images 21 | (cd output/images; push-source.py --token ${API_TOKEN} --api ${API} --publish_path ${PUBLISH_PATH} --file *) 22 | -------------------------------------------------------------------------------- /scripts/kernel-arch-complete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | if [ "$PUBLISH" != "true" ]; then 6 | echo "Skipping publish step. PUBLISH != true." 7 | exit 0 8 | fi 9 | 10 | if [[ -z $TREE_NAME ]]; then 11 | echo "TREE_NAME not set. Not publishing." 12 | exit 1 13 | fi 14 | 15 | if [[ -z $BRANCH ]]; then 16 | echo "BRANCH not set. Not publishing." 17 | exit 1 18 | fi 19 | 20 | if [[ -z $GIT_DESCRIBE ]]; then 21 | echo "GIT_DESCRIBE not set. Not publishing." 22 | exit 1 23 | fi 24 | 25 | if [[ -z $EMAIL_AUTH_TOKEN ]]; then 26 | echo "EMAIL_AUTH_TOKEN not set. Not publishing." 27 | exit 1 28 | fi 29 | 30 | if [[ -z $API ]]; then 31 | echo "API not set. Not publishing." 32 | exit 1 33 | fi 34 | 35 | echo "Build has now finished, reporting result to dashboard." 36 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'"}' ${API}/job 37 | exit 0 38 | if [ "$EMAIL" != "true" ]; then 39 | echo "Not sending emails because EMAIL was false" 40 | exit 0 41 | elif [ "$TREE_NAME" == "agross" ]; then 42 | echo "Sending results to Andy Gross" 43 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["agross@kernel.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 44 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["agross@kernel.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 45 | elif [ "$TREE_NAME" == "alex" ]; then 46 | echo "Sending results to Alex Bennee" 47 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["alex.bennee@linaro.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 48 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["alex.bennee@linaro.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 49 | elif [ "$TREE_NAME" == "amlogic" ]; then 50 | echo "Sending results to Kevin Hilman" 51 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["khilman@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 52 | elif [ "$TREE_NAME" == "android" ]; then 53 | echo "Sending results to Android maintainers" 54 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["tom.gall@linaro.org", "sumit.semwal@linaro.org", "amit.pundir@linaro.org", "arnd.bergmann@linaro.org", "anmar.oueja@linaro.org", "kernel-team+kernelci@android.com", "gregkh@google.com", "fellows@kernelci.org"], "format": ["txt"], "delay": 10}' ${API}/send 55 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["tom.gall@linaro.org", "sumit.semwal@linaro.org", "amit.pundir@linaro.org", "arnd.bergmann@linaro.org", "anmar.oueja@linaro.org", "kernel-team+kernelci@android.com", "gregkh@google.com", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 56 | elif [ "$TREE_NAME" == "ardb" ]; then 57 | echo "Sending results to Ard Biesheuvel" 58 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["ardb@kernel.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 59 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["ardb@kernel.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 60 | elif [ "$TREE_NAME" == "arm64" ]; then 61 | echo "Sending results for the arm64 tree" 62 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["will@kernel.org", "catalin.marinas@arm.com", "linux-arm-kernel@lists.infradead.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 63 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["will@kernel.org", "catalin.marinas@arm.com", "linux-arm-kernel@lists.infradead.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 64 | elif [ "$TREE_NAME" == "arnd" ]; then 65 | echo "Sending results to Arnd Bergmann" 66 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["arnd@arndb.de", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 67 | elif [ "$TREE_NAME" == "broonie-regmap" ]; then 68 | echo "Sending results to Mark Brown" 69 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 70 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 71 | elif [ "$TREE_NAME" == "broonie-regulator" ]; then 72 | echo "Sending results to Mark Brown" 73 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 74 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 75 | elif [ "$TREE_NAME" == "broonie-sound" ]; then 76 | echo "Sending results to Mark Brown" 77 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 78 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 79 | elif [ "$TREE_NAME" == "broonie-spi" ]; then 80 | echo "Sending results to Mark Brown" 81 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 82 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["broonie@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 83 | elif [ "$TREE_NAME" == "chrome-platform" ]; then 84 | echo "Sending results for Chrome Platform tree" 85 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io", "chrome-platform@lists.linux.dev", "eballetbo@gmail.com", "bleung@chromium.org", "groeck@chromium.org", "pmalani@chromium.org"], "delay": 60}' ${API}/send 86 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io", "chrome-platform@lists.linux.dev", "eballetbo@gmail.com", "bleung@chromium.org", "groeck@chromium.org", "pmalani@chromium.org"], "format": ["txt"], "delay": 2700}' ${API}/send 87 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io", "chrome-platform@lists.linux.dev", "eballetbo@gmail.com", "bleung@chromium.org", "groeck@chromium.org", "pmalani@chromium.org"], "format": ["txt"], "delay": 5400}' ${API}/send 88 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io", "chrome-platform@lists.linux.dev", "eballetbo@gmail.com", "bleung@chromium.org", "groeck@chromium.org", "pmalani@chromium.org"], "format": ["txt"], "delay": 3600}' ${API}/send 89 | elif [ "$TREE_NAME" == "cip" ]; then 90 | echo "Sending results for CIP tree" 91 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 92 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 93 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-cip-nfs", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 94 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 95 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-filesystems", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 96 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-futex", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 97 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lib", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 98 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lkdtm", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 99 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-seccomp", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 100 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-crypto", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 101 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-fcntl-locktests", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 102 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-ima", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 103 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-ipc", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 104 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-mm", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 105 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-pty", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 106 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-timers", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 107 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "preempt-rt", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 108 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "smc", "send_to": ["cip-testing-results@lists.cip-project.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 109 | elif [ "$TREE_NAME" == "cip-gitlab" ]; then 110 | echo "Sending results for CIP (GitLab) tree" 111 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["cip-testing-results@lists.cip-project.org"], "delay": 60}' ${API}/send 112 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 1800}' ${API}/send 113 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-cip-nfs", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 1800}' ${API}/send 114 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 1800}' ${API}/send 115 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-filesystems", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 116 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-futex", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 117 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lib", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 118 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lkdtm", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 119 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-seccomp", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 120 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-crypto", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 121 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-fcntl-locktests", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 122 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-ima", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 123 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-ipc", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 124 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-mm", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 125 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-pty", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 126 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-timers", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 127 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "preempt-rt", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 128 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "smc", "send_to": ["cip-testing-results@lists.cip-project.org"], "format": ["txt"], "delay": 3600}' ${API}/send 129 | elif [ "$TREE_NAME" == "clk" ]; then 130 | echo "Sending results for CLK tree" 131 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["sboyd+clkci@kernel.org", "mturquette+clkci@baylibre.com", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 132 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["sboyd+clkci@kernel.org", "mturquette+clkci@baylibre.com", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 133 | elif [ "$TREE_NAME" == "efi" ]; then 134 | echo "Sending results to EFI maintainers" 135 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["ardb@kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 136 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["ardb@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 137 | elif [ "$TREE_NAME" == "evalenti" ]; then 138 | echo "Sending results to Eduardo Valentin" 139 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["edubezval@gmail.com", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 140 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["edubezval@gmail.com", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 141 | elif [ "$TREE_NAME" == "gtucker" ]; then 142 | echo "Sending results to Guillaume" 143 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["guillaume.tucker@collabora.com"], "delay": 0}' ${API}/send 144 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 1800}' ${API}/send 145 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-vivid", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 2700}' ${API}/send 146 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-uvc", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 147 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-exynos", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 148 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-rockchip", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 149 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-tegra", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 150 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-gpu-panfrost", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 151 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 152 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["guillaume.tucker@collabora.com"], "format": ["txt"], "delay": 3600}' ${API}/send 153 | elif [ "$TREE_NAME" == "kernelci" ]; then 154 | echo "Sending results to kernelci folks" 155 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results-staging@groups.io"], "delay": 0}' ${API}/send 156 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 157 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 158 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-fastboot", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 159 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-vivid", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 160 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-uvc", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 161 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-exynos", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 162 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-rockchip", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 163 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-tegra", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 164 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-gpu-panfrost", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 165 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 166 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["kernelci-results-staging@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 167 | elif [ "$TREE_NAME" == "khilman" ]; then 168 | echo "Sending results to Kevin Hilman" 169 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["khilman@kernel.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 170 | elif [ "$TREE_NAME" == "krzysztof" ]; then 171 | echo "Sending results to Krzysztof Kozlowski" 172 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["krzk@kernel.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 173 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["krzk@kernel.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 174 | elif [ "$TREE_NAME" == "kselftest" ]; then 175 | echo "Sending results for kselftest tree" 176 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "delay": 60}' ${API}/send 177 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-cpufreq", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 178 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-filesystems", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 179 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-futex", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 180 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lib", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 181 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-livepatch", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 182 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-lkdtm", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 183 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-rtc", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 184 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "kselftest-seccomp", "send_to": ["kernelci-results@groups.io", "linux-kselftest@vger.kernel.org", "shuah@kernel.org"], "format": ["txt"], "delay": 3600}' ${API}/send 185 | elif [ "$TREE_NAME" == "lee-backlight" ]; then 186 | echo "Sending results for Lee's Backlight tree" 187 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["lee@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 188 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["lee@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 189 | elif [ "$TREE_NAME" == "lee-mfd" ]; then 190 | echo "Sending results for Lee's MFD tree" 191 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["lee@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 192 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["lee@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 193 | elif [ "$TREE_NAME" == "linusw" ]; then 194 | echo "Sending results to linux-gpio" 195 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["linux-gpio@vger.kernel.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 10}' ${API}/send 196 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["linux-gpio@vger.kernel.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 2700}' ${API}/send 197 | elif [ "$TREE_NAME" == "mainline" ]; then 198 | echo "Sending results for mainline" 199 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 200 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 201 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-av1", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 202 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h264", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 203 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h265", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 204 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp8", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 205 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp9", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 206 | elif [ "$TREE_NAME" == "media" ]; then 207 | echo "Sending results for media tree" 208 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-vivid", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 209 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-uvc", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 210 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-av1", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 211 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h264", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 212 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h265", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 213 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp8", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 214 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp9", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 215 | elif [ "$TREE_NAME" == "net-next" ]; then 216 | echo "Sending results for net-next tree" 217 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 218 | elif [ "$TREE_NAME" == "next" ]; then 219 | echo "Sending results to Linux Next" 220 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 221 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["linux-next@vger.kernel.org"], "format": ["txt"], "delay": 10}' ${API}/send 222 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["linux-next@vger.kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 223 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-av1", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 224 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h264", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 225 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-h265", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 226 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp8", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 227 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-decoder-conformance-vp9", "send_to": ["kernelci-results@groups.io"], "format": ["txt"], "delay": 5400}' ${API}/send 228 | echo "Sending build results to LLVM Linux for master only" 229 | if [ "$BRANCH" == "master" ]; then 230 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["llvm@lists.linux.dev"], "format": ["txt"], "delay": 10}' ${API}/send 231 | fi 232 | elif [ "$TREE_NAME" == "omap" ]; then 233 | echo "Sending results to Tony Lindgren" 234 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["tony@atomide.com", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 235 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["tony@atomide.com", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 236 | elif [ "$TREE_NAME" == "peterz" ]; then 237 | echo "Sending results to Peter Zijlstra" 238 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results@groups.io", "peterz@infradead.org"], "delay": 0}' ${API}/send 239 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernelci-results@groups.io", "peterz@infradead.org"], "format": ["txt"], "delay": 1800}' ${API}/send 240 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["kernelci-results@groups.io", "peterz@infradead.org"], "format": ["txt"], "delay": 1800}' ${API}/send 241 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["kernelci-results@groups.io", "peterz@infradead.org"], "format": ["txt"], "delay": 2700}' ${API}/send 242 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["kernelci-results@groups.io", "peterz@infradead.org"], "format": ["txt"], "delay": 2700}' ${API}/send 243 | elif [ "$TREE_NAME" == "pm" ]; then 244 | echo "Sending results for the pm tree" 245 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["rafael@kernel.org", "linux-pm@vger.kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 246 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["rafael@kernel.org", "linux-pm@vger.kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 247 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["rafael@kernel.org", "linux-pm@vger.kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 248 | elif [ "$TREE_NAME" == "pmwg" ]; then 249 | echo "Sending results to PMWG maintainers" 250 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["private-pmwg@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 10}' ${API}/send 251 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["daniel.lezcano@linaro.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 252 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["private-pmwg@lists.linaro.org", "daniel.lezcano@linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 253 | elif [ "$TREE_NAME" == "qcom-lt" ]; then 254 | echo "Sending results to QCOM-LT team" 255 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["qcomlt-patches@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 256 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["qcomlt-patches@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 257 | elif [ "$TREE_NAME" == "renesas" ]; then 258 | echo "Sending results to Renesas" 259 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 260 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 261 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 262 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 263 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-gpu-panfrost", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 264 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-exynos", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 265 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-kms-rockchip", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 266 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "igt-gpu-tegra", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 267 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "ltp-ipc", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 268 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 269 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "usb", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 270 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "v4l2-compliance-uvc", "send_to": ["linux-renesas-soc@vger.kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 3600}' ${API}/send 271 | elif [ "$TREE_NAME" == "riscv" ]; then 272 | echo "Sending results for RISC-V tree" 273 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results@groups.io", "kernel-ci-triage@rivosinc.com", "linux-riscv@lists.infradead.org"], "delay": 60}' ${API}/send 274 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernelci-results@groups.io", "kernel-ci-triage@rivosinc.com", "linux-riscv@lists.infradead.org"], "format": ["txt"], "delay": 1800}' ${API}/send 275 | elif [ "$TREE_NAME" == "robh" ]; then 276 | echo "Sending results for Rob Herring's tree" 277 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results@groups.io", "robh@kernel.org"], "delay": 60}' ${API}/send 278 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernelci-results@groups.io", "robh@kernel.org"], "format": ["txt"], "delay": 1800}' ${API}/send 279 | elif [ "$TREE_NAME" == "rmk" ]; then 280 | echo "Sending results for SoC tree" 281 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 282 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 283 | elif [ "$TREE_NAME" == "rppt" ]; then 284 | echo "Sending results for Mike Rapoport's tree" 285 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["rppt@kernel.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 286 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["rppt@kernel.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 287 | elif [ "$TREE_NAME" == "rt-stable" ]; then 288 | echo "Sending results for rt-stable tree" 289 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H 290 | "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["stable-rt@vger.kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 291 | elif [ "$TREE_NAME" == "samsung" ]; then 292 | echo "Sending results to Samsung Team" 293 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["krzk@kernel.org", "kgene.kim@samsung.com", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 294 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["krzk@kernel.org", "kgene.kim@samsung.com", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 295 | elif [ "$TREE_NAME" == "sashal" ]; then 296 | echo "Sending results for sashal's tree" 297 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["sashal@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 298 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["sashal@kernel.org", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 299 | elif [ "$TREE_NAME" == "soc" ]; then 300 | echo "Sending results for SoC tree" 301 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 302 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 1800}' ${API}/send 303 | elif [[ "$TREE_NAME" == "stable"* ]]; then 304 | echo "Sending stable results to stable pubic mailing list" 305 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 10}' ${API}/send 306 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 307 | if [ "$BRANCH" == "linux-4.4.y" ] || [ "$BRANCH" == "linux-4.9.y" ]; then 308 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["tom.gall@linaro.org", "sumit.semwal@linaro.org", "amit.pundir@linaro.org", "arnd.bergmann@linaro.org", "anmar.oueja@linaro.org"], "format": ["txt"], "delay": 10}' ${API}/send 309 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["tom.gall@linaro.org", "sumit.semwal@linaro.org", "amit.pundir@linaro.org", "arnd.bergmann@linaro.org", "anmar.oueja@linaro.org"], "format": ["txt"], "delay": 12600}' ${API}/send 310 | fi 311 | elif [ "$TREE_NAME" == "tegra" ]; then 312 | echo "Sending results to Tegra maintainers" 313 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["thierry.reding@gmail.com", "jonathanh@nvidia.com", "kernelci-results@groups.io"], "format": ["txt", "html"], "delay": 10}' ${API}/send 314 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["thierry.reding@gmail.com", "jonathanh@nvidia.com", "kernelci-results@groups.io"], "format": ["txt"], "delay": 12600}' ${API}/send 315 | elif [ "$TREE_NAME" == "thermal" ]; then 316 | echo "Sending results for the thermal tree" 317 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["daniel.lezcano@linaro.org", "rui.zhang@intel.com", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "delay": 60}' ${API}/send 318 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["daniel.lezcano@linaro.org", "rui.zhang@intel.com", "kernel-build-reports@lists.linaro.org", "kernelci-results@groups.io"], "format": ["txt"], "delay": 2700}' ${API}/send 319 | elif [ "$TREE_NAME" == "tip" ]; then 320 | echo "Sending results to x86 folks" 321 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["kernelci-results@groups.io", "x86@kernel.org"], "delay": 0}' ${API}/send 322 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["kernelci-results@groups.io", "x86@kernel.org"], "format": ["txt"], "delay": 1800}' ${API}/send 323 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline-nfs", "send_to": ["kernelci-results@groups.io", "x86@kernel.org"], "format": ["txt"], "delay": 1800}' ${API}/send 324 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "cros-ec", "send_to": ["kernelci-results@groups.io", "x86@kernel.org"], "format": ["txt"], "delay": 2700}' ${API}/send 325 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "sleep", "send_to": ["kernelci-results@groups.io", "x86@kernel.org"], "format": ["txt"], "delay": 2700}' ${API}/send 326 | elif [ "$TREE_NAME" == "ulfh" ]; then 327 | echo "Sending results to Ulf Hansson" 328 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["ulf.hansson@linaro.org", "fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 329 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["ulf.hansson@linaro.org", "fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 330 | elif [ "$TREE_NAME" == "vireshk" ]; then 331 | echo "Sending results for vireshk's tree" 332 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["vireshk@kernel.org"], "delay": 60}' ${API}/send 333 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["vireshk@kernel.org"], "format": ["txt"], "delay": 2700}' ${API}/send 334 | elif [ "$TREE_NAME" == "weiny2" ]; then 335 | echo "Sending results for weiny2 tree" 336 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["ira.weiny@intel.com", "iweiny@gmail.com"], "delay": 60}' ${API}/send 337 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["ira.weiny@intel.com", "iweiny@gmail.com"], "format": ["txt"], "delay": 2700}' ${API}/send 338 | elif [ "$TREE_NAME" == "mediatek" ]; then 339 | echo "Sending results for MediaTek tree" 340 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "format": ["txt"], "send_to": ["matthias.bgg@kernel.org", "angelogioacchino.delregno@kernel.org"], "delay": 60}' ${API}/send 341 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["matthias.bgg@kernel.org", "angelogioacchino.delregno@kernel.org"], "format": ["txt"], "delay": 2700}' ${API}/send 342 | 343 | else 344 | # Private Mailing List 345 | echo "Sending results to private mailing list" 346 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "build_report": 1, "send_to": ["fellows@kernelci.org"], "format": ["txt", "html"], "delay": 10}' ${API}/send 347 | curl -X POST -H "Authorization: $EMAIL_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"job": "'$TREE_NAME'", "kernel": "'$GIT_DESCRIBE'", "git_branch": "'$BRANCH'", "report_type": "test", "plan": "baseline", "send_to": ["fellows@kernelci.org"], "format": ["txt"], "delay": 12600}' ${API}/send 348 | fi 349 | -------------------------------------------------------------------------------- /scripts/push-source.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (C) 2017 Linaro Limited 4 | # Author: Matt Hart 5 | # 6 | # Copyright (C) 2019 Collabora Limited 7 | # Author: Guillaume Tucker 8 | # 9 | # This module is free software; you can redistribute it and/or modify it under 10 | # the terms of the GNU Lesser General Public License as published by the Free 11 | # Software Foundation; either version 2.1 of the License, or (at your option) 12 | # any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, but WITHOUT 15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 17 | # details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public License 20 | # along with this library; if not, write to the Free Software Foundation, Inc., 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import os 24 | import argparse 25 | import requests 26 | from urllib.parse import urljoin 27 | import time 28 | 29 | 30 | def do_post_retry(url=None, data=None, headers=None, files=None): 31 | retry = True 32 | count = 5 33 | while retry and count >= 0: 34 | try: 35 | response = requests.post( 36 | url, data=data, headers=headers, files=files) 37 | if str(response.status_code)[:1] != "2": 38 | raise Exception(response.content) 39 | else: 40 | return response.content 41 | retry = False 42 | except Exception as e: 43 | print("ERROR: failed to publish") 44 | print(e) 45 | count = count - 1 46 | time.sleep(10) 47 | print("Failed to push file") 48 | exit(1) 49 | 50 | 51 | parser = argparse.ArgumentParser() 52 | parser.add_argument("--token", help="KernelCI API Token") 53 | parser.add_argument("--tree", help="Kernel tree") 54 | parser.add_argument("--describe", help="Kernel describe", default='') 55 | parser.add_argument("--branch", help="Kernel branch") 56 | parser.add_argument("--file", nargs='+', help="File to upload") 57 | parser.add_argument("--api", help="KernelCI API URL", 58 | default="https://api.kernelci.org") 59 | parser.add_argument("--publish_path", help="file path at destination") 60 | 61 | args = vars(parser.parse_args()) 62 | 63 | artifacts = [] 64 | headers = {} 65 | build_data = {} 66 | headers['Authorization'] = args.get('token') 67 | 68 | publish_path = args.get('publish_path', None) 69 | if not publish_path: 70 | build_data['job'] = args.get('tree') 71 | build_data['kernel'] = args.get('describe', '') 72 | build_data['git_branch'] = args.get('branch') 73 | publish_path = os.path.join( 74 | build_data['job'], build_data['git_branch'], build_data['kernel']) 75 | 76 | build_data['path'] = publish_path 77 | build_data['file_server_resource'] = publish_path 78 | file_count = 0 79 | filenames = args.get('file') 80 | for f in filenames: 81 | artifacts.append(('file%d' % file_count, (f, open(f, 'rb'), 'rb'))) 82 | file_count += 1 83 | 84 | upload_url = urljoin(args.get('api'), '/upload') 85 | print("pushing %s to %s/%s" % (filenames, upload_url, publish_path)) 86 | publish_response = do_post_retry( 87 | url=upload_url, data=build_data, headers=headers, files=artifacts) 88 | -------------------------------------------------------------------------------- /src/org/kernelci/util/Job.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Collabora Limited 3 | Author: Guillaume Tucker 4 | 5 | This module is free software; you can redistribute it and/or modify it under 6 | the terms of the GNU Lesser General Public License as published by the Free 7 | Software Foundation; either version 2.1 of the License, or (at your option) 8 | any later version. 9 | 10 | This library is distributed in the hope that it will be useful, but WITHOUT 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this library; if not, write to the Free Software Foundation, Inc., 17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | 21 | package org.kernelci.util; 22 | 23 | def addStrParams(params, str_params) { 24 | for (p in str_params) { 25 | params.push( 26 | [$class: "StringParameterValue", name: p.key, value: p.value]) 27 | } 28 | } 29 | 30 | def addBoolParams(params, bool_params) { 31 | for (p in bool_params) { 32 | params.push( 33 | [$class: "BooleanParameterValue", name: p.key, value: p.value]) 34 | } 35 | } 36 | 37 | def cloneKciCore(path, url, branch) { 38 | sh(script: "rm -rf ${path}") 39 | dir("${path}") { 40 | git(url: url, 41 | branch: branch, 42 | poll: false) 43 | } 44 | } 45 | 46 | def dockerImageName(build_env, kernel_arch) { 47 | def image_name = build_env 48 | 49 | def build_env_raw = sh( 50 | script: """ 51 | kci_build \ 52 | show_build_env \ 53 | --build-env=${build_env} \ 54 | --arch=${kernel_arch} \ 55 | """, returnStdout: true).trim() 56 | def build_env_data = build_env_raw.split('\n').toList() 57 | def cc_arch = build_env_data[3] 58 | 59 | if (cc_arch == 'sparc') /* No kselftest variant for sparc */ 60 | image_name = "${build_env}:${cc_arch}-kernelci" 61 | else if (cc_arch) 62 | image_name = "${build_env}:${cc_arch}-kselftest-kernelci" 63 | else 64 | image_name = "${build_env}:kselftest-kernelci" 65 | 66 | return image_name 67 | } 68 | 69 | def dockerPullWithRetry(image_name, retries=10, sleep_time=1) { 70 | def image = docker.image(image_name) 71 | def pulled = false 72 | 73 | while (!pulled) { 74 | try { 75 | image.pull() 76 | pulled = true 77 | } 78 | catch (Exception e) { 79 | if (!retries) { 80 | throw e 81 | } 82 | echo("""Docker pull failed, retry count ${retries}: ${e.toString()}""") 83 | sleep sleep_time 84 | retries -= 1 85 | sleep_time = sleep_time * 2 86 | } 87 | } 88 | 89 | return image 90 | } 91 | --------------------------------------------------------------------------------