diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ecce863 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text eol=lf +*.png binary +*.jpg binary +*.jpeg binary +*.jar binary diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ce072c8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.tabSize": 2 +} diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000..9030854 --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,6 @@ +mode: ContinuousDeployment +branches: + master: + mode: ContinuousDeployment +ignore: + sha: [] diff --git a/README.md b/README.md index dcdd2f2..4c6890e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Ruby Sample App on OpenShift -============================ +Ruby Sample App on OpenShift (rubex) +==================================== This is a basic ruby application for OpenShift v3 that you can use as a starting point to develop your own application and deploy it on an [OpenShift](https://github.com/openshift/origin) cluster. diff --git a/config.ru b/config.ru index a709f06..92ea689 100755 --- a/config.ru +++ b/config.ru @@ -85,7 +85,6 @@ ul { display: table; /* 2 */ - } .container:after { clear: both; @@ -226,10 +225,9 @@ pre {
-

Welcome to your Ruby application on OpenShift

+

Welcome to your Ruby application on OpenShift (version {{BUILD_VERSION}})

-
diff --git a/deployment/config.yaml b/deployment/config.yaml new file mode 100644 index 0000000..189c629 --- /dev/null +++ b/deployment/config.yaml @@ -0,0 +1,24 @@ +prev: + deployment: + frontend: + templates: + - manifest: deployment/manifests/app.yaml + parameters: + ENV: prev + REPLICAS: 1 +dev: + deployment: + frontend: + templates: + - manifest: deployment/manifests/app.yaml + parameters: + ENV: dev + REPLICAS: 1 +test: + deployment: + frontend: + templates: + - manifest: deployment/manifests/app.yaml + parameters: + ENV: test + REPLICAS: 2 diff --git a/deployment/delivery-job-config.xml b/deployment/delivery-job-config.xml new file mode 100644 index 0000000..972b1be --- /dev/null +++ b/deployment/delivery-job-config.xml @@ -0,0 +1,45 @@ + + + + false + + + + + + + + + + -1 + 5 + -1 + -1 + + + + + + + + + + 2 + + + https://github.com/omallo/ruby-ex + + + + + */master + + + false + + + + deployment/delivery-pipeline.groovy + + + diff --git a/deployment/delivery-pipeline.groovy b/deployment/delivery-pipeline.groovy new file mode 100644 index 0000000..6106cb1 --- /dev/null +++ b/deployment/delivery-pipeline.groovy @@ -0,0 +1,45 @@ +@Library('occd') _ + +node() { + stage("Checkout") { + deleteDir() + git(url: "https://github.com/omallo/ruby-ex.git", branch: "master", credentialsId: "github-omallo") + } + + def config = occd.parseConfig(readFile("deployment/config.yaml")) + + stage("Build") { + def buildVersion = occd.getDeliveryBuildVersion() + echo "buildVersion=${buildVersion}" + + sh "sed -e 's/{{BUILD_VERSION}}/${buildVersion}/g' -i config.ru" + + occd.build("rubex-dev", "frontend-master", "deployment/manifests/build.yaml", "master") + } + + stage("Deploy to DEV") { + occd.tag("rubex-dev", "frontend", "b-master", "dev") + occd.rollout("rubex-dev", "frontend", config.dev.deployment.frontend) + } + + def isPromoteToTest = false + stage("Promote to TEST?") { + isPromoteToTest = input(message: "Promotion", parameters: [booleanParam(defaultValue: false, name: "Promote to TEST?")]) + } + + if (isPromoteToTest) { + stage("Deploy to TEST") { + def releaseVersion = occd.getReleaseVersion() + echo "releaseVersion=${releaseVersion}" + + withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'github-omallo', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) { + sh "git tag ${releaseVersion}" + sh "git push --tags https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/omallo/ruby-ex.git" + } + + occd.tag("rubex-dev", "frontend", "dev", releaseVersion) + occd.tag("rubex-dev", "frontend", releaseVersion, "test") + occd.rollout("rubex-test", "frontend", config.test.deployment.frontend) + } + } +} diff --git a/deployment/feature-build-pipeline.groovy b/deployment/feature-build-pipeline.groovy new file mode 100644 index 0000000..999d8a3 --- /dev/null +++ b/deployment/feature-build-pipeline.groovy @@ -0,0 +1,17 @@ +@Library('occd') _ + +node() { + stage("Checkout") { + deleteDir() + git(url: "https://github.com/omallo/ruby-ex.git", branch: "${BRANCH}", credentialsId: "github-omallo") + } + + stage("Build") { + def buildVersion = occd.getFeatureBuildVersion("${BRANCH}") + echo "versions: build=${buildVersion}" + + sh "sed -e 's/{{BUILD_VERSION}}/${buildVersion}/g' -i config.ru" + + occd.build("rubex-dev", "frontend-${BRANCH}", "deployment/manifests/build.yaml", "${BRANCH}") + } +} diff --git a/deployment/manifests/app.yaml b/deployment/manifests/app.yaml new file mode 100644 index 0000000..7aeadff --- /dev/null +++ b/deployment/manifests/app.yaml @@ -0,0 +1,100 @@ +apiVersion: v1 +kind: Template +objects: +#- apiVersion: v1 +# kind: PersistentVolumeClaim +# metadata: +# name: ${APP}-data +# labels: +# app: ${APP} +# spec: +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: ${STORAGE_SIZE} +- apiVersion: v1 + kind: DeploymentConfig + metadata: + name: ${APP} + labels: + app: ${APP} + spec: + replicas: ${REPLICAS} + selector: + app: ${APP} + deploymentconfig: ${APP} + template: + metadata: + labels: + app: ${APP} + deploymentconfig: ${APP} + spec: + containers: + - image: ${PROJECT_BASE}-${BUILD_ENV}/${APP}:${ENV} + imagePullPolicy: Always + name: ${APP} + ports: + - containerPort: 8080 + protocol: TCP + triggers: + - type: ImageChange + imageChangeParams: + automatic: false + containerNames: + - ${APP} + from: + kind: ImageStreamTag + name: ${APP}:${ENV} + namespace: ${PROJECT_BASE}-${BUILD_ENV} +- apiVersion: v1 + kind: Service + metadata: + name: ${APP} + labels: + app: ${APP} + spec: + ports: + - name: 8080-tcp + port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app: ${APP} + deploymentconfig: ${APP} +- apiVersion: v1 + kind: Route + metadata: + name: ${APP} + labels: + app: ${APP} + spec: + port: + targetPort: 8080-tcp + to: + kind: Service + name: ${APP} +parameters: +- description: The project base name. + displayName: Project base name + name: PROJECT_BASE + value: rubex +- description: The application name. + displayName: Application name + name: APP + value: frontend +- description: The environment in which the image stream is built. + displayName: Build environment + name: BUILD_ENV + value: dev +- description: The environment into which the app is deployed. + displayName: Environment + name: ENV +- description: The number of replicas. + displayName: Replicas + name: REPLICAS + value: "1" +- description: The size of the storage to reclaim. + displayName: Storage size + name: STORAGE_SIZE + value: 5Gi diff --git a/deployment/manifests/build.yaml b/deployment/manifests/build.yaml new file mode 100644 index 0000000..007b995 --- /dev/null +++ b/deployment/manifests/build.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Template +objects: +- apiVersion: v1 + kind: ImageStream + metadata: + name: ${APP} + labels: + app: ${APP} +- apiVersion: v1 + kind: BuildConfig + metadata: + name: ${APP}-${BRANCH} + labels: + app: ${APP} + spec: + output: + to: + kind: ImageStreamTag + name: ${APP}:b-${BRANCH} + source: + type: Binary + binary: {} + strategy: + type: Source + sourceStrategy: + from: + kind: ImageStreamTag + name: ruby:2.3 + namespace: openshift +parameters: +- description: The application name. + displayName: Application name + name: APP + value: frontend +- description: The branch being built. + displayName: Branch + name: BRANCH diff --git a/deployment/preview-pipeline.groovy b/deployment/preview-pipeline.groovy new file mode 100644 index 0000000..3225de4 --- /dev/null +++ b/deployment/preview-pipeline.groovy @@ -0,0 +1,15 @@ +@Library('occd') _ + +node() { + stage("Checkout") { + deleteDir() + git(url: "https://github.com/omallo/ruby-ex.git", branch: "${BRANCH}", credentialsId: "github-omallo") + } + + def config = occd.parseConfig(readFile("deployment/config.yaml")) + + stage("Deploy to PREV") { + occd.tag("rubex-dev", "frontend", "b-${BRANCH}", "prev") + occd.rollout("rubex-prev", "frontend", config.prev.deployment.frontend) + } +} diff --git a/infra/setup.sh b/infra/setup.sh new file mode 100644 index 0000000..5e76e14 --- /dev/null +++ b/infra/setup.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +sudo htpasswd -b /etc/origin/master/htpasswd dev1 dev1 +sudo htpasswd -b /etc/origin/master/htpasswd test1 test1 + +oc login -u system:admin +mkdir -p ~/openshift/volumes/ +oc delete -f infra/volumes-local.yaml +oc apply -f infra/volumes-local.yaml +oc get pv + +oc login -u system:admin +oc project openshift +oc delete is oc-jenkins +oc create is oc-jenkins +oc tag --source=docker --scheduled=true omallo/oc-jenkins:latest openshift/oc-jenkins:latest + +oc login -u admin -p admin +oc new-project rubex-prev +oc policy add-role-to-user edit dev1 -n rubex-prev +oc policy add-role-to-user view test1 -n rubex-prev + +oc login -u admin -p admin +oc new-project rubex-dev +oc policy add-role-to-user edit dev1 -n rubex-dev +oc policy add-role-to-user view test1 -n rubex-dev + +oc login -u admin -p admin +oc new-project rubex-test +oc policy add-role-to-user edit test1 -n rubex-test +oc policy add-role-to-group system:image-puller system:serviceaccounts:rubex-prev -n rubex-dev +oc policy add-role-to-group system:image-puller system:serviceaccounts:rubex-test -n rubex-dev + +oc login -u admin -p admin +oc new-project cicd +oc policy add-role-to-user edit system:serviceaccount:cicd:jenkins -n rubex-prev +oc policy add-role-to-user edit system:serviceaccount:cicd:jenkins -n rubex-dev +oc policy add-role-to-user edit system:serviceaccount:cicd:jenkins -n rubex-test + +oc login -u admin -p admin +oc project cicd +oc process \ + -f https://raw.githubusercontent.com/openshift/origin/master/examples/jenkins/jenkins-persistent-template.json \ + -v JENKINS_IMAGE_STREAM_TAG=oc-jenkins:latest \ + -v MEMORY_LIMIT=2Gi \ + -v VOLUME_CAPACITY=5Gi \ + | oc apply -f - + +mkdir -p ~/openshift/volumes/disk-1/jobs/rubex-frontend-delivery +cp deployment/delivery-job-config.xml ~/openshift/volumes/disk-1/jobs/rubex-frontend-delivery/config.xml + +# --- + +oc login -u dev1 -p dev1 +oc project rubex-dev + +oc new-app --name frontend ruby:2.3~https://github.com/omallo/ruby-ex # then: configure GitHub webhook +oc expose service frontend + +oc tag rubex-dev/frontend:latest rubex-dev/frontend:test + +oc login -u test1 -p test1 +oc project rubex-test + +oc new-app rubex-dev/frontend:test +oc expose service frontend + +oc login -u dev1 -p dev1 +oc project rubex-dev + +oc tag rubex-dev/frontend:latest rubex-dev/frontend:test diff --git a/infra/volumes-gce.yaml b/infra/volumes-gce.yaml new file mode 100644 index 0000000..52f0779 --- /dev/null +++ b/infra/volumes-gce.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: disk-1 +spec: + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + gcePersistentDisk: + pdName: disk-1 + fsType: ext4 diff --git a/infra/volumes-local.yaml b/infra/volumes-local.yaml new file mode 100644 index 0000000..5d283da --- /dev/null +++ b/infra/volumes-local.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: disk-1 +spec: + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /Users/omallo/openshift/volumes/disk-1