├── .gitignore ├── README.md ├── deploy ├── Jenkinsfile └── README.md ├── docker-app-chart ├── Chart.yaml ├── Chart_README.md ├── Jenkinsfile ├── README.md ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── secret.yaml │ └── service.yaml └── values.yaml ├── docker-app ├── Dockerfile ├── Jenkinsfile ├── README.md ├── app-test │ ├── promote-gradleWar.json │ └── retag.json ├── appmodules-download.json └── retag.json ├── docker-framework ├── Dockerfile ├── Jenkinsfile ├── README.md ├── framework-download.json ├── framework-test │ └── Dockerfile ├── gradeWar-download.json ├── retag.json └── tomcat │ └── server.xml ├── gradle-example ├── Jenkinsfile ├── README.md ├── api │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── gradle │ │ ├── api │ │ ├── PersonList.java │ │ └── package.html │ │ └── apiImpl │ │ └── Impl.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── increment.sh ├── services │ └── webservice │ │ ├── build.gradle │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── gradle │ │ │ │ └── webservice │ │ │ │ └── TestTest.java │ │ └── webapp │ │ │ ├── images │ │ │ ├── k8s-reg.jpg │ │ │ ├── logo.png │ │ │ └── ready_weekend.png │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── org │ │ └── gradle │ │ └── webservice │ │ └── TestTestTest.java ├── settings.gradle └── shared │ └── src │ └── main │ ├── java │ └── org │ │ └── gradle │ │ └── shared │ │ ├── Person.java │ │ └── package-info.java │ └── resources │ └── org │ └── gradle │ └── shared │ └── main.properties └── images ├── Add_Artifactory_Server.png ├── Add_Credentials.png └── configure_docker.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff: 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/dictionaries 10 | 11 | # Sensitive or high-churn files: 12 | .idea/**/dataSources/ 13 | .idea/**/dataSources.ids 14 | .idea/**/dataSources.xml 15 | .idea/**/dataSources.local.xml 16 | .idea/**/sqlDataSources.xml 17 | .idea/**/dynamic.xml 18 | .idea/**/uiDesigner.xml 19 | 20 | # Gradle: 21 | .idea/**/gradle.xml 22 | .idea/**/libraries 23 | 24 | # CMake 25 | cmake-build-debug/ 26 | 27 | # Mongo Explorer plugin: 28 | .idea/**/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.iws 32 | 33 | ## Plugin-specific files: 34 | 35 | # IntelliJ 36 | out/ 37 | 38 | # mpeltonen/sbt-idea plugin 39 | .idea_modules/ 40 | 41 | # JIRA plugin 42 | atlassian-ide-plugin.xml 43 | 44 | # Cursive Clojure plugin 45 | .idea/replstate.xml 46 | 47 | # Crashlytics plugin (for Android Studio and IntelliJ) 48 | com_crashlytics_export_strings.xml 49 | crashlytics.properties 50 | crashlytics-build.properties 51 | fabric.properties 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 5 Step CI/CD In Kubernetes using Artifactory, Jenkins & Helm 2 | 3 | # Contents 4 | 5 | - [Setup Kubernetes Cluster on EKS](#setup-kubernetes-cluster-on-eks) 6 | - [Setup Kubernetes Cluster on GKE](#setup-kubernetes-cluster-on-gke) 7 | - [Setup Kubernetes Cluster on AKS](#setup-kubernetes-cluster-on-aks) 8 | - [Install Artifactory on kubernetes](#install-artifactory-on-kubernetes) 9 | - [Install Jenkins on kubernetes](#install-jenkins-on-kubernetes) 10 | - [Configure Continuous Integration/Continuous Deployment](#5-step-cicd) 11 | 12 | 13 | ### Prerequisites 14 | * Basic knowledge of [Docker](https://www.docker.com/), [Jenkins](https://jenkins.io/), [Kubernetes](https://kubernetes.io/) and [Artifactory](https://www.jfrog.com/artifactory/) 15 | 16 | ## Setup Kubernetes Cluster on EKS 17 | Follow this to setup kubernetes cluster on EKS. [https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html) 18 | 19 | ## Setup Kubernetes Cluster on GKE 20 | Follow this to setup kubernetes cluster on GKE. [https://cloud.google.com/container-engine/docs/quickstart](https://cloud.google.com/container-engine/docs/quickstart) 21 | 22 | ## Setup Kubernetes Cluster on AKS 23 | Follow this to setup kubernetes cluster on AKS. [https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-deploy-cluster](https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-deploy-cluster) 24 | 25 | ## Install Artifactory on kubernetes 26 | Here is documentation to install JFrog Artifactory on kubernetes [artifactory-docker-examples](https://github.com/JFrogDev/artifactory-docker-examples/tree/master/kubernetes)
27 | Here is link to official helm chart for Artifactory [https://github.com/kubernetes/charts/tree/master/stable/artifactory](https://github.com/kubernetes/charts/tree/master/stable/artifactory) 28 | 29 | Note If you are using [Artifactory SaaS](https://www.jfrog.com/artifactory/free-trial/#Cloud) you can skip this step. 30 | 31 | ### Configure docker insecure registry in each node of kubernetes cluster if you are using self-signed certificate. 32 | 33 | * Get cluster ip of nginx services by running following command: 34 | ``` 35 | kubectl get services nginx-kubernetes-service 36 | ``` 37 | * Ssh into each node of cluster and configure insecure registry using steps provided [here](https://docs.docker.com/registry/insecure/) 38 | 39 | Note: configure range which include `$CLUSTER_IP` as insecure registry. 40 | 41 | * Add following entry in `/etc/hosts` file: 42 | ``` 43 | $CLUSTER_IP docker.artifactory docker-remote.artifactory docker-local.artifactory 44 | ``` 45 | * Pull `node` docker image from artifactory by running following command: 46 | ``` 47 | docker pull docker.artifactory/node 48 | ``` 49 | 50 | ## Install Jenkins on kubernetes 51 | 52 | Use [Helm](https://github.com/kubernetes/helm) [Chart](https://github.com/kubernetes/charts) to install [jenkins](https://github.com/kubernetes/charts/tree/master/stable/jenkins) in kubernetes.
53 | Note: Make sure to increase resources for Jenkins deployment in [values.yaml](https://github.com/kubernetes/charts/blob/master/stable/jenkins/values.yaml) file. Jenkins comes with the Kubernetes plugin..
54 | Cache docker images of jenkins master and agent in Artifactory by changing value of `Master.Image` to `docker.artifactory/jenkinsci/jenkins` and `Agent.Image` to `docker.artifactory/jenkinsci/jnlp-slave` in [values.yaml](https://github.com/kubernetes/charts/blob/master/stable/jenkins/values.yaml) file. 55 | 56 | 57 | ### Configuring Jenkins to build docker images: 58 | 59 | * From Jenkins home click on Manage Jenkins -> Configure System. 60 | * You will see section Cloud -> Kubernetes -> Images -> Volumes. 61 | * Click on Add Volume and add Host Path Volume with following mount path: 62 | ![configure_docker](images/configure_docker.png) 63 | * ssh into each kubernetes node of your cluster and perform following: 64 | 1. Create `jenkins` user. 65 | 2. Add `jenkins` user to docker group. 66 | 3. Make sure `jenkins` user can access `/var/run/docker.sock` and `/usr/bin/docker` in each kubernetes node. 67 | 4. Create `test` job in Jenkins and run `docker version` command from `test` job. 68 | 69 | # 5 Step CI/CD 70 | 71 | ## Step 1. Create an application war file 72 | * Creates a sample application called ‘webservice-1.1.2.war’ 73 | * Pushes it to a local repository in Artifactory 74 | * [gradle-example](/gradle-example) 75 | 76 | ## Step 2. Create a template Docker image 77 | * Creates a base Docker image called ‘docker-framework’ using Ubuntu + Java + Tomcat 78 | * Pushes it to a local repository in Artifactory 79 | * [docker-framework](/docker-framework) 80 | 81 | ## Step 3. Create a product Docker image 82 | * Downloads, from Artifactory, the ‘webservice-1.1.2.war’ file and the ‘docker-framework’ Docker image, that were created in the previous two pipelines 83 | * Creates a ‘docker-app’ production Docker image 84 | * Pushes it to Artifactory 85 | * Promotes it to a production repository in Artifactory 86 | * [docker-app](/docker-app) 87 | 88 | ## Step 4. Create Helm chart of product Docker image 89 | * Create helm chart of `docker-app` 90 | * Push helm chart in local helm repository in Artifactory 91 | * [chart](/docker-app-chart) 92 | 93 | ## Step 5. Deploy `docker-app` in Kubernetes cluster using helm chart 94 | * Pull helm chart from Virtual helm repository of Artifactory 95 | * Deploy `docker-app` in Kubernetes using downloaded helm chart 96 | * [deploy](/deploy) 97 | -------------------------------------------------------------------------------- /deploy/Jenkinsfile: -------------------------------------------------------------------------------- 1 | node { 2 | 3 | stage('Install helm') { 4 | /* This installs helm client */ 5 | sh "curl -O https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz" 6 | sh "tar -xvf helm-v2.9.1-linux-amd64.tar.gz" 7 | sh "chmod 777 ./linux-amd64/helm" 8 | sh "./linux-amd64/helm version" 9 | } 10 | 11 | stage('Configure helm & add Artifactory repo') { 12 | /* Configure helm client to point to k8s cluster */ 13 | sh './linux-amd64/helm init --upgrade' 14 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 15 | sh "./linux-amd64/helm version" 16 | sh "./linux-amd64/helm repo add artifactory ${SERVER_URL}/helm --username ${env.USERNAME} --password ${env.PASSWORD}" 17 | sh "./linux-amd64/helm repo update" 18 | } 19 | } 20 | 21 | stage('Deploy chart pulling from Artifactory') { 22 | /* Finally, we'll deploy the image to k8s using helm chart. */ 23 | sh "./linux-amd64/helm upgrade my-docker-app --install --recreate-pods artifactory/docker-app-chart" 24 | } 25 | } -------------------------------------------------------------------------------- /deploy/README.md: -------------------------------------------------------------------------------- 1 | ## Deploy `docker-app` in Kubernetes cluster using helm chart 2 | * Pull helm chart from Virtual helm repository of Artifactory 3 | * Deploy `docker-app` in Kubernetes using downloaded helm chart 4 | 5 | 1. On the Jenkins front page, click on Credentials -> System -> Global credentials -> Add Credentials 6 | Add your Artifactory credentials as the type Username with password, with the ID artifactory-credentials 7 | ![Add_Artifactory_Credentials](../images/Add_Credentials.png) 8 | 9 | 2. Create new Jenkins Pipeline Job. 10 | 11 | 3. Create Helm repositories in Artifactory using [quick setup wizard](https://www.jfrog.com/confluence/display/RTF/Getting+Started#GettingStarted-OnboardingWizard). 12 | 13 | 4. Add String Parameters: 14 | * IMAGE_TAG (String Parameter) : Domain of Artifactory docker registry 15 | e.g `IMAGE_TAG : latest` 16 | * SERVER_URL (String Parameter) : Artifactory Server URL
17 | e.g. `SERVER_URL -> http://35.225.27.231/artifactory` 18 | * REPO (String Parameter) : Artifactory Helm repo
19 | e.g. `REPO -> helm` 20 | * CREDENTIALS (Credentials Parameter) : Artifactory Credential
21 | e.g. `CREDENTIALS -> artifactory-credentials` 22 | 23 | 5. Copy [Jenkinsfile](Jenkinsfile) to Pipeline Script. 24 | 25 | 6. To build it, press Build Now. 26 | 27 | 7. Check your newly published build in build browser of Artifactory. 28 | 29 | ## Commands to deploy `docker-app` chart manually to K8S cluster. 30 | 31 | * Add Artifactory Helm repo with helm client 32 | ``` 33 | helm repo add artifactory $ART_URL/$HELM_REPO --username $ART_USERNAME --password $ART_PASSWORD 34 | ``` 35 | **Note**: `--username` and `--pasword` flag is only supported in helm version 2.9.0 and higher. 36 | 37 | * Update local helm repo index 38 | ``` 39 | helm repo update 40 | ``` 41 | 42 | * Install `docker-app` in k8s 43 | ``` 44 | helm install my-docker-app artifactory/docker-app-chart 45 | ``` 46 | -------------------------------------------------------------------------------- /docker-app-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Kubernetes 3 | name: docker-app-chart 4 | version: 0.1.1 5 | keywords: 6 | - http 7 | - node 8 | - web 9 | - npm 10 | home: https://github.com/jfrogtraining/swampup/ 11 | sources: 12 | - https://github.com/jfrogtraining/swampup/ 13 | maintainers: 14 | - name: jainishshah17 15 | email: jainishs@jfrog.com 16 | icon: https://raw.githubusercontent.com/JFrogDev/artifactory-dcos/master/images/jfrog_med.png -------------------------------------------------------------------------------- /docker-app-chart/Chart_README.md: -------------------------------------------------------------------------------- 1 | # Helm Chart for docker-app 2 | 3 | ### Configure docker registry credentials in K8S to pull docker image from Artifactory docker registry 4 | 5 | ## Create a Secret named regsecret: 6 | ``` 7 | kubectl create secret docker-registry regsecret --docker-server= --docker-username= --docker-password= --docker-email= 8 | ``` 9 | ##### where: 10 | ``` 11 | is your Private Docker Registry FQDN. 12 | is your Docker username. 13 | is your Docker password. 14 | is your Docker email. 15 | ``` 16 | 17 | ##### Understanding your Secret 18 | 19 | To understand what’s in the Secret you just created, start by viewing the Secret in YAML format: 20 | ``` 21 | kubectl get secret regsecret --output=yaml 22 | ``` 23 | 24 | ## Installing the Chart 25 | 26 | To install the chart with the release name `my-release`: 27 | 28 | ```console 29 | $ helm install --name my-release ./ 30 | ``` 31 | 32 | The command deploys docker-app on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 33 | 34 | > **Tip**: List all releases using `helm list` 35 | 36 | ## Uninstalling the Chart 37 | 38 | To uninstall/delete the `my-release` deployment: 39 | 40 | ```console 41 | $ helm delete my-release --purge 42 | ``` 43 | 44 | The command removes all the Kubernetes components associated with the chart and deletes the release. 45 | 46 | ## Configuration 47 | 48 | The following tables lists the configurable parameters of the docker-app chart and their default values. 49 | 50 | | Parameter | Description | Default | 51 | |------------------------------------|-------------------------------------|-----------------------------------------------------------| 52 | | `image.repository` | docker-app image | `$ART_DOCKER_REPO/docker-app:{tag}` | 53 | | `image.pullPolicy` | Image pull policy | `Always` | 54 | | `image.tag` | Tag of docker image | `latest` | 55 | | `image.secretName` | Credentials of Art docker repo | `regsecret` | 56 | | `service.type` | Kubernetes Service type | `LoadBalancer` | 57 | | `service.port` | Port to expose | `8181` | 58 | | `imageCredentials.registry` | Artifactory docker registry | `docker.artifactory` | 59 | | `imageCredentials.username` | Artifactory username | `admin` | 60 | | `imageCredentials.password` | Artifactory password | `password` | 61 | 62 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 63 | 64 | ```console 65 | $ helm install --name my-release --set image.tag=27 ./ 66 | ``` 67 | 68 | Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, 69 | 70 | ```console 71 | $ helm install --name my-release -f values.yaml ./ 72 | ``` 73 | 74 | ## Upgrade chart 75 | ```console 76 | $ helm upgrade --name my-release --set image.tag=28 ./ 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /docker-app-chart/Jenkinsfile: -------------------------------------------------------------------------------- 1 | node { 2 | 3 | stage('Clone repository') { 4 | /* Let's make sure we have the repository cloned to our workspace */ 5 | git url: 'https://github.com/jfrogtraining/kubernetes_example.git', branch: 'master' 6 | } 7 | 8 | stage('Install helm & JFrog CLI') { 9 | /* This installs helm client */ 10 | sh "curl -O https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz" 11 | sh "tar -xvf helm-v2.9.1-linux-amd64.tar.gz" 12 | sh "chmod 777 ./linux-amd64/helm" 13 | sh "./linux-amd64/helm version -c" 14 | /* This installs and configure JFrog Cli */ 15 | sh "curl -fL https://getcli.jfrog.io | sh" 16 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 17 | sh "./jfrog rt config --url ${SERVER_URL} --user ${env.USERNAME} --password ${env.PASSWORD}" 18 | } 19 | } 20 | 21 | stage('Build Chart & push it to Artifactory repo') { 22 | /* Configure helm client to point to k8s cluster */ 23 | sh "./linux-amd64/helm init" 24 | sh "sed -i 's/0.1.1/0.1.${env.BUILD_NUMBER}/' docker-app-chart/Chart.yaml" 25 | sh "sed -i 's/latest/${IMAGE_TAG}/g' docker-app-chart/values.yaml" 26 | sh "./linux-amd64/helm package ./docker-app-chart/" 27 | sh "./jfrog rt u '*.tgz' ${REPO} --build-name=${env.JOB_NAME} --build-number=${env.BUILD_NUMBER}" 28 | sh "./jfrog rt bce ${env.JOB_NAME} ${env.BUILD_NUMBER}" 29 | sh "./jfrog rt dl docker-prod-local/docker-app/${IMAGE_TAG}/manifest.json --build-name=${env.JOB_NAME} --build-number=${env.BUILD_NUMBER} " 30 | sh "./jfrog rt bp ${env.JOB_NAME} ${env.BUILD_NUMBER}" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docker-app-chart/README.md: -------------------------------------------------------------------------------- 1 | ## Create Helm chart of product Docker image 2 | * Create helm chart of [`docker-app`](Chart_README.md) 3 | * Push helm chart in local helm repository in Artifactory 4 | 5 | 1. On the Jenkins front page, click on Credentials -> System -> Global credentials -> Add Credentials 6 | Add your Artifactory credentials as the type Username with password, with the ID artifactory-credentials 7 | ![Add_Artifactory_Credentials](../images/Add_Credentials.png) 8 | 9 | 2. Create new Jenkins Pipeline Job. 10 | 11 | 3. Add String Parameters: 12 | * IMAGE_TAG (String Parameter) : Domain of Artifactory docker registry 13 | e.g `IMAGE_TAG : latest` 14 | * SERVER_URL (String Parameter) : Artifactory Server URL
15 | e.g. `SERVER_URL -> http://35.225.27.231/artifactory` 16 | * REPO (String Parameter) : Artifactory Helm repo
17 | e.g. `REPO -> helm` 18 | * CREDENTIALS (Credentials Parameter) : Artifactory Credential
19 | e.g. `CREDENTIALS -> artifactory-credentials` 20 | 21 | 22 | 4. Copy [Jenkinsfile](Jenkinsfile) to Pipeline Script. 23 | 24 | 5. To build it, press Build Now. 25 | 26 | 6. Check your newly published build in build browser of Artifactory. 27 | -------------------------------------------------------------------------------- /docker-app-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Get docker-app URL 2 | {{- if contains "NodePort" .Values.service.type }} 3 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "docker-app.fullname" . }}) 4 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 5 | echo http://$NODE_IP:$NODE_PORT/ 6 | 7 | {{- else if contains "LoadBalancer" .Values.service.type }} 8 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 9 | You can watch the status of by running 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "docker-app.fullname" . }}' 10 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "docker-app.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") 11 | echo http://$SERVICE_IP:{{ .Values.service.port }} 12 | 13 | {{- else if contains "ClusterIP" .Values.service.type }} 14 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "component={{ template "docker-app.fullname" . }}-master" -o jsonpath="{.items[0].metadata.name}") 15 | echo http://127.0.0.1:{{ .Values.service.port }} 16 | kubectl port-forward $POD_NAME {{ .Values.service.port }}:{{ .Values.service.port }} 17 | 18 | {{- end }} -------------------------------------------------------------------------------- /docker-app-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "docker-app.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "docker-app.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | 18 | {{- define "imagePullSecret" }} 19 | {{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }} 20 | {{- end }} -------------------------------------------------------------------------------- /docker-app-chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "docker-app.fullname" . }} 5 | labels: 6 | heritage: {{ .Release.Service }} 7 | release: {{ .Release.Name }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | app: {{ template "docker-app.name" . }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | strategy: 13 | rollingUpdate: 14 | maxSurge: 0 15 | maxUnavailable: 1 16 | type: RollingUpdate 17 | template: 18 | metadata: 19 | labels: 20 | app: {{ template "docker-app.name" . }} 21 | release: {{ .Release.Name }} 22 | spec: 23 | containers: 24 | - name: {{ template "docker-app.name" . }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | livenessProbe: 28 | failureThreshold: 3 29 | httpGet: 30 | path: / 31 | port: 8181 32 | scheme: HTTP 33 | initialDelaySeconds: 30 34 | periodSeconds: 10 35 | successThreshold: 1 36 | timeoutSeconds: 30 37 | ports: 38 | - name: http 39 | containerPort: 8181 40 | protocol: TCP 41 | imagePullSecrets: 42 | {{- if .Values.image.secretName }} 43 | - name: {{ .Values.image.secretName }} 44 | {{- else }} 45 | - name: {{ template "docker-app.fullname" . }}-regsecret 46 | {{- end -}} -------------------------------------------------------------------------------- /docker-app-chart/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if (not .Values.image.secretName) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ template "docker-app.fullname" . }}-regsecret 6 | labels: 7 | heritage: {{ .Release.Service }} 8 | release: {{ .Release.Name }} 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | app: {{ template "docker-app.name" . }} 11 | type: kubernetes.io/dockerconfigjson 12 | data: 13 | .dockerconfigjson: {{ template "imagePullSecret" . }} 14 | {{- end -}} -------------------------------------------------------------------------------- /docker-app-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if .Values.service.annotations }} 5 | annotations: 6 | {{ toYaml .Values.service.annotations | indent 4 }} 7 | {{- end }} 8 | labels: 9 | app: {{ template "docker-app.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 11 | heritage: {{ .Release.Service }} 12 | release: {{ .Release.Name }} 13 | name: {{ template "docker-app.fullname" . }} 14 | spec: 15 | # Provides options for the service so chart users have the full choice 16 | type: "{{ .Values.service.type }}" 17 | clusterIP: "{{ .Values.service.clusterIP }}" 18 | {{- if .Values.service.externalIPs }} 19 | externalIPs: 20 | {{ toYaml .Values.service.externalIPs | indent 4 }} 21 | {{- end }} 22 | {{- if .Values.service.loadBalancerIP }} 23 | loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" 24 | {{- end }} 25 | {{- if .Values.service.loadBalancerSourceRanges }} 26 | loadBalancerSourceRanges: 27 | {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} 28 | {{- end }} 29 | ports: 30 | - name: http 31 | port: {{ .Values.service.port }} 32 | protocol: TCP 33 | targetPort: http 34 | {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} 35 | nodePort: {{ .Values.service.nodePort }} 36 | {{- end }} 37 | selector: 38 | app: {{ template "docker-app.name" . }} 39 | release: {{ .Release.Name }} -------------------------------------------------------------------------------- /docker-app-chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for docker-app. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | 5 | replicaCount: 1 6 | restartPolicy: Never 7 | 8 | image: 9 | repository: docker.artifactory/docker-app 10 | tag: latest 11 | secretName: regsecret 12 | pullPolicy: Always 13 | 14 | #Uncomment if you want to generate docker credentials using helm 15 | #imageCredentials: 16 | # registry: docker.artifactory 17 | # username: admin 18 | # password: password 19 | 20 | service: 21 | annotations: {} 22 | clusterIP: "" 23 | externalIPs: [] 24 | loadBalancerIP: "" 25 | loadBalancerSourceRanges: [] 26 | type: LoadBalancer 27 | port: 8181 28 | nodePort: "" 29 | 30 | resources: {} 31 | 32 | nodeSelector: {} -------------------------------------------------------------------------------- /docker-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.artifactory/docker-framework:latest 2 | 3 | MAINTAINER Jainish Shah jainishs@jfrog.com 4 | 5 | RUN rm -rf /home/exec/apache-tomcat-8.0.32/webapps/* 6 | 7 | ADD war/*.war /home/exec/apache-tomcat-8.0.32/webapps/ROOT.war 8 | 9 | CMD /bin/bash -c cd /home/exec; /home/exec/apache-tomcat-8.0.32/bin/catalina.sh run 10 | -------------------------------------------------------------------------------- /docker-app/Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | node { 4 | 5 | // Cleanup workspace 6 | deleteDir() 7 | 8 | //Clone example project from GitHub repository 9 | git url: 'https://github.com/jfrogtraining/kubernetes_example.git', branch: 'master' 10 | def rtServer = Artifactory.server SERVER_ID 11 | def rtDocker = Artifactory.docker server: rtServer 12 | def buildInfo = Artifactory.newBuildInfo() 13 | def tagDockerApp 14 | 15 | buildInfo.env.capture = true 16 | 17 | //Fetch all depedencies from Artifactory 18 | stage ('Dependencies') { 19 | dir ('docker-app') { 20 | try { 21 | println "Gather Released Docker Framework and Gradle War file" 22 | def gradleWarDownload = """{ 23 | "files": [ 24 | { 25 | "pattern": "gradle-release-local/org/jfrog/example/gradle/webservice/1.1.2/*.war", 26 | "target": "war/webservice.war", 27 | "props": "unit-test=pass", 28 | "flat": "true" 29 | } 30 | ] 31 | }""" 32 | rtServer.download(gradleWarDownload, buildInfo ) 33 | } catch (Exception e) { 34 | println "Caught Exception during resolution. Message ${e.message}" 35 | throw e 36 | } 37 | } 38 | } 39 | //Build docker image named docker-app 40 | stage ('Build & Deploy') { 41 | dir ('docker-app') { 42 | sh "sed -i 's/docker.artifactory/${ARTDOCKER_REGISTRY}/' Dockerfile" 43 | tagDockerApp = "${ARTDOCKER_REGISTRY}/docker-app:${env.BUILD_NUMBER}" 44 | println "Docker App Build" 45 | docker.build(tagDockerApp) 46 | println "Docker push" + tagDockerApp + " : " + REPO 47 | buildInfo = rtDocker.push(tagDockerApp, REPO, buildInfo) 48 | println "Docker Buildinfo" 49 | rtServer.publishBuildInfo buildInfo 50 | } 51 | } 52 | 53 | stage ("Retag latest image") { 54 | dir('docker-app') { 55 | reTagLatest (SOURCE_REPO) 56 | } 57 | } 58 | 59 | //Test docker image 60 | stage ('Test') { 61 | dir('docker-app/app-test') { 62 | tagDockerApp = "${ARTDOCKER_REGISTRY}/docker-app:${env.BUILD_NUMBER}" 63 | if (testApp(tagDockerApp)) { 64 | println "Setting property and promotion" 65 | sh 'docker rmi '+tagDockerApp+' || true' 66 | } else { 67 | currentBuild.result = 'UNSTABLE' 68 | return 69 | } 70 | } 71 | } 72 | 73 | //Scan Build Artifacts in Xray 74 | stage('Xray Scan') { 75 | if (XRAY_SCAN == "YES") { 76 | def xrayConfig = [ 77 | 'buildName' : env.JOB_NAME, 78 | 'buildNumber' : env.BUILD_NUMBER, 79 | 'failBuild' : false 80 | ] 81 | def xrayResults = rtServer.xrayScan xrayConfig 82 | echo xrayResults as String 83 | } else { 84 | println "No Xray scan performed. To enable set XRAY_SCAN = YES" 85 | } 86 | sleep 60 87 | } 88 | 89 | //Promote docker image from staging local repo to production repo in Artifactory 90 | /* stage ('Promote') { 91 | dir('docker-app/app-test') { 92 | def promotionConfig = [ 93 | 'buildName' : env.JOB_NAME, 94 | 'buildNumber' : env.BUILD_NUMBER, 95 | 'targetRepo' : PROMOTE_REPO, 96 | 'comment' : 'App works with latest released version of gradle swampup app, tomcat and jdk', 97 | 'sourceRepo' : SOURCE_REPO, 98 | 'status' : 'Released', 99 | 'includeDependencies': false, 100 | 'copy' : true 101 | ] 102 | rtServer.promote promotionConfig 103 | reTagLatest (SOURCE_REPO) 104 | reTagLatest (PROMOTE_REPO) 105 | } 106 | 107 | // promote war file from gradle-dev-local to gradle-release-local 108 | 109 | }*/ 110 | 111 | 112 | 113 | } 114 | 115 | def testApp (tag) { 116 | docker.image(tag).withRun('-p 9191:8181') {c -> 117 | sleep 10 118 | //def stdout = sh(script: 'curl "http://localhost:9191/swampup/"', returnStdout: true) 119 | //if (stdout.contains("Welcome Docker Lifecycle Training")) { 120 | // println "*** Passed Test: " + stdout 121 | println "*** Passed Test" 122 | return true 123 | // } else { 124 | // println "*** Failed Test: " + stdout 125 | // return false 126 | // } 127 | } 128 | } 129 | 130 | //Tag docker image 131 | def reTagLatest (targetRepo) { 132 | def BUILD_NUMBER = env.BUILD_NUMBER 133 | sh 'sed -E "s/@/$BUILD_NUMBER/" retag.json > retag_out.json' 134 | switch (targetRepo) { 135 | case PROMOTE_REPO : 136 | sh 'sed -E "s/TARGETREPO/${PROMOTE_REPO}/" retag_out.json > retaga_out.json' 137 | break 138 | case SOURCE_REPO : 139 | sh 'sed -E "s/TARGETREPO/${SOURCE_REPO}/" retag_out.json > retaga_out.json' 140 | break 141 | } 142 | sh 'cat retaga_out.json' 143 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 144 | def curlString = "curl -u " + env.USERNAME + ":" + env.PASSWORD + " " + SERVER_URL 145 | def regTagStr = curlString + "/api/docker/$targetRepo/v2/promote -X POST -H 'Content-Type: application/json' -T retaga_out.json" 146 | println "Curl String is " + regTagStr 147 | sh regTagStr 148 | } 149 | } 150 | 151 | def updateProperty (property) { 152 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 153 | def curlString = "curl -u " + env.USERNAME + ":" + env.PASSWORD + " " + "-X PUT " + SERVER_URL 154 | def updatePropStr = curlString + "/api/storage/${SOURCE_REPO}/docker-app/${env.BUILD_NUMBER}?properties=${property}" 155 | println "Curl String is " + updatePropStr 156 | sh updatePropStr 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /docker-app/README.md: -------------------------------------------------------------------------------- 1 | ## Create a product Docker image 2 | * Downloads, from Artifactory, the ‘webservice-1.1.2.war’ file and the ‘docker-framework’ Docker 3 | image, that were created in the previous two pipelines 4 | * Creates a ‘docker-app’ production Docker image 5 | * Pushes it to Artifactory 6 | * Scans it with Xray 7 | * Promotes it to a production repository in Artifactory 8 | 9 | ### Step to create Jenkins Pipeline: 10 | Note: List of required Jenkins plugins 11 | * [Artifactory Plugin](https://wiki.jenkins.io/display/JENKINS/Artifactory+Plugin) 12 | * [Docker Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Docker+Pipeline+Plugin) 13 | * [GitHub plugin](https://plugins.jenkins.io/git) 14 | * [Pipeline Github Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Github+Plugin) 15 | * [Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Plugin) 16 | 17 | 1. On the Jenkins front page, click on Credentials -> System -> Global credentials -> Add Credentials 18 | Add your Artifactory credentials as the type Username with password, with the ID artifactory-credentials 19 | ![Add_Artifactory_Credentials](../images/Add_Credentials.png) 20 | 21 | 2. Create Following Docker repositories in Artifactory. 22 | `docker-stage-local` - Local docker repo. 23 | `docker-prod-local` - Local docker repo. 24 | `docker-remote` - Remote docker repo pointing to Docker hub `https://registry-1.docker.io/`. 25 | `bintray-docker-remote` - Remote docker repo pointing to Bintray: `https://docker.bintray.io`. 26 | `docker` - Virtual docker repo aggregating all above created repo with `docker-stage-local` as default repo for deployment. 27 | 28 | 3. Create Generic local repository with name `tomcat-local` and deploy [Java](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) and [Tomcat](https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.32/bin/apache-tomcat-8.0.32.tar.gz) binaries in it. 29 | 30 | 4. Create new Jenkins Pipeline Job. 31 | 32 | 5. Add String Parameters: 33 | * ARTDOCKER_REGISTRY (String Parameter) : Domain of Artifactory docker registry 34 | e.g `ARTDOCKER_REGISTRY : docker.artifactory` 35 | * REPO (String Parameter) -> Artifactory virtual docker registry
36 | e.g. `REPO -> docker` 37 | * PROMOTE_REPO (String Parameter) : Artifactory production docker registry
38 | e.g. `PROMOTE_REPO -> docker-prod-local` 39 | * SOURCE_REPO (String Parameter) : Artifactory staging docker registry
40 | e.g. `SOURCE_REPO -> docker-stage-local` 41 | * SERVER_ID (String Parameter) : Artifactory Server Id
42 | e.g. `SERVER_ID -> artifactory` 43 | * XRAY_SCAN (Choice Parameter) : Xray Scan. Applicable only if you are using JFrog Xray
44 | e.g. `XRAY_SCAN -> YES` 45 | * SERVER_URL (String Parameter) : Artifactory Server URL
46 | e.g. `SERVER_URL -> http://35.225.27.231/artifactory` 47 | * CREDENTIALS (Credentials Parameter) : Artifactory Credential
48 | e.g. `CREDENTIALS -> artifactory-credentials` 49 | 50 | 6. Copy [Jenkinsfile](Jenkinsfile) to Pipeline Script. 51 | 52 | 7. To build it, press Build Now. 53 | 54 | 8. Check your newly published build in build browser of Artifactory. 55 | -------------------------------------------------------------------------------- /docker-app/app-test/promote-gradleWar.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "Released", 3 | "comment" : "App Image has passed test.", 4 | "ciUser": "jfrog", 5 | "dryRun" : false, 6 | "targetRepo" : "gradle-release-local", 7 | "sourceRepo" : "gradle-dev-local", 8 | "includeDependencies" : false, 9 | "copy" : false, 10 | "failFast": false 11 | } -------------------------------------------------------------------------------- /docker-app/app-test/retag.json: -------------------------------------------------------------------------------- 1 | { 2 | "targetRepo" : "docker-prod-local", 3 | "dockerRepository" : "docker-app", 4 | "tag" : "@", 5 | "targetTag" : "latest", 6 | "copy": true 7 | } 8 | -------------------------------------------------------------------------------- /docker-app/appmodules-download.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "pattern": "gradle-release-local/org/jfrog/example/gradle/webservice/*/*.war", 5 | "target": "war/webservice.war", 6 | "props": "unit-test=pass", 7 | "flat": "true", 8 | "build": "gradle-release/LATEST" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /docker-app/retag.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "targetRepo" : "TARGETREPO", 4 | "dockerRepository" : "docker-app", 5 | "tag" : "@", 6 | "targetTag" : "latest", 7 | "copy": true 8 | } -------------------------------------------------------------------------------- /docker-framework/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.artifactory/ubuntu:14.04 2 | 3 | MAINTAINER Jainish Shah jainishs@jfrog.com 4 | 5 | RUN mkdir -p /home/exec/jdk8 /home/exec/tomcat 6 | 7 | COPY jdk/jdk-8-linux-x64.tar.gz /home/exec/ 8 | RUN cd /home/exec/ && tar -xvf /home/exec/jdk-8-linux-x64.tar.gz 9 | ENV JAVA_HOME=/home/exec/jdk1.8.0_91 10 | #RUN sed "/securerandom.source=/{s/file:\/dev\/random/file:\/dev\/urandom/}" /home/exec/jdk8/jre/lib/security/java.security -i 11 | 12 | COPY tomcat/apache-tomcat-8.tar.gz /home/exec/tomcat 13 | RUN cd /home/exec/ && tar -xvf /home/exec/tomcat/apache-tomcat-8.tar.gz 14 | ADD tomcat/server.xml /home/exec/apache-tomcat-8.0.32/conf/server.xml 15 | ENV CATALINA_HOME=/home/exec/apache-tomcat-8.0.32 16 | ENV TEST_ENV=2 17 | 18 | CMD /bin/bash -c cd /home/exec; /home/exec/apache-tomcat-8.0.32/bin/catalina.sh run -------------------------------------------------------------------------------- /docker-framework/Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | node { 4 | //Clone example project from GitHub repository 5 | git url: 'https://github.com/jfrogtraining/kubernetes_example.git', branch : 'master' 6 | def rtServer = Artifactory.server SERVER_ID 7 | def rtDocker = Artifactory.docker server: rtServer 8 | def buildInfo = Artifactory.newBuildInfo() 9 | def tagName 10 | buildInfo.env.capture = true 11 | //Fetch all depensencies from Artifactory 12 | stage('Dependencies') { 13 | dir('docker-framework') { 14 | try { 15 | println "Gather Java and Tomcat" 16 | 17 | def downloadSpec = """{ 18 | "files": [ 19 | { 20 | "pattern": "tomcat-local/java/jdk-8u91-linux-x64.tar.gz", 21 | "target": "jdk/jdk-8-linux-x64.tar.gz", 22 | "flat":"true" 23 | }, 24 | { 25 | "pattern": "tomcat-local/org/apache/apache-tomcat/apache-tomcat-8.0.32.tar.gz", 26 | "target": "tomcat/apache-tomcat-8.tar.gz", 27 | "flat":"true" 28 | } 29 | ] 30 | }""" 31 | 32 | rtServer.download (downloadSpec, buildInfo) 33 | if (fileExists('jdk/jdk-8-linux-x64.tar.gz') && fileExists('tomcat/apache-tomcat-8.tar.gz')) { 34 | println "Downloaded dependencies" 35 | } else { 36 | println "Missing Dependencies either jdk or tomcat - see listing below:" 37 | sh 'ls -d */*' 38 | throw new FileNotFoundException("Missing Dependencies") 39 | } 40 | } catch (Exception e) { 41 | println "Caught exception during resolution. Message ${e.message}" 42 | throw e 43 | } 44 | } 45 | } 46 | //Build docker image named "docker-framework" with Java 8 and Tomcat 47 | stage('Build') { 48 | dir ('docker-framework') { 49 | sh "sed -i 's/docker.artifactory/${ARTDOCKER_REGISTRY}/' Dockerfile" 50 | tagName = "${ARTDOCKER_REGISTRY}/docker-framework:${env.BUILD_NUMBER}" 51 | println "Docker Framework Build" 52 | docker.build(tagName) 53 | println "Docker pushing -->" + tagName + " To " + REPO 54 | buildInfo = rtDocker.push(tagName, REPO, buildInfo) 55 | println "Docker Buildinfo" 56 | rtServer.publishBuildInfo buildInfo 57 | 58 | } 59 | } 60 | //Test docker image 61 | stage('Test') { 62 | dir('docker-framework/framework-test') { 63 | 64 | def gradleWarDownload = """{ 65 | "files": [ 66 | { 67 | "pattern": "gradle-release-local/org/jfrog/example/gradle/webservice/1.1.2/*.war", 68 | "target": "war/webservice.war", 69 | "props": "unit-test=pass", 70 | "flat": "true" 71 | } 72 | ] 73 | }""" 74 | 75 | rtServer.download(gradleWarDownload) 76 | updateDockerFile() 77 | def tagDockerFramework = "${ARTDOCKER_REGISTRY}/docker-framework-test:${env.BUILD_NUMBER}" 78 | docker.build(tagDockerFramework) 79 | if (testFramework(tagDockerFramework)) { 80 | println "Setting property and promotion" 81 | updateProperty ("functional-test=pass") 82 | sh "docker rmi ${tagName}" 83 | } else { 84 | updateProperty ("functional-test=fail; failed-test=page-not-loaded") 85 | currentBuild.result = 'UNSTABLE' 86 | sh "docker rmi ${tagName}" 87 | return 88 | } 89 | } 90 | } 91 | //Scan build's Artifacts in Xray 92 | stage('Xray Scan') { 93 | if (XRAY_SCAN == "YES") { 94 | def xrayConfig = [ 95 | 'buildName' : env.JOB_NAME, 96 | 'buildNumber' : env.BUILD_NUMBER, 97 | 'failBuild' : false 98 | ] 99 | def xrayResults = rtServer.xrayScan xrayConfig 100 | echo xrayResults as String 101 | } else { 102 | println "No Xray scan performed. To enable set XRAY_SCAN = YES" 103 | } 104 | sleep 60 105 | } 106 | 107 | //Promote image from local staging repositoy to production repository 108 | stage ('Promote') { 109 | dir ('docker-framework') { 110 | def promotionConfig = [ 111 | 'buildName' : env.JOB_NAME, 112 | 'buildNumber' : env.BUILD_NUMBER, 113 | 'targetRepo' : PROMOTE_REPO, 114 | 'comment' : 'Framework test with latest version of application', 115 | 'sourceRepo' : SOURCE_REPO, 116 | 'status' : 'Released', 117 | 'includeDependencies': false, 118 | 'copy' : true 119 | ] 120 | rtServer.promote promotionConfig 121 | reTagLatest (SOURCE_REPO) 122 | reTagLatest (PROMOTE_REPO) 123 | } 124 | } 125 | } 126 | 127 | def updateDockerFile () { 128 | def BUILD_NUMBER = env.BUILD_NUMBER 129 | sh "sed -i 's/docker.artifactory/${ARTDOCKER_REGISTRY}/' Dockerfile" 130 | sh 'sed -i "s/docker-framework:latest/docker-framework:$BUILD_NUMBER/" Dockerfile' 131 | } 132 | 133 | def reTagLatest (targetRepo) { 134 | def BUILD_NUMBER = env.BUILD_NUMBER 135 | sh 'sed -E "s/@/$BUILD_NUMBER/" retag.json > retag_out.json' 136 | switch (targetRepo) { 137 | case PROMOTE_REPO : 138 | sh 'sed -E "s/TARGETREPO/${PROMOTE_REPO}/" retag_out.json > retaga_out.json' 139 | break 140 | case SOURCE_REPO : 141 | sh 'sed -E "s/TARGETREPO/${SOURCE_REPO}/" retag_out.json > retaga_out.json' 142 | break 143 | } 144 | sh 'cat retaga_out.json' 145 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 146 | def curlString = "curl -u " + env.USERNAME + ":" + env.PASSWORD + " " + SERVER_URL 147 | def regTagStr = curlString + "/api/docker/${SOURCE_REPO}/v2/promote -X POST -H 'Content-Type: application/json' -T retaga_out.json" 148 | println "Curl String is " + regTagStr 149 | sh regTagStr 150 | } 151 | } 152 | 153 | //test docker image by runnning container 154 | def testFramework (tag) { 155 | def result = true 156 | docker.image(tag).withRun('-p 8181:8181') {c -> 157 | sleep 10 158 | //def stdout = sh(script: 'curl "http://localhost:8181/swampup/"', returnStdout: true) 159 | //if (stdout.contains("Welcome Docker Lifecycle Training")) { 160 | // println "*** Passed Test: " + stdout 161 | //} else { 162 | // println "*** Failed Test: " + stdout 163 | // result = false 164 | //} 165 | } 166 | sh "docker rmi ${tag}" 167 | return true 168 | } 169 | 170 | def updateProperty (property) { 171 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: CREDENTIALS, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { 172 | def curlString = "curl -u " + env.USERNAME + ":" + env.PASSWORD + " " + "-X PUT " + SERVER_URL 173 | def updatePropStr = curlString + "/api/storage/${SOURCE_REPO}/docker-framework/${env.BUILD_NUMBER}?properties=${property}" 174 | println "Curl String is " + updatePropStr 175 | sh updatePropStr 176 | } 177 | } -------------------------------------------------------------------------------- /docker-framework/README.md: -------------------------------------------------------------------------------- 1 | ## Create a template Docker image 2 | • Creates a base Docker image called ‘docker-framework’ using Ubuntu + Java + Tomcat 3 | • Pushes it to a local repository in Artifactory 4 | 5 | ### Step to create Jenkins Pipeline: 6 | Note: List of required Jenkins plugins 7 | * [Artifactory Plugin](https://wiki.jenkins.io/display/JENKINS/Artifactory+Plugin) 8 | * [Docker Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Docker+Pipeline+Plugin) 9 | * [GitHub plugin](https://plugins.jenkins.io/git) 10 | * [Pipeline Github Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Github+Plugin) 11 | * [Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Plugin) 12 | 13 | 1. On the Jenkins front page, click on Credentials -> System -> Global credentials -> Add Credentials 14 | Add your Artifactory credentials as the type Username with password, with the ID artifactory-credentials 15 | ![Add_Artifactory_Credentials](../images/Add_Credentials.png) 16 | 17 | 2. Create Following Docker repositories in Artifactory. 18 | `docker-stage-local` - Local docker repo. 19 | `docker-prod-local` - Local docker repo. 20 | `docker-remote` - Remote docker repo pointing to Docker hub `https://registry-1.docker.io/`. 21 | `bintray-docker-remote` - Remote docker repo pointing to Bintray: `https://docker.bintray.io`. 22 | `docker` - Virtual docker repo aggregating all above created repo with `docker-stage-local` as default repo for deployment. 23 | 24 | 3. Create Generic local repository with name `tomcat-local` and deploy [Java](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) and [Tomcat](https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.32/bin/apache-tomcat-8.0.32.tar.gz) binaries in it. 25 | 26 | 4. Create new Jenkins Pipeline Job. 27 | 28 | 5. Add String Parameters: 29 | * ARTDOCKER_REGISTRY (String Parameter) : Domain of Artifactory docker registry 30 | e.g `ARTDOCKER_REGISTRY : docker.artifactory` 31 | * REPO (String Parameter) -> Artifactory virtual docker registry
32 | e.g. `REPO -> docker` 33 | * PROMOTE_REPO (String Parameter) : Artifactory production docker registry
34 | e.g. `PROMOTE_REPO -> docker-prod-local` 35 | * SOURCE_REPO (String Parameter) : Artifactory staging docker registry
36 | e.g. `SOURCE_REPO -> docker-stage-local` 37 | * SERVER_ID (String Parameter) : Artifactory Server Id
38 | e.g. `SERVER_ID -> artifactory` 39 | * XRAY_SCAN (Choice Parameter) : Xray Scan. Applicable only if you are using JFrog Xray
40 | e.g. `XRAY_SCAN -> YES` 41 | * SERVER_URL (String Parameter) : Artifactory Server URL
42 | e.g. `SERVER_URL -> http://35.225.27.231/artifactory` 43 | * CREDENTIALS (Credentials Parameter) : Artifactory Credential
44 | e.g. `CREDENTIALS -> artifactory-credentials` 45 | 46 | 6. Copy [Jenkinsfile](Jenkinsfile) to Pipeline Script. 47 | 48 | 7. To build it, press Build Now. 49 | 50 | 8. Check your newly published build in build browser of Artifactory. 51 | -------------------------------------------------------------------------------- /docker-framework/framework-download.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "aql": { 5 | "items.find": { 6 | "repo": "tomcat-local", 7 | "$and": [ 8 | { 9 | "path": {"$match": "java"}, 10 | "name": {"$match": "jdk-8u91-linux-x64.tar.gz"}, 11 | "property.key" : {"$match" : "*.alert.topSeverity"}, 12 | "property.value" : {"$ne" : "Critical"} 13 | } 14 | ] 15 | } 16 | }, 17 | "target": "jdk/jdk-8-linux-x64.tar.gz", 18 | "flat": "true" 19 | }, 20 | { 21 | "aql": { 22 | "items.find": { 23 | "repo": "tomcat-local", 24 | "$and": [ 25 | { 26 | "path": {"$match": "org/apache/apache-tomcat"}, 27 | "name": {"$match": "apache-tomcat-8.0.32.tar.gz"} 28 | } 29 | ] 30 | } 31 | }, 32 | "target": "tomcat/apache-tomcat-8.tar.gz", 33 | "flat": "true" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /docker-framework/framework-test/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.artifactory/docker-framework:latest 2 | 3 | MAINTAINER Jainish Shah jainishs@jfrog.com 4 | 5 | RUN rm -rf /home/exec/apache-tomcat-8.0.32/webapps/* 6 | 7 | ADD war/*.war /home/exec/apache-tomcat-8.0.32/webapps/ROOT.war 8 | CMD /bin/bash -c cd /home/exec; /home/exec/apache-tomcat-8.0.32/bin/catalina.sh run 9 | -------------------------------------------------------------------------------- /docker-framework/gradeWar-download.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "pattern": "gradle-release-local/org/jfrog/example/gradle/webservice/*/*.war", 5 | "target": "war/webservice.war", 6 | "props": "unit-test=pass", 7 | "flat": "true", 8 | "build": "gradle-release/LATEST" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /docker-framework/retag.json: -------------------------------------------------------------------------------- 1 | { 2 | "targetRepo" : "TARGETREPO", 3 | "dockerRepository" : "docker-framework", 4 | "tag" : "@", 5 | "targetTag" : "latest", 6 | "copy": true 7 | } -------------------------------------------------------------------------------- /docker-framework/tomcat/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gradle-example/Jenkinsfile: -------------------------------------------------------------------------------- 1 | node { 2 | def server = Artifactory.server SERVER_ID 3 | def rtGradle = Artifactory.newGradleBuild() 4 | 5 | //Clone example code from GitHub repository 6 | stage 'Build' 7 | git url: 'https://github.com/jfrogtraining/kubernetes_example.git', branch: 'master' 8 | 9 | //Configure Artifactroy repository to pull/push artifacts 10 | stage 'Artifactory configuration' 11 | rtGradle.tool = GRADLE_TOOL // Tool name from Jenkins configuration 12 | rtGradle.deployer repo:DEPLOY_REPO, server: server 13 | rtGradle.resolver repo:'libs-release', server: server 14 | rtGradle.deployer.addProperty("unit-test", "pass").addProperty("qa-team", "platform", "ui") 15 | def buildInfo = Artifactory.newBuildInfo() 16 | buildInfo.env.capture = true 17 | 18 | //Run gradle build 19 | stage 'Exec Gradle' 20 | if(CLEAN_REPO == "YES") { 21 | sh 'rm -rf ~/.gradle/caches' 22 | } 23 | rtGradle.run rootDir: "gradle-example/", buildFile: 'build.gradle', tasks: 'clean artifactoryPublish', buildInfo: buildInfo 24 | 25 | //Publish artifacts to Artifactory along with build information and scan build artifacts in Xray 26 | stage 'Publish Build Information & Scan Artifacts' 27 | server.publishBuildInfo buildInfo 28 | if (XRAY_SCAN == "YES") { 29 | def scanConfig = [ 30 | 'buildName' : env.JOB_NAME, 31 | 'buildNumber' : env.BUILD_NUMBER, 32 | 'failBuild' : false 33 | ] 34 | def scanResult = server.xrayScan scanConfig 35 | echo scanResult as String 36 | } 37 | } -------------------------------------------------------------------------------- /gradle-example/README.md: -------------------------------------------------------------------------------- 1 | ## Create an application war file 2 | 3 | • Creates a sample application called ‘webservice-1.1.2.war’ 4 | • Pushes it to a local repository in Artifactory 5 | 6 | ### Step to create Jenkins Pipeline: 7 | Note: List of required Jenkins plugins 8 | * [Artifactory Plugin](https://wiki.jenkins.io/display/JENKINS/Artifactory+Plugin) 9 | * [Docker Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Docker+Pipeline+Plugin) 10 | * [GitHub plugin](https://plugins.jenkins.io/git) 11 | * [Pipeline Github Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Github+Plugin) 12 | * [Pipeline Plugin](https://wiki.jenkins.io/display/JENKINS/Pipeline+Plugin) 13 | * [Gradle Plugin](https://wiki.jenkins.io/display/JENKINS/Gradle+Plugin) 14 | 15 | 1. Configure Artifactory server in Jenkins Manage Jenkins -> Configure System -> Artifactory -> Add Artifactory Server. 16 | ![Add_Artifactory_Server](../images/Add_Artifactory_Server.png) 17 | 18 | 2. Create Gradle repositories in Artifactory using [quick setup wizard](https://www.jfrog.com/confluence/display/RTF/Getting+Started#GettingStarted-OnboardingWizard). 19 | 20 | 3. Create new Jenkins Pipeline Job. 21 | 22 | 4. Add String Parameters: 23 | * GRADLE_TOOL (String Parameter) : Provide name of configured Gradle installation 24 | e.g `GRADLE_TOOL : gradle-3.5.1` 25 | * DEPLOY_REPO (String Parameter) -> Artifactory Gradle Repository name
26 | e.g. `DEPLOY_REPO -> gradle-release` 27 | * SERVER_ID (String Parameter) : Artifactory Server Id
28 | e.g. `SERVER_ID -> artifactory` 29 | * XRAY_SCAN (Choice Parameter) : Xray Scan. Applicable only if you are using JFrog Xray
30 | e.g. `XRAY_SCAN -> NO` 31 | * CLEAN_REPO (Choice Parameter) : Clean gradle cache before building project
32 | e.g. `CLEAN_REPO -> YES` 33 | 34 | 5. Copy [Jenkinsfile](Jenkinsfile) to Pipeline Script. 35 | 36 | 6. To build it, press Build Now. 37 | 38 | 7. Check your newly published build in build browser of Artifactory. 39 | -------------------------------------------------------------------------------- /gradle-example/api/build.gradle: -------------------------------------------------------------------------------- 1 | configurations { 2 | spi 3 | } 4 | 5 | dependencies { 6 | compile project(':shared') 7 | compile module("commons-lang:commons-lang:2.4") { 8 | dependency("commons-io:commons-io:1.2") 9 | } 10 | compile group: 'org.apache.wicket', name: 'wicket', version: '1.3.7' 11 | compile group: 'commons-httpclient', name: 'commons-httpclient', version: '3.0' 12 | 13 | } 14 | 15 | // Just a smoke test that using this option does not lead to any exception 16 | compileJava.options.compilerArgs = ['-Xlint:unchecked'] 17 | -------------------------------------------------------------------------------- /gradle-example/api/src/main/java/org/gradle/api/PersonList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.gradle.api; 18 | 19 | import org.gradle.apiImpl.Impl; 20 | import org.gradle.shared.Person; 21 | 22 | import java.util.ArrayList; 23 | 24 | 25 | public class PersonList { 26 | private ArrayList persons = new ArrayList(); 27 | 28 | public void doSomethingWithImpl() { 29 | org.apache.commons.lang.builder.ToStringBuilder stringBuilder; 30 | try { 31 | Class.forName("org.apache.commons.io.FileUtils"); 32 | } catch (ClassNotFoundException e) { 33 | throw new RuntimeException(e); 34 | } 35 | new Impl().implMethod(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /gradle-example/api/src/main/java/org/gradle/api/package.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |

These are the API classes

19 | 20 | -------------------------------------------------------------------------------- /gradle-example/api/src/main/java/org/gradle/apiImpl/Impl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.gradle.apiImpl; 18 | 19 | 20 | public class Impl { 21 | 22 | public void implMethod() { 23 | double a = 4.0 * 4; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /gradle-example/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | jcenter() 20 | } 21 | } 22 | 23 | allprojects { 24 | apply plugin: 'java' 25 | apply plugin: 'maven' 26 | 27 | group = 'org.jfrog.example.gradle' 28 | version = currentVersion 29 | status = 'release' 30 | } 31 | 32 | // Setting this property to true will make the artifactoryPublish task 33 | // skip this module (in our case, the root module): 34 | artifactoryPublish.skip = true 35 | 36 | task wrapper(type: Wrapper) { 37 | gradleVersion = '2.4' 38 | } -------------------------------------------------------------------------------- /gradle-example/gradle.properties: -------------------------------------------------------------------------------- 1 | currentVersion=1.1.2 2 | artifactory_password=password 3 | artifactory_user=admin 4 | -------------------------------------------------------------------------------- /gradle-example/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/gradle-example/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle-example/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 20 09:52:53 IDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip 7 | -------------------------------------------------------------------------------- /gradle-example/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradle-example/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /gradle-example/increment.sh: -------------------------------------------------------------------------------- 1 | if sed --version 2 | then sed -r 's/(currentVersion)=([0-9]+).([0-9]+).([0-9]+)/echo "\1=\2.\3.$BUILD_NUMBER"/e' gradle.properties -i 3 | else gsed -r 's/(currentVersion)=([0-9]+).([0-9]+).([0-9]+)/echo "\1=\2.\3.$BUILD_NUMBER"/e' gradle.properties -i 4 | fi 5 | -------------------------------------------------------------------------------- /gradle-example/services/webservice/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'war' 2 | 3 | dependencies { 4 | compile project(':shared'), 'commons-collections:commons-collections:3.2@jar', 'commons-io:commons-io:1.2', 'commons-lang:commons-lang:2.4@jar' 5 | compile group: 'org.apache.wicket', name: 'wicket', version: '1.3.7' 6 | compile group: 'org.apache.struts', name: 'struts2-core', version: '2.3.14' 7 | compile group: 'junit', name: 'junit', version: '4.11' 8 | compile project(':api') 9 | } 10 | -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/main/java/org/gradle/webservice/TestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.gradle.webservice; 18 | 19 | import org.apache.commons.collections.list.GrowthList; 20 | import org.apache.commons.io.FilenameUtils; 21 | import org.apache.commons.lang.builder.ToStringBuilder; 22 | import org.gradle.api.PersonList; 23 | import org.gradle.shared.Person; 24 | 25 | public class TestTest { 26 | private String name; 27 | 28 | public void method() { 29 | FilenameUtils.separatorsToUnix("my/unix/filename"); 30 | ToStringBuilder.reflectionToString(new Person("name")); 31 | new GrowthList(); 32 | new PersonList().doSomethingWithImpl(); // compile with api-spi, runtime with api 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/main/webapp/images/k8s-reg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/gradle-example/services/webservice/src/main/webapp/images/k8s-reg.jpg -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/main/webapp/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/gradle-example/services/webservice/src/main/webapp/images/logo.png -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/main/webapp/images/ready_weekend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/gradle-example/services/webservice/src/main/webapp/images/ready_weekend.png -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kubernetes Registry 4 | 5 | 47 | 48 | 49 | 50 | 51 |

IT WORKED!

52 | 53 | 54 |
55 | 56 |
57 | 58 |

Enjoy Swampup 2019!

59 | 60 | 61 | -------------------------------------------------------------------------------- /gradle-example/services/webservice/src/test/java/org/gradle/webservice/TestTestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gradle.webservice; 17 | 18 | import junit.framework.TestCase; 19 | 20 | /** 21 | * @author Hans Dockter 22 | */ 23 | public class TestTestTest extends TestCase { 24 | public void testClasspath() { 25 | new TestTest().method(); 26 | } 27 | 28 | public void testApiCompileClasspath() { 29 | new org.gradle.api.PersonList(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gradle-example/settings.gradle: -------------------------------------------------------------------------------- 1 | include "shared", "api", "services:webservice" 2 | -------------------------------------------------------------------------------- /gradle-example/shared/src/main/java/org/gradle/shared/Person.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.gradle.shared; 18 | 19 | import java.io.IOException; 20 | import java.util.Properties; 21 | 22 | public class Person { 23 | private String name; 24 | 25 | public Person(String name) { 26 | this.name = name; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public String readProperty() throws IOException { 38 | Properties properties = new Properties(); 39 | properties.load(getClass().getClassLoader().getResourceAsStream("org/gradle/shared/main.properties")); 40 | return properties.getProperty("main"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gradle-example/shared/src/main/java/org/gradle/shared/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 JFrog Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * These are the shared classes. 19 | */ 20 | package org.gradle.shared; 21 | -------------------------------------------------------------------------------- /gradle-example/shared/src/main/resources/org/gradle/shared/main.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2011 JFrog Ltd. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | main=mainValue 18 | -------------------------------------------------------------------------------- /images/Add_Artifactory_Server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/images/Add_Artifactory_Server.png -------------------------------------------------------------------------------- /images/Add_Credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/images/Add_Credentials.png -------------------------------------------------------------------------------- /images/configure_docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfrogtraining/kubernetes_example/23a99bd1df278706e3d7fc5dd638cf8d752b2b50/images/configure_docker.png --------------------------------------------------------------------------------