cicd-template.yaml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. apiVersion: v1
  2. kind: Template
  3. labels:
  4. template: cicd
  5. group: cicd
  6. metadata:
  7. annotations:
  8. iconClass: icon-jenkins
  9. tags: instant-app,jenkins,gogs,nexus,cicd
  10. name: cicd
  11. message: "Use the following credentials for login:\nJenkins: use your OpenShift credentials\nNexus: admin/admin123\nSonarQube: admin/admin\nGogs Git Server: gogs/gogs"
  12. parameters:
  13. - displayName: DEV project name
  14. value: dev
  15. name: DEV_PROJECT
  16. required: true
  17. - displayName: STAGE project name
  18. value: stage
  19. name: STAGE_PROJECT
  20. required: true
  21. - displayName: Deploy Eclipse Che
  22. description: Deploy Eclipse Che in order to use as an online IDE for changing code in this demo
  23. value: "false"
  24. name: DEPLOY_CHE
  25. required: true
  26. - displayName: Ephemeral
  27. description: Use no persistent storage for Gogs and Nexus
  28. value: "true"
  29. name: EPHEMERAL
  30. required: true
  31. - description: Webhook secret
  32. from: '[a-zA-Z0-9]{8}'
  33. generate: expression
  34. name: WEBHOOK_SECRET
  35. required: true
  36. - displayName: Integrate Quay.io
  37. description: Integrate image build and deployment with Quay.io
  38. value: "false"
  39. name: ENABLE_QUAY
  40. required: true
  41. - displayName: Quay.io Username
  42. description: Quay.io username to push the images to tasks-sample-app repository on your Quay.io account
  43. name: QUAY_USERNAME
  44. - displayName: Quay.io Password
  45. description: Quay.io password to push the images to tasks-sample-app repository on your Quay.io account
  46. name: QUAY_PASSWORD
  47. - displayName: Quay.io Image Repository
  48. description: Quay.io repository for pushing Tasks container images
  49. name: QUAY_REPOSITORY
  50. required: true
  51. value: tasks-app
  52. objects:
  53. - apiVersion: v1
  54. groupNames: null
  55. kind: RoleBinding
  56. metadata:
  57. name: default_admin
  58. roleRef:
  59. name: admin
  60. subjects:
  61. - kind: ServiceAccount
  62. name: default
  63. # Pipeline
  64. - apiVersion: v1
  65. kind: BuildConfig
  66. metadata:
  67. annotations:
  68. pipeline.alpha.openshift.io/uses: '[{"name": "jenkins", "namespace": "", "kind": "DeploymentConfig"}]'
  69. labels:
  70. app: cicd-pipeline
  71. name: cicd-pipeline
  72. name: tasks-pipeline
  73. spec:
  74. triggers:
  75. - type: GitHub
  76. github:
  77. secret: ${WEBHOOK_SECRET}
  78. - type: Generic
  79. generic:
  80. secret: ${WEBHOOK_SECRET}
  81. runPolicy: Serial
  82. source:
  83. type: None
  84. strategy:
  85. jenkinsPipelineStrategy:
  86. env:
  87. - name: DEV_PROJECT
  88. value: ${DEV_PROJECT}
  89. - name: STAGE_PROJECT
  90. value: ${STAGE_PROJECT}
  91. - name: ENABLE_QUAY
  92. value: ${ENABLE_QUAY}
  93. jenkinsfile: |-
  94. def mvnCmd = "mvn -s configuration/cicd-settings-nexus3.xml"
  95. pipeline {
  96. agent {
  97. label 'maven'
  98. }
  99. stages {
  100. stage('Build App') {
  101. steps {
  102. git branch: 'eap-7', url: 'http://gogs:3000/gogs/openshift-tasks.git'
  103. sh "${mvnCmd} install -DskipTests=true"
  104. }
  105. }
  106. stage('Test') {
  107. steps {
  108. sh "${mvnCmd} test"
  109. step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
  110. }
  111. }
  112. stage('Code Analysis') {
  113. steps {
  114. script {
  115. sh "${mvnCmd} sonar:sonar -Dsonar.host.url=http://sonarqube:9000 -DskipTests=true"
  116. }
  117. }
  118. }
  119. stage('Archive App') {
  120. steps {
  121. sh "${mvnCmd} deploy -DskipTests=true -P nexus3"
  122. }
  123. }
  124. stage('Build Image') {
  125. steps {
  126. sh "cp target/openshift-tasks.war target/ROOT.war"
  127. script {
  128. openshift.withCluster() {
  129. openshift.withProject(env.DEV_PROJECT) {
  130. openshift.selector("bc", "tasks").startBuild("--from-file=target/ROOT.war", "--wait=true")
  131. }
  132. }
  133. }
  134. }
  135. }
  136. stage('Deploy DEV') {
  137. steps {
  138. script {
  139. openshift.withCluster() {
  140. openshift.withProject(env.DEV_PROJECT) {
  141. openshift.selector("dc", "tasks").rollout().latest();
  142. }
  143. }
  144. }
  145. }
  146. }
  147. stage('Promote to STAGE?') {
  148. agent {
  149. label 'skopeo'
  150. }
  151. steps {
  152. timeout(time:15, unit:'MINUTES') {
  153. input message: "Promote to STAGE?", ok: "Promote"
  154. }
  155. script {
  156. openshift.withCluster() {
  157. if (env.ENABLE_QUAY.toBoolean()) {
  158. withCredentials([usernamePassword(credentialsId: "${openshift.project()}-quay-cicd-secret", usernameVariable: "QUAY_USER", passwordVariable: "QUAY_PWD")]) {
  159. sh "skopeo copy docker://quay.io/${QUAY_USERNAME}/${QUAY_REPOSITORY}:latest docker://quay.io/${QUAY_USERNAME}/${QUAY_REPOSITORY}:stage --src-creds \"$QUAY_USER:$QUAY_PWD\" --dest-creds \"$QUAY_USER:$QUAY_PWD\" --src-tls-verify=false --dest-tls-verify=false"
  160. }
  161. } else {
  162. openshift.tag("${env.DEV_PROJECT}/tasks:latest", "${env.STAGE_PROJECT}/tasks:stage")
  163. }
  164. }
  165. }
  166. }
  167. }
  168. stage('Deploy STAGE') {
  169. steps {
  170. script {
  171. openshift.withCluster() {
  172. openshift.withProject(env.STAGE_PROJECT) {
  173. openshift.selector("dc", "tasks").rollout().latest();
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. }
  181. type: JenkinsPipeline
  182. - apiVersion: v1
  183. kind: ConfigMap
  184. metadata:
  185. labels:
  186. app: cicd-pipeline
  187. role: jenkins-slave
  188. name: jenkins-slaves
  189. data:
  190. maven-template: |-
  191. <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
  192. <inheritFrom></inheritFrom>
  193. <name>maven</name>
  194. <privileged>false</privileged>
  195. <alwaysPullImage>false</alwaysPullImage>
  196. <instanceCap>2147483647</instanceCap>
  197. <idleMinutes>0</idleMinutes>
  198. <label>maven</label>
  199. <serviceAccount>jenkins</serviceAccount>
  200. <nodeSelector></nodeSelector>
  201. <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
  202. <workspaceVolume class="org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume">
  203. <memory>false</memory>
  204. </workspaceVolume>
  205. <volumes />
  206. <containers>
  207. <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
  208. <name>jnlp</name>
  209. <image>openshift/jenkins-agent-maven-35-centos7</image>
  210. <privileged>false</privileged>
  211. <alwaysPullImage>false</alwaysPullImage>
  212. <workingDir>/tmp</workingDir>
  213. <command></command>
  214. <args>${computer.jnlpmac} ${computer.name}</args>
  215. <ttyEnabled>false</ttyEnabled>
  216. <resourceRequestCpu>200m</resourceRequestCpu>
  217. <resourceRequestMemory>512Mi</resourceRequestMemory>
  218. <resourceLimitCpu>2</resourceLimitCpu>
  219. <resourceLimitMemory>4Gi</resourceLimitMemory>
  220. <envVars/>
  221. </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
  222. </containers>
  223. <envVars/>
  224. <annotations/>
  225. <imagePullSecrets/>
  226. </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
  227. skopeo-template: |-
  228. <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
  229. <inheritFrom></inheritFrom>
  230. <name>skopeo</name>
  231. <privileged>false</privileged>
  232. <alwaysPullImage>false</alwaysPullImage>
  233. <instanceCap>2147483647</instanceCap>
  234. <idleMinutes>0</idleMinutes>
  235. <label>skopeo</label>
  236. <serviceAccount>jenkins</serviceAccount>
  237. <nodeSelector></nodeSelector>
  238. <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
  239. <workspaceVolume class="org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume">
  240. <memory>false</memory>
  241. </workspaceVolume>
  242. <volumes />
  243. <containers>
  244. <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
  245. <name>jnlp</name>
  246. <image>docker.io/siamaksade/jenkins-slave-skopeo-centos7</image>
  247. <privileged>false</privileged>
  248. <alwaysPullImage>false</alwaysPullImage>
  249. <workingDir>/tmp</workingDir>
  250. <command></command>
  251. <args>${computer.jnlpmac} ${computer.name}</args>
  252. <ttyEnabled>false</ttyEnabled>
  253. <envVars/>
  254. </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
  255. </containers>
  256. <envVars/>
  257. <annotations/>
  258. <imagePullSecrets/>
  259. </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
  260. # Setup Demo
  261. - apiVersion: batch/v1
  262. kind: Job
  263. metadata:
  264. name: cicd-demo-installer
  265. spec:
  266. activeDeadlineSeconds: 400
  267. completions: 1
  268. parallelism: 1
  269. template:
  270. spec:
  271. containers:
  272. - env:
  273. - name: CICD_NAMESPACE
  274. valueFrom:
  275. fieldRef:
  276. fieldPath: metadata.namespace
  277. command:
  278. - /bin/bash
  279. - -x
  280. - -c
  281. - |
  282. # adjust jenkins
  283. oc set resources dc/jenkins --limits=cpu=2,memory=2Gi --requests=cpu=100m,memory=512Mi
  284. oc label dc jenkins app=jenkins --overwrite
  285. # setup dev env
  286. oc import-image wildfly --from=openshift/wildfly-120-centos7 --confirm -n ${DEV_PROJECT}
  287. if [ "${ENABLE_QUAY}" == "true" ] ; then
  288. # cicd
  289. oc create secret generic quay-cicd-secret --from-literal="username=${QUAY_USERNAME}" --from-literal="password=${QUAY_PASSWORD}" -n ${CICD_NAMESPACE}
  290. oc label secret quay-cicd-secret credential.sync.jenkins.openshift.io=true -n ${CICD_NAMESPACE}
  291. # dev
  292. oc create secret docker-registry quay-cicd-secret --docker-server=quay.io --docker-username="${QUAY_USERNAME}" --docker-password="${QUAY_PASSWORD}" --docker-email=cicd@redhat.com -n ${DEV_PROJECT}
  293. oc new-build --name=tasks --image-stream=wildfly:latest --binary=true --push-secret=quay-cicd-secret --to-docker --to='quay.io/${QUAY_USERNAME}/${QUAY_REPOSITORY}:latest' -n ${DEV_PROJECT}
  294. oc new-app --name=tasks --docker-image=quay.io/${QUAY_USERNAME}/${QUAY_REPOSITORY}:latest --allow-missing-images -n ${DEV_PROJECT}
  295. oc set triggers dc tasks --remove-all -n ${DEV_PROJECT}
  296. oc patch dc tasks -p '{"spec": {"template": {"spec": {"containers": [{"name": "tasks", "imagePullPolicy": "Always"}]}}}}' -n ${DEV_PROJECT}
  297. oc delete is tasks -n ${DEV_PROJECT}
  298. oc secrets link default quay-cicd-secret --for=pull -n ${DEV_PROJECT}
  299. # stage
  300. oc create secret docker-registry quay-cicd-secret --docker-server=quay.io --docker-username="${QUAY_USERNAME}" --docker-password="${QUAY_PASSWORD}" --docker-email=cicd@redhat.com -n ${STAGE_PROJECT}
  301. oc new-app --name=tasks --docker-image=quay.io/${QUAY_USERNAME}/${QUAY_REPOSITORY}:stage --allow-missing-images -n ${STAGE_PROJECT}
  302. oc set triggers dc tasks --remove-all -n ${STAGE_PROJECT}
  303. oc patch dc tasks -p '{"spec": {"template": {"spec": {"containers": [{"name": "tasks", "imagePullPolicy": "Always"}]}}}}' -n ${STAGE_PROJECT}
  304. oc delete is tasks -n ${STAGE_PROJECT}
  305. oc secrets link default quay-cicd-secret --for=pull -n ${STAGE_PROJECT}
  306. else
  307. # dev
  308. oc new-build --name=tasks --image-stream=wildfly:latest --binary=true -n ${DEV_PROJECT}
  309. oc new-app tasks:latest --allow-missing-images -n ${DEV_PROJECT}
  310. oc set triggers dc -l app=tasks --containers=tasks --from-image=tasks:latest --manual -n ${DEV_PROJECT}
  311. # stage
  312. oc new-app tasks:stage --allow-missing-images -n ${STAGE_PROJECT}
  313. oc set triggers dc -l app=tasks --containers=tasks --from-image=tasks:stage --manual -n ${STAGE_PROJECT}
  314. fi
  315. # dev project
  316. oc expose dc/tasks --port=8080 -n ${DEV_PROJECT}
  317. oc expose svc/tasks -n ${DEV_PROJECT}
  318. oc set probe dc/tasks --readiness --get-url=http://:8080/ws/demo/healthcheck --initial-delay-seconds=30 --failure-threshold=10 --period-seconds=10 -n ${DEV_PROJECT}
  319. oc set probe dc/tasks --liveness --get-url=http://:8080/ws/demo/healthcheck --initial-delay-seconds=180 --failure-threshold=10 --period-seconds=10 -n ${DEV_PROJECT}
  320. oc rollout cancel dc/tasks -n ${STAGE_PROJECT}
  321. # stage project
  322. oc expose dc/tasks --port=8080 -n ${STAGE_PROJECT}
  323. oc expose svc/tasks -n ${STAGE_PROJECT}
  324. oc set probe dc/tasks --readiness --get-url=http://:8080/ws/demo/healthcheck --initial-delay-seconds=30 --failure-threshold=10 --period-seconds=10 -n ${STAGE_PROJECT}
  325. oc set probe dc/tasks --liveness --get-url=http://:8080/ws/demo/healthcheck --initial-delay-seconds=180 --failure-threshold=10 --period-seconds=10 -n ${STAGE_PROJECT}
  326. oc rollout cancel dc/tasks -n ${DEV_PROJECT}
  327. # deploy gogs
  328. HOSTNAME=$(oc get route jenkins -o template --template='{{.spec.host}}' | sed "s/jenkins-${CICD_NAMESPACE}.//g")
  329. GOGS_HOSTNAME="gogs-$CICD_NAMESPACE.$HOSTNAME"
  330. if [ "${EPHEMERAL}" == "true" ] ; then
  331. oc new-app -f https://raw.githubusercontent.com/OpenShiftDemos/gogs-openshift-docker/master/openshift/gogs-template.yaml \
  332. --param=GOGS_VERSION=0.11.34 \
  333. --param=HOSTNAME=$GOGS_HOSTNAME \
  334. --param=SKIP_TLS_VERIFY=true
  335. else
  336. oc new-app -f https://raw.githubusercontent.com/OpenShiftDemos/gogs-openshift-docker/master/openshift/gogs-persistent-template.yaml \
  337. --param=GOGS_VERSION=0.11.34 \
  338. --param=HOSTNAME=$GOGS_HOSTNAME \
  339. --param=SKIP_TLS_VERIFY=true
  340. fi
  341. sleep 5
  342. oc new-app -f http://bit.ly/openshift-sonarqube-embedded-template --param=SONARQUBE_VERSION=7.0 --param=SONAR_MAX_MEMORY=6Gi
  343. if [ "${EPHEMERAL}" == "true" ] ; then
  344. oc set volume dc/sonarqube --name=sonarqube-data --add -t emptyDir --overwrite -n $CICD_NAMESPACE
  345. oc delete pvc sonarqube-data -n $CICD_NAMESPACE
  346. fi
  347. if [ "${DEPLOY_CHE}" == "true" ] ; then
  348. oc process -f https://raw.githubusercontent.com/minishift/minishift/master/addons/che/templates/che-single-user.yml \
  349. --param PROJECT_NAME=$CICD_NAMESPACE \
  350. --param DOMAIN_NAME=$HOSTNAME \
  351. --param OPENSHIFT_OAUTH_TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
  352. | oc create -f -
  353. oc set resources dc/che --limits=cpu=1,memory=2Gi --requests=cpu=200m,memory=512Mi
  354. fi
  355. if [ "${EPHEMERAL}" == "true" ] ; then
  356. oc new-app -f https://raw.githubusercontent.com/OpenShiftDemos/nexus/master/nexus3-template.yaml --param=NEXUS_VERSION=3.13.0 --param=MAX_MEMORY=2Gi
  357. else
  358. oc new-app -f https://raw.githubusercontent.com/OpenShiftDemos/nexus/master/nexus3-persistent-template.yaml --param=NEXUS_VERSION=3.13.0 --param=MAX_MEMORY=2Gi
  359. fi
  360. oc set resources dc/nexus --requests=cpu=200m,memory=1Gi --limits=cpu=2,memory=4Gi
  361. GOGS_SVC=$(oc get svc gogs -o template --template='{{.spec.clusterIP}}')
  362. GOGS_USER=gogs
  363. GOGS_PWD=gogs
  364. oc rollout status dc gogs
  365. _RETURN=$(curl -o /tmp/curl.log -sL --post302 -w "%{http_code}" http://$GOGS_SVC:3000/user/sign_up \
  366. --form user_name=$GOGS_USER \
  367. --form password=$GOGS_PWD \
  368. --form retype=$GOGS_PWD \
  369. --form email=admin@gogs.com)
  370. sleep 5
  371. if [ $_RETURN != "200" ] && [ $_RETURN != "302" ] ; then
  372. echo "ERROR: Failed to create Gogs admin"
  373. cat /tmp/curl.log
  374. exit 255
  375. fi
  376. sleep 10
  377. cat <<EOF > /tmp/data.json
  378. {
  379. "clone_addr": "https://github.com/OpenShiftDemos/openshift-tasks.git",
  380. "uid": 1,
  381. "repo_name": "openshift-tasks"
  382. }
  383. EOF
  384. _RETURN=$(curl -o /tmp/curl.log -sL -w "%{http_code}" -H "Content-Type: application/json" \
  385. -u $GOGS_USER:$GOGS_PWD -X POST http://$GOGS_SVC:3000/api/v1/repos/migrate -d @/tmp/data.json)
  386. if [ $_RETURN != "201" ] ;then
  387. echo "ERROR: Failed to import openshift-tasks GitHub repo"
  388. cat /tmp/curl.log
  389. exit 255
  390. fi
  391. sleep 5
  392. cat <<EOF > /tmp/data.json
  393. {
  394. "type": "gogs",
  395. "config": {
  396. "url": "https://openshift.default.svc.cluster.local/oapi/v1/namespaces/$CICD_NAMESPACE/buildconfigs/tasks-pipeline/webhooks/${WEBHOOK_SECRET}/generic",
  397. "content_type": "json"
  398. },
  399. "events": [
  400. "push"
  401. ],
  402. "active": true
  403. }
  404. EOF
  405. _RETURN=$(curl -o /tmp/curl.log -sL -w "%{http_code}" -H "Content-Type: application/json" \
  406. -u $GOGS_USER:$GOGS_PWD -X POST http://$GOGS_SVC:3000/api/v1/repos/gogs/openshift-tasks/hooks -d @/tmp/data.json)
  407. if [ $_RETURN != "201" ] ; then
  408. echo "ERROR: Failed to set webhook"
  409. cat /tmp/curl.log
  410. exit 255
  411. fi
  412. image: openshift/origin:v3.11
  413. name: cicd-demo-installer-job
  414. resources: {}
  415. terminationMessagePath: /dev/termination-log
  416. terminationMessagePolicy: File
  417. restartPolicy: Never