From ab24e2c8fd599ab085ba0c65f1dfdc631e2803dd Mon Sep 17 00:00:00 2001 From: Jakub Al-Khalili Date: Wed, 27 Nov 2019 10:53:45 +0100 Subject: [PATCH] Add 0.3.x docs, add instruction how to run e2e tests on crc --- .../content/en/docs/Developer Guide/tools.md | 57 - .../en/docs/Getting Started/future/_index.md | 18 + .../en/docs/Getting Started/future/aks.md | 24 + .../Getting Started/future/configuration.md | 325 +++ .../future/configure-backup-and-restore.md | 86 + .../future/custom-backup-and-restore.md | 184 ++ .../Getting Started/future/customization.md | 186 ++ .../Getting Started/future/deploy-jenkins.md | 89 + .../Getting Started/future/developer-guide.md | 224 ++ .../Getting Started/future/diagnostics.md | 42 + .../en/docs/Getting Started/future/schema.md | 1979 +++++++++++++++++ .../latest/developer-guide.md} | 47 + .../Getting Started/v0.1.x/developer-guide.md | 198 ++ 13 files changed, 3402 insertions(+), 57 deletions(-) delete mode 100644 website/content/en/docs/Developer Guide/tools.md create mode 100644 website/content/en/docs/Getting Started/future/_index.md create mode 100644 website/content/en/docs/Getting Started/future/aks.md create mode 100644 website/content/en/docs/Getting Started/future/configuration.md create mode 100644 website/content/en/docs/Getting Started/future/configure-backup-and-restore.md create mode 100644 website/content/en/docs/Getting Started/future/custom-backup-and-restore.md create mode 100644 website/content/en/docs/Getting Started/future/customization.md create mode 100644 website/content/en/docs/Getting Started/future/deploy-jenkins.md create mode 100644 website/content/en/docs/Getting Started/future/developer-guide.md create mode 100644 website/content/en/docs/Getting Started/future/diagnostics.md create mode 100644 website/content/en/docs/Getting Started/future/schema.md rename website/content/en/docs/{Developer Guide/_index.md => Getting Started/latest/developer-guide.md} (82%) create mode 100644 website/content/en/docs/Getting Started/v0.1.x/developer-guide.md diff --git a/website/content/en/docs/Developer Guide/tools.md b/website/content/en/docs/Developer Guide/tools.md deleted file mode 100644 index 95285d80..00000000 --- a/website/content/en/docs/Developer Guide/tools.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: "Tools" -linkTitle: "Tools" -weight: 30 -date: 2019-08-05 -description: > - Required tools for building and running Jenkins Operator ---- - -{{% pageinfo %}} -This document explains how to install the Go tools used by the development process. -{{% /pageinfo %}} - -## Configure environment variables - -```bash -export GOPATH=/home/go # example value -export GOROOT=/usr/lib/go-1.12 # example value -export PATH=$GOPATH/bin:$PATH -``` - -## goimports - -``` -go get golang.org/x/tools/cmd/goimports -cd $GOPATH/src/golang.org/x/tools/cmd/goimports -go build -go install -``` - -## golint - -``` -go get -u golang.org/x/lint/golint -cd $GOPATH/src/golang.org/x/lint/golint -go build -go install -``` - -## checkmake -``` -go get github.com/mrtazz/checkmake -cd $GOPATH/src/github.com/mrtazz/checkmake -go build -go install -``` - -## staticcheck - -``` -mkdir -p $GOPATH/src/github.com/dominikh/ -cd $GOPATH/src/github.com/dominikh/ -git clone https://github.com/dominikh/go-tools.git -cd $GOPATH/src/github.com/dominikh/go-tools/staticcheck -go build -go install -``` diff --git a/website/content/en/docs/Getting Started/future/_index.md b/website/content/en/docs/Getting Started/future/_index.md new file mode 100644 index 00000000..4cddd338 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/_index.md @@ -0,0 +1,18 @@ +--- +title: "Future (v0.3.x)" +linkTitle: "Future (v0.3.x)" +weight: 10 +date: 2019-08-05 +description: > + How to work with jenkins-operator latest version +--- + +{{% pageinfo %}} +This document describes a getting started guide for **Jenkins Operator** `v0.3.x` and an additional configuration. +{{% /pageinfo %}} + +## First Steps + +Prepare your Kubernetes cluster and set up your `kubectl` access. + +Once you have running Kubernetes cluster you can focus on installing **Jenkins Operator** according to the [Installation](/docs/installation/) guide. diff --git a/website/content/en/docs/Getting Started/future/aks.md b/website/content/en/docs/Getting Started/future/aks.md new file mode 100644 index 00000000..7eab9a40 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/aks.md @@ -0,0 +1,24 @@ +--- +title: "AKS" +linkTitle: "AKS" +weight: 10 +date: 2019-08-05 +description: > + Additional configuration for Azure Kubernetes Service +--- + +Azure AKS managed Kubernetes service adds to every pod the following environment variables: + +```yaml +- name: KUBERNETES_PORT_443_TCP_ADDR + value: +- name: KUBERNETES_PORT + value: tcp:// +- name: KUBERNETES_PORT_443_TCP + value: tcp:// +- name: KUBERNETES_SERVICE_HOST + value: +``` + +The operator is aware of it and omits these environment variables when checking if a Jenkins pod environment has been changed. It prevents the +restart of a Jenkins pod over and over again. \ No newline at end of file diff --git a/website/content/en/docs/Getting Started/future/configuration.md b/website/content/en/docs/Getting Started/future/configuration.md new file mode 100644 index 00000000..ef8086b1 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/configuration.md @@ -0,0 +1,325 @@ +--- +title: "Configuration" +linkTitle: "Configuration" +weight: 2 +date: 2019-08-05 +description: > + How to configure Jenkins with Operator +--- + +## Configure Seed Jobs and Pipelines + +Jenkins operator uses [job-dsl][job-dsl] and [kubernetes-credentials-provider][kubernetes-credentials-provider] plugins for configuring jobs +and deploy keys. + +## Prepare job definitions and pipelines + +First you have to prepare pipelines and job definition in your GitHub repository using the following structure: + +``` +cicd/ +├── jobs +│   └── build.jenkins +└── pipelines + └── build.jenkins +``` + +**`cicd/jobs/build.jenkins`** is a job definition: + +``` +#!/usr/bin/env groovy + +pipelineJob('build-jenkins-operator') { + displayName('Build jenkins-operator') + + definition { + cpsScm { + scm { + git { + remote { + url('https://github.com/jenkinsci/kubernetes-operator.git') + credentials('jenkins-operator') + } + branches('*/master') + } + } + scriptPath('cicd/pipelines/build.jenkins') + } + } +} +``` + +**`cicd/pipelines/build.jenkins`** is an actual Jenkins pipeline: + +``` +#!/usr/bin/env groovy + +def label = "build-jenkins-operator-${UUID.randomUUID().toString()}" +def home = "/home/jenkins" +def workspace = "${home}/workspace/build-jenkins-operator" +def workdir = "${workspace}/src/github.com/jenkinsci/kubernetes-operator/" + +podTemplate(label: label, + containers: [ + containerTemplate(name: 'jnlp', image: 'jenkins/jnlp-slave:alpine'), + containerTemplate(name: 'go', image: 'golang:1-alpine', command: 'cat', ttyEnabled: true), + ], + envVars: [ + envVar(key: 'GOPATH', value: workspace), + ], + ) { + + node(label) { + dir(workdir) { + stage('Init') { + timeout(time: 3, unit: 'MINUTES') { + checkout scm + } + container('go') { + sh 'apk --no-cache --update add make git gcc libc-dev' + } + } + + stage('Dep') { + container('go') { + sh 'make dep' + } + } + + stage('Test') { + container('go') { + sh 'make test' + } + } + + stage('Build') { + container('go') { + sh 'make build' + } + } + } + } +} +``` + +## Configure Seed Jobs + +Jenkins Seed Jobs are configured using `Jenkins.spec.seedJobs` section from your custom resource manifest: + +``` +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + seedJobs: + - id: jenkins-operator + targets: "cicd/jobs/*.jenkins" + description: "Jenkins Operator repository" + repositoryBranch: master + repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git +``` + +**Jenkins Operator** will automatically discover and configure all the seed jobs. + +You can verify if deploy keys were successfully configured in the Jenkins **Credentials** tab. + +![jenkins](/kubernetes-operator/img/jenkins-credentials.png) + +You can verify if your pipelines were successfully configured in the Jenkins Seed Job console output. + +![jenkins](/kubernetes-operator/img/jenkins-seed.png) + +If your GitHub repository is **private** you have to configure SSH or username/password authentication. + +### SSH authentication + +#### Generate SSH Keys + +There are two methods of SSH private key generation: + +```bash +$ openssl genrsa -out 2048 +``` + +or + +```bash +$ ssh-keygen -t rsa -b 2048 +$ ssh-keygen -p -f -m pem +``` + +Then copy content from generated file. + +#### Public key + +If you want to upload your public key to your Git server you need to extract it. + +If key was generated by `openssl` then you need to type this to extract public key: + +```bash +$ openssl rsa -in -pubout > .pub +``` + +If key was generated by `ssh-keygen` the public key content is located in .pub and there is no need to extract public key + +#### Configure SSH authentication + +Configure a seed job like this: + +``` +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + seedJobs: + - id: jenkins-operator-ssh + credentialType: basicSSHUserPrivateKey + credentialID: k8s-ssh + targets: "cicd/jobs/*.jenkins" + description: "Jenkins Operator repository" + repositoryBranch: master + repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git +``` + +and create a Kubernetes Secret (name of secret should be the same from `credentialID` field): + +``` +apiVersion: v1 +kind: Secret +metadata: + name: k8s-ssh +stringData: + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + MIIJKAIBAAKCAgEAxxDpleJjMCN5nusfW/AtBAZhx8UVVlhhhIKXvQ+dFODQIdzO + oDXybs1zVHWOj31zqbbJnsfsVZ9Uf3p9k6xpJ3WFY9b85WasqTDN1xmSd6swD4N8 + ... + username: github_user_name +``` + +### Username & password authentication + +Configure the seed job like: + +``` +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + seedJobs: + - id: jenkins-operator-user-pass + credentialType: usernamePassword + credentialID: k8s-user-pass + targets: "cicd/jobs/*.jenkins" + description: "Jenkins Operator repository" + repositoryBranch: master + repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git +``` + +and create a Kubernetes Secret (name of secret should be the same from `credentialID` field): + +``` +apiVersion: v1 +kind: Secret +metadata: + name: k8s-user-pass +stringData: + username: github_user_name + password: password_or_token +``` + +## HTTP Proxy for downloading plugins + +To use forwarding proxy with an operator to download plugins you need to add the following environment variable to Jenkins Custom Resource (CR), e.g.: + +```yaml +spec: + master: + containers: + - name: jenkins-master + env: + - name: CURL_OPTIONS + value: -L -x +``` + +In `CURL_OPTIONS` var you can set additional arguments to `curl` command. + +## Pulling Docker images from private repositories + +To pull a Docker Image from private repository you can use `imagePullSecrets`. + +Please follow the instructions on [creating a secret with a docker config](https://kubernetes.io/docs/concepts/containers/images/?origin_team=T42NTAGHM#creating-a-secret-with-a-docker-config). + +### Docker Hub Configuration +To use Docker Hub additional steps are required. + +Edit the previously created secret: +```bash +kubectl -n edit secret +``` + +The `.dockerconfigjson` key's value needs to be replaced with a modified version. + +After modifications, it needs to be encoded as a Base64 value before setting the `.dockerconfigjson` key. + +Example config file to modify and use: +``` +{ + "auths":{ + "https://index.docker.io/v1/":{ + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "auth.docker.io":{ + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "registry.docker.io":{ + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "docker.io":{ + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "https://registry-1.docker.io/v2/": { + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "registry-1.docker.io/v2/": { + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "registry-1.docker.io": { + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + }, + "https://registry-1.docker.io": { + "username":"user", + "password":"password", + "email":"yourdockeremail@gmail.com", + "auth":"base64 of string user:password" + } + } +} +``` + +[job-dsl]:https://github.com/jenkinsci/job-dsl-plugin +[kubernetes-credentials-provider]:https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ diff --git a/website/content/en/docs/Getting Started/future/configure-backup-and-restore.md b/website/content/en/docs/Getting Started/future/configure-backup-and-restore.md new file mode 100644 index 00000000..c8987e0e --- /dev/null +++ b/website/content/en/docs/Getting Started/future/configure-backup-and-restore.md @@ -0,0 +1,86 @@ +--- +title: "Configure backup and restore" +linkTitle: "Configure backup and restore" +weight: 10 +date: 2019-08-05 +description: > + Prevent loss of job history +--- + +Backup and restore is done by a container sidecar. + +### PVC + +#### Create PVC + +Save to the file named pvc.yaml: +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: + namespace: +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 500Gi +``` + +Run the following command: +```bash +$ kubectl -n create -f pvc.yaml +``` + +#### Configure Jenkins CR + +```yaml +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: + namespace: +spec: + master: + securityContext: + runAsUser: 1000 + fsGroup: 1000 + containers: + - name: jenkins-master + image: jenkins/jenkins:lts + - name: backup # container responsible for the backup and restore + env: + - name: BACKUP_DIR + value: /backup + - name: JENKINS_HOME + value: /jenkins-home + - name: BACKUP_COUNT + value: "3" # keep only the 2 most recent backups + image: virtuslab/jenkins-operator-backup-pvc:v0.0.7 # look at backup/pvc directory + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /jenkins-home # Jenkins home volume + name: jenkins-home + - mountPath: /backup # backup volume + name: backup + volumes: + - name: backup # PVC volume where backups will be stored + persistentVolumeClaim: + claimName: + backup: + containerName: backup # container name is responsible for backup + action: + exec: + command: + - /home/user/bin/backup.sh # this command is invoked on "backup" container to make backup, for example /home/user/bin/backup.sh , is passed by operator + interval: 30 # how often make backup in seconds + makeBackupBeforePodDeletion: true # make a backup before pod deletion + restore: + containerName: backup # container name is responsible for restore backup + action: + exec: + command: + - /home/user/bin/restore.sh # this command is invoked on "backup" container to make restore backup, for example /home/user/bin/restore.sh , is passed by operator + #recoveryOnce: # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restored +``` diff --git a/website/content/en/docs/Getting Started/future/custom-backup-and-restore.md b/website/content/en/docs/Getting Started/future/custom-backup-and-restore.md new file mode 100644 index 00000000..cc927599 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/custom-backup-and-restore.md @@ -0,0 +1,184 @@ +--- +title: "Custom Backup and Restore Providers" +linkTitle: "Custom Backup and Restore Providers" +weight: 10 +date: 2019-08-05 +description: > + Custom backup and restore provider +--- + +With enough effort one can create a custom backup and restore provider +for the Jenkins Operator. + +## Requirements + +Two commands (e.g. scripts) are required: + +- a backup command, e.g. `backup.sh` that takes one argument, a **backup number** +- a restore command, e.g. `backup.sh` that takes one argument, a **backup number** + +Both scripts need to return an exit code of `0` on success and `1` or greater for failure. + +One of those scripts (or the entry point of the container) needs to be responsible +for backup cleanup or rotation if required, or an external system. + +## How it works + +The mechanism relies on basic Kubernetes and UNIX functionalities. + +The backup (and restore) container runs as a sidecar in the same +Kubernetes pod as the Jenkins master. + +Name of the backup and restore containers can be set as necessary using +`spec.backup.containerName` and `spec.restore.containerName`. +In most cases it will be the same container, but we allow for less common use cases. + +The operator will call a backup or restore commands inside a sidecar container when necessary: + +- backup command (defined in `spec.backup.action.exec.command`) + will be called every `N` seconds configurable in: `spec.backup.interval` + and on pod shutdown (if enabled in `spec.backup.makeBackupBeforePodDeletion`) + with an integer representing the current backup number as first and only argument +- restore command (defined in `spec.restore.action.exec.command`) + will be called at Jenkins startup + with an integer representing the backup number to restore as first and only argument + (can be overridden using `spec.restore.recoveryOnce`) + +## Example AWS S3 backup using the CLI + +This example shows abbreviated version of a simple AWS S3 backup implementation +using: `aws-cli`, `bash` and `kube2iam`. + +In addition to your normal `Jenkins` `CustomResource` some additional settings +for backup and restore are required, e.g.: + +```yaml +kind: Jenkins +apiVersion: jenkins.io/v1alpha1 +metadata: + name: example + namespace: jenkins +spec: + master: + masterAnnotations: + iam.amazonaws.com/role: "my-example-backup-role" # tell kube2iam where the AWS IAM role is + containers: + - name: jenkins-master + ... + - name: backup # container responsible for backup and restore + image: quay.io/virtuslab/aws-cli:1.16.263-2 + workingDir: /home/user/bin/ + command: # our container entry point + - sleep + - infinity + env: + - name: BACKUP_BUCKET + value: my-example-bucket # the S3 bucket name to use + - name: BACKUP_PATH + value: my-backup-path # the S3 bucket path prefix to use + - name: JENKINS_HOME + value: /jenkins-home # the path to mount jenkins home dir in the backup container + volumeMounts: + - mountPath: /jenkins-home # Jenkins home volume + name: jenkins-home + - mountPath: /home/user/bin/backup.sh + name: backup-scripts + subPath: backup.sh + readOnly: true + - mountPath: /home/user/bin/restore.sh + name: backup-scripts + subPath: restore.sh + readOnly: true + volumes: + - name: backup-scripts + configMap: + defaultMode: 0754 + name: jenkins-operator-backup-s3 + securityContext: # make sure both containers use the same UID and GUID + runAsUser: 1000 + fsGroup: 1000 + ... + backup: + containerName: backup # container name responsible for backup + interval: 3600 # how often make a backup in seconds + makeBackupBeforePodDeletion: true # trigger backup just before deleting the pod + action: + exec: + command: + # this command is invoked on "backup" container to create a backup, + # is passed by operator, + # for example /home/user/bin/backup.sh + - /home/user/bin/backup.sh + restore: + containerName: backup # container name is responsible for restore backup + action: + exec: + command: + # this command is invoked on "backup" container to restore a backup, + # is passed by operator + # for example /home/user/bin/restore.sh + - /home/user/bin/restore.sh +# recoveryOnce: # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restored +``` + +The actual backup and restore scripts will be provided in a `ConfigMap`: + +```yaml +kind: ConfigMap +apiVersion: v1 +metadata: + name: jenkins-operator-backup-s3 + namespace: jenkins + labels: + app: jenkins-operator +data: + backup.sh: |- + #!/bin/bash -xeu + [[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1; + [[ -z "${BACKUP_BUCKET}" ]] && echo "Required 'BACKUP_BUCKET' env not set" && exit 1; + [[ -z "${BACKUP_PATH}" ]] && echo "Required 'BACKUP_PATH' env not set" && exit 1; + [[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1; + + backup_number=$1 + echo "Running backup #${backup_number}" + + BACKUP_TMP_DIR=$(mktemp -d) + tar -C ${JENKINS_HOME} -czf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" --exclude jobs/*/workspace* -c jobs && \ + + aws s3 cp ${BACKUP_TMP_DIR}/${backup_number}.tar.gz s3://${BACKUP_BUCKET}/${BACKUP_PATH}/${backup_number}.tar.gz + echo Done + + restore.sh: |- + #!/bin/bash -xeu + [[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1 + [[ -z "${BACKUP_BUCKET}" ]] && echo "Required 'BACKUP_BUCKET' env not set" && exit 1; + [[ -z "${BACKUP_PATH}" ]] && echo "Required 'BACKUP_PATH' env not set" && exit 1; + [[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1; + + backup_number=$1 + echo "Running restore #${backup_number}" + + BACKUP_TMP_DIR=$(mktemp -d) + aws s3 cp s3://${BACKUP_BUCKET}/${BACKUP_PATH}/${backup_number}.tar.gz ${BACKUP_TMP_DIR}/${backup_number}.tar.gz + + tar -C ${JENKINS_HOME} -zxf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" + echo Done +``` + +In our example we will use S3 bucket lifecycle policy to keep +the number of backups under control, e.g. Cloud Formation fragment: +```yaml + Type: AWS::S3::Bucket + Properties: + BucketName: my-example-bucket + ... + LifecycleConfiguration: + Rules: + - Id: BackupCleanup + Status: Enabled + Prefix: my-backup-path + ExpirationInDays: 7 + NoncurrentVersionExpirationInDays: 14 + AbortIncompleteMultipartUpload: + DaysAfterInitiation: 3 +``` diff --git a/website/content/en/docs/Getting Started/future/customization.md b/website/content/en/docs/Getting Started/future/customization.md new file mode 100644 index 00000000..7d953c71 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/customization.md @@ -0,0 +1,186 @@ +--- +title: "Customization" +linkTitle: "Customization" +weight: 3 +date: 2019-08-05 +description: > + How to customize Jenkins +--- + +Jenkins can be customized using groovy scripts or the [configuration as code plugin](https://github.com/jenkinsci/configuration-as-code-plugin). +By using a [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) you can create your own **Jenkins** customized configuration. +Then you must reference the **`ConfigMap`** in the **Jenkins** pod customization file in `spec.groovyScripts` or `spec.configurationAsCode` + +For example create a **`ConfigMap`** with name `jenkins-operator-user-configuration`. Then, modify the **Jenkins** manifest to look like this: + +```yaml +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + configurationAsCode: + configurations: + - name: jenkins-operator-user-configuration + groovyScripts: + configurations: + - name: jenkins-operator-user-configuration +``` + +Here is an example of `jenkins-operator-user-configuration`: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: jenkins-operator-user-configuration +data: + 1-configure-theme.groovy: | + import jenkins.* + import jenkins.model.* + import hudson.* + import hudson.model.* + import org.jenkinsci.plugins.simpletheme.ThemeElement + import org.jenkinsci.plugins.simpletheme.CssTextThemeElement + import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement + + Jenkins jenkins = Jenkins.getInstance() + + def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class) + + List configElements = new ArrayList<>(); + configElements.add(new CssTextThemeElement("DEFAULT")); + configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-light-green.css")); + decorator.setElements(configElements); + decorator.save(); + + jenkins.save() + 1-system-message.yaml: | + jenkins: + systemMessage: "Configuration as Code integration works!!!" +``` + +* `*.groovy` is Groovy script configuration +* `*.yaml is` configuration as code + +If you want to correct your configuration you can edit it while the **Jenkins Operator** is running. +Jenkins will reconcile and apply the new configuration. + +### Using secrets from a Groovy script + +If you configured `spec.groovyScripts.secret.name`, then this secret is available to use from map Groovy scripts. +The secrets are loaded to `secrets` map. + +Create a [secret](https://kubernetes.io/docs/concepts/configuration/secret/) with for example the name `jenkins-conf-secrets`. + +```yaml +kind: Secret +apiVersion: v1 +type: Opaque +metadata: + name: jenkins-conf-secrets + namespace: default +data: + SYSTEM_MESSAGE: SGVsbG8gd29ybGQ= +``` + +Then modify the **Jenkins** pod manifest by changing `spec.groovyScripts.secret.name` to `jenkins-conf-secrets`. + +```yaml +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + configurationAsCode: + configurations: + - name: jenkins-operator-user-configuration + secret: + name: jenkins-conf-secrets + groovyScripts: + configurations: + - name: jenkins-operator-user-configuration + secret: + name: jenkins-conf-secrets +``` + +Now you can test that the secret is mounted by applying this `ConfigMap` for Groovy script: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: jenkins-operator-user-configuration +data: + 1-system-message.groovy: | + import jenkins.* + import jenkins.model.* + import hudson.* + import hudson.model.* + Jenkins jenkins = Jenkins.getInstance() + + jenkins.setSystemMessage(secrets["SYSTEM_MESSAGE"]) + jenkins.save() +``` + +Or by applying this configuration as code: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: jenkins-operator-user-configuration +data: + 1-system-message.yaml: | + jenkins: + systemMessage: ${SYSTEM_MESSAGE} +``` + + +After this, you should see the `Hello world` system message from the **Jenkins** homepage. + +## Install Plugins + +Edit Custom Resource under `spec.master.plugins`: + +``` +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + master: + plugins: + - name: simple-theme-plugin + version: 0.5.1 +``` + +Under `spec.master.basePlugins` you can find plugins for a valid **Jenkins Operator**: + +```yaml +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + master: + basePlugins: + - name: kubernetes + version: 1.18.3 + - name: workflow-job + version: "2.34" + - name: workflow-aggregator + version: "2.6" + - name: git + version: 3.12.0 + - name: job-dsl + version: "1.76" + - name: configuration-as-code + version: "1.29" + - name: configuration-as-code-support + version: "1.19" + - name: kubernetes-credentials-provider + version: 0.12.1 +``` + +You can change their versions. + +The **Jenkins Operator** will then automatically install plugins after the Jenkins master pod restarts. diff --git a/website/content/en/docs/Getting Started/future/deploy-jenkins.md b/website/content/en/docs/Getting Started/future/deploy-jenkins.md new file mode 100644 index 00000000..4f7b5a96 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/deploy-jenkins.md @@ -0,0 +1,89 @@ +--- +title: "Deploy Jenkins" +linkTitle: "Deploy Jenkins" +weight: 1 +date: 2019-08-05 +description: > + Deploy production ready Jenkins Operator manifest +--- + +Once Jenkins Operator is up and running let's deploy actual Jenkins instance. +Create manifest e.g. **`jenkins_instance.yaml`** with following data and save it on drive. + +```bash +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: example +spec: + master: + containers: + - name: jenkins-master + image: jenkins/jenkins:lts + imagePullPolicy: Always + livenessProbe: + failureThreshold: 12 + httpGet: + path: /login + port: http + scheme: HTTP + initialDelaySeconds: 80 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /login + port: http + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 1500m + memory: 3Gi + requests: + cpu: "1" + memory: 500Mi + seedJobs: + - id: jenkins-operator + targets: "cicd/jobs/*.jenkins" + description: "Jenkins Operator repository" + repositoryBranch: master + repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git +``` + +Deploy a Jenkins to Kubernetes: + +```bash +kubectl create -f jenkins_instance.yaml +``` +Watch the Jenkins instance being created: + +```bash +kubectl get pods -w +``` + +Get the Jenkins credentials: + +```bash +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.user}' | base64 -d +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.password}' | base64 -d +``` + +Connect to the Jenkins instance (minikube): + +```bash +minikube service jenkins-operator-http- --url +``` + +Connect to the Jenkins instance (actual Kubernetes cluster): + +```bash +kubectl port-forward jenkins- 8080:8080 +``` +Then open browser with address `http://localhost:8080`. +![jenkins](/img/jenkins.png) diff --git a/website/content/en/docs/Getting Started/future/developer-guide.md b/website/content/en/docs/Getting Started/future/developer-guide.md new file mode 100644 index 00000000..93435098 --- /dev/null +++ b/website/content/en/docs/Getting Started/future/developer-guide.md @@ -0,0 +1,224 @@ +--- +title: "Developer Guide" +linkTitle: "Developer Guide" +weight: 60 +date: 2019-08-05 +description: > + Jenkins Operator for developers +--- + +{{% pageinfo %}} +This document explains how to setup your development environment. +{{% /pageinfo %}} + +## Prerequisites + +- [operator_sdk][operator_sdk] version v0.8.1 +- [git][git_tool] +- [go][go_tool] version v1.12+ +- [goimports, golint, checkmake and staticcheck][install_dev_tools] +- [minikube][minikube] version v1.1.0+ (preferred Hypervisor - [virtualbox][virtualbox]) +- [docker][docker_tool] version 17.03+ + +## Clone repository and download dependencies + +```bash +mkdir -p $GOPATH/src/github.com/jenkinsci +cd $GOPATH/src/github.com/jenkinsci/ +git clone git@github.com:jenkinsci/kubernetes-operator.git +cd kubernetes-operator +make go-dependencies +``` + +## Build and run with a minikube + +Build and run **Jenkins Operator** locally: + +```bash +make build minikube-run EXTRA_ARGS='--jenkins-api-hostname=$(eval minikube ip) --jenkins-api-use-nodeport=true' +``` + +Once minikube and **Jenkins Operator** are up and running, apply Jenkins custom resource: + +```bash +kubectl apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml +kubectl get jenkins -o yaml +kubectl get po +``` + +## Build and run with a remote Kubernetes cluster + +You can also run the controller locally and make it listen to a remote Kubernetes server. + +```bash +make run NAMESPACE=default KUBECTL_CONTEXT=remote-k8s EXTRA_ARGS='--kubeconfig ~/.kube/config' +``` + +Once minikube and **Jenkins Operator** are up and running, apply Jenkins custom resource: + +```bash +kubectl --context remote-k8s --namespace default apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml +kubectl --context remote-k8s --namespace default get jenkins -o yaml +kubectl --context remote-k8s --namespace default get po +``` + +## Testing + +Run unit tests: + +```bash +make test +``` + +### Running E2E tests on Linux + +Run e2e tests with minikube: + +```bash +make minikube-start +eval $(minikube docker-env) +make build e2e config=config.minikube.env CR=podman +``` + +`config.minikube.env` is the E2E test profile which provides all connection info to operator to run on minikube. + +Run the specific e2e test: + +```bash +make build e2e E2E_TEST_SELECTOR='^TestConfiguration$' config=config.minikube.env CR=podman +``` + +If you want to run E2E tests on CRC (Code Ready Containers by OpenShift), you should use `config.crc.env` profile instead of `config.minikube.env`. + +### Running E2E tests on macOS + +At first, you need to start minikube: +```bash +$ make minikube-start +$ eval $(minikube docker-env) +``` + +Build a Docker image inside the provided Linux container by: +```bash +$ make indocker +``` + +Build **Jenkins Operator** inside a container using: + + +```bash +$ make build +``` + +Then exit the container and run: +``` +make e2e CONFIG=config.minikube.env +``` + +or with CRC: +``` +make e2e CONFIG=config.crc.env +``` + +### Use Docker image instead of podman (Code Ready Containers) + +If you have trouble to build image with `podman`, you can set additional flag `USE_ORGANIZATION` to pull image from organization. + +At first, edit you `config.base.env` and change `DOCKER_ORGANIZATION` to your account/organization name from [hub](https://hub.docker.com/). +Next, you need to pull image to your repository: + +```bash +$ make cr-build cr-snapshot-push +``` + +When image will be uploaded to repository, you can now write this command to run E2E tests: + +```bash +$ make e2e E2E_TEST_SELECTOR='^TestConfiguration$' config=config.crc.env USE_ORGANIZATION=true +``` + +## Tips & Tricks + +### Building docker image on minikube (for e2e tests) + +To be able to work with the docker daemon on `minikube` machine run the following command before building an image: + +```bash +eval $(minikube docker-env) +``` + +### When `pkg/apis/jenkinsio/*/jenkins_types.go` has changed + +Run: + +```bash +make deepcopy-gen +``` + +### Getting the Jenkins URL and basic credentials + +```bash +minikube service jenkins-operator-http- --url +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.user}' | base64 -d +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.password}' | base64 -d +``` + +# Tools + +## Configure environment variables + +```bash +export GOPATH=/home/go # example value +export GOROOT=/usr/lib/go-1.12 # example value +export PATH=$GOPATH/bin:$PATH +``` + +## goimports + +``` +go get golang.org/x/tools/cmd/goimports +cd $GOPATH/src/golang.org/x/tools/cmd/goimports +go build +go install +``` + +## golint + +``` +go get -u golang.org/x/lint/golint +cd $GOPATH/src/golang.org/x/lint/golint +go build +go install +``` + +## checkmake +``` +go get github.com/mrtazz/checkmake +cd $GOPATH/src/github.com/mrtazz/checkmake +go build +go install +``` + +## staticcheck + +``` +mkdir -p $GOPATH/src/github.com/dominikh/ +cd $GOPATH/src/github.com/dominikh/ +git clone https://github.com/dominikh/go-tools.git +cd $GOPATH/src/github.com/dominikh/go-tools/staticcheck +go build +go install +``` + + +[dep_tool]:https://golang.github.io/dep/docs/installation.html +[git_tool]:https://git-scm.com/downloads +[go_tool]:https://golang.org/dl/ +[operator_sdk]:https://github.com/operator-framework/operator-sdk +[fork_guide]:https://help.github.com/articles/fork-a-repo/ +[docker_tool]:https://docs.docker.com/install/ +[kubectl_tool]:https://kubernetes.io/docs/tasks/tools/install-kubectl/ +[minikube]:https://kubernetes.io/docs/tasks/tools/install-minikube/ +[virtualbox]:https://www.virtualbox.org/wiki/Downloads +[jenkins-operator]:../README.md +[install_dev_tools]:install_dev_tools.md diff --git a/website/content/en/docs/Getting Started/future/diagnostics.md b/website/content/en/docs/Getting Started/future/diagnostics.md new file mode 100644 index 00000000..87286adb --- /dev/null +++ b/website/content/en/docs/Getting Started/future/diagnostics.md @@ -0,0 +1,42 @@ +--- +title: "Diagnostics" +linkTitle: "Diagnostics" +weight: 40 +date: 2019-08-05 +description: > + How to deal with Jenkins Operator problems +--- + + +Turn on debug in **Jenkins Operator** deployment: + +```bash +sed -i 's|\(args:\).*|\1\ ["--debug"\]|' deploy/operator.yaml +kubectl apply -f deploy/operator.yaml +``` + +Watch Kubernetes events: + +```bash +kubectl get events --sort-by='{.lastTimestamp}' +``` + +Verify Jenkins master logs: + +```bash +kubectl logs -f jenkins- +``` + +Verify the `jenkins-operator` logs: + +```bash +kubectl logs deployment/jenkins-operator +``` + +## Troubleshooting + +Delete the Jenkins master pod and wait for the new one to come up: + +```bash +kubectl delete pod jenkins- +``` diff --git a/website/content/en/docs/Getting Started/future/schema.md b/website/content/en/docs/Getting Started/future/schema.md new file mode 100644 index 00000000..008414be --- /dev/null +++ b/website/content/en/docs/Getting Started/future/schema.md @@ -0,0 +1,1979 @@ +--- +title: "Schema" +linkTitle: "Schema" +weight: 40 +date: 2019-08-05 +description: > + API Schema definitions for Jenkins CRD +--- + +{{% pageinfo %}} +This document contains API scheme for `jenkins-operator` Custom Resource Definition manifest +{{% /pageinfo %}} + +

Packages:

+ +

jenkins.io

+

+

Package v1alpha2 contains the API Schema definitions for the jenkins.io v1alpha2 API group

+

+Resource Types: + +

Jenkins +

+

+

Jenkins is the Schema for the jenkins API

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +jenkins.io/v1alpha2 + +
+kind
+string +
Jenkins
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +JenkinsSpec + + +
+

Spec defines the desired state of the Jenkins

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+master
+ + +JenkinsMaster + + +
+

Master represents Jenkins master pod properties and Jenkins plugins. +Every single change here requires a pod restart.

+
+seedJobs
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.SeedJob + + +
+(Optional) +

SeedJobs defines a list of Jenkins Seed Job configurations +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines

+
+service
+ + +Service + + +
+(Optional) +

Service is the Kubernetes service of the Jenkins master HTTP pod +Defaults to : +port: 8080 +type: ClusterIP

+
+slaveService
+ + +Service + + +
+(Optional) +

Service is the Kubernetes service of the Jenkins slave pods +Defaults to : +port: 50000 +type: ClusterIP

+
+backup
+ + +Backup + + +
+(Optional) +

Backup defines the configuration of a Jenkins backup +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore

+
+restore
+ + +Restore + + +
+(Optional) +

Backup defines the configuration of a Jenkins backup restore +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore

+
+groovyScripts
+ + +GroovyScripts + + +
+(Optional) +

GroovyScripts defines the configuration of Jenkins customization via groovy scripts

+
+configurationAsCode
+ + +ConfigurationAsCode + + +
+(Optional) +

ConfigurationAsCode defines the configuration of Jenkins customization via the Configuration as Code Jenkins plugin

+
+
+status
+ + +JenkinsStatus + + +
+

Status defines the observed state of Jenkins

+
+

AppliedGroovyScript +

+

+(Appears on: +JenkinsStatus) +

+

+

AppliedGroovyScript is the applied groovy script in Jenkins by the operator

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+configurationType
+ +string + +
+

ConfigurationType is the name of the configuration type(base-groovy, user-groovy, user-casc)

+
+source
+ +string + +
+

Source is the name of source where is located groovy script

+
+name
+ +string + +
+

Name is the name of the groovy script

+
+Hash
+ +string + +
+

Hash is the hash of the groovy script and secrets which it uses

+
+

Backup +

+

+(Appears on: +JenkinsSpec) +

+

+

Backup defines the configuration of a Jenkins backup

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+containerName
+ +string + +
+

ContainerName is the container name responsible for backup operation

+
+action
+ + +Handler + + +
+

Action defines the action which performs the backup in the backup container sidecar

+
+interval
+ +uint64 + +
+

Interval tells you how often the backup is made in seconds +Defaults to 30.

+
+makeBackupBeforePodDeletion
+ +bool + +
+

MakeBackupBeforePodDeletion tells the operator to make a backup before Jenkins master pod deletion

+
+

ConfigMapRef +

+

+(Appears on: +Customization) +

+

+

ConfigMapRef is the reference to Kubernetes ConfigMap

+

+ + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+
+

ConfigurationAsCode +

+

+(Appears on: +JenkinsSpec) +

+

+

ConfigurationAsCode defines configuration of Jenkins customization via the Configuration as Code Jenkins plugin

+

+ + + + + + + + + + + + + +
FieldDescription
+Customization
+ + +Customization + + +
+
+

Container +

+

+(Appears on: +JenkinsMaster) +

+

+

Container defines the Kubernetes container attributes

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name of the container specified as a DNS_LABEL. +Each container in a pod must have a unique name (DNS_LABEL).

+
+image
+ +string + +
+

Docker image name. +More info: https://kubernetes.io/docs/concepts/containers/images

+
+imagePullPolicy
+ + +Kubernetes core/v1.PullPolicy + + +
+

Image pull policy. +One of Always, Never, IfNotPresent. +Defaults to Always.

+
+resources
+ + +Kubernetes core/v1.ResourceRequirements + + +
+

Compute Resources required by this container. +More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

+
+command
+ +[]string + +
+(Optional) +

Entrypoint array. Not executed within a shell. +The docker image’s ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

+
+args
+ +[]string + +
+(Optional) +

Arguments to the entrypoint. +The docker image’s CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

+
+workingDir
+ +string + +
+(Optional) +

Container’s working directory. +If not specified, the container runtime’s default will be used, which +might be configured in the container image.

+
+ports
+ + +[]Kubernetes core/v1.ContainerPort + + +
+(Optional) +

List of ports to expose from the container. Exposing a port here gives +the system additional information about the network connections a +container uses, but is primarily informational. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default “0.0.0.0” address inside a container will be +accessible from the network.

+
+envFrom
+ + +[]Kubernetes core/v1.EnvFromSource + + +
+(Optional) +

List of sources to populate environment variables in the container. +The keys defined within a source must be a C_IDENTIFIER. All invalid keys +will be reported as an event when the container is starting. When a key exists in multiple +sources, the value associated with the last source will take precedence. +Values defined by an Env with a duplicate key will take precedence.

+
+env
+ + +[]Kubernetes core/v1.EnvVar + + +
+(Optional) +

List of environment variables to set in the container.

+
+volumeMounts
+ + +[]Kubernetes core/v1.VolumeMount + + +
+(Optional) +

Pod volumes to mount into the container’s filesystem.

+
+livenessProbe
+ + +Kubernetes core/v1.Probe + + +
+(Optional) +

Periodic probe of container liveness. +Container will be restarted if the probe fails.

+
+readinessProbe
+ + +Kubernetes core/v1.Probe + + +
+(Optional) +

Periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails.

+
+lifecycle
+ + +Kubernetes core/v1.Lifecycle + + +
+(Optional) +

Actions that the management system should take in response to container lifecycle events.

+
+securityContext
+ + +Kubernetes core/v1.SecurityContext + + +
+(Optional) +

Security options the pod should run with. +More info: https://kubernetes.io/docs/concepts/policy/security-context/ +More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

+
+

Customization +

+

+(Appears on: +ConfigurationAsCode, +GroovyScripts) +

+

+

Customization defines configuration of Jenkins customization

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+secret
+ + +SecretRef + + +
+
+configurations
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.ConfigMapRef + + +
+
+

GroovyScripts +

+

+(Appears on: +JenkinsSpec) +

+

+

GroovyScripts defines configuration of Jenkins customization via groovy scripts

+

+ + + + + + + + + + + + + +
FieldDescription
+Customization
+ + +Customization + + +
+
+

Handler +

+

+(Appears on: +Backup, +Restore) +

+

+

Handler defines a specific action that should be taken

+

+ + + + + + + + + + + + + +
FieldDescription
+exec
+ + +Kubernetes core/v1.ExecAction + + +
+

Exec specifies the action to take.

+
+

JenkinsCredentialType +(string alias)

+

+(Appears on: +SeedJob) +

+

+

JenkinsCredentialType defines the type of Jenkins credential used in the seed job mechanism

+

+

JenkinsMaster +

+

+(Appears on: +JenkinsSpec) +

+

+

JenkinsMaster defines the Jenkins master pod attributes and plugins, +every single change requires a Jenkins master pod restart

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+masterAnnotations
+ +map[string]string + +
+(Optional) +

Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations

+
+nodeSelector
+ +map[string]string + +
+(Optional) +

NodeSelector is a selector which must be true for the pod to fit on a node. +Selector which must match a node’s labels for the pod to be scheduled on that node. +More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

+
+securityContext
+ + +Kubernetes core/v1.PodSecurityContext + + +
+(Optional) +

SecurityContext that applies to all the containers of the Jenkins +Master. As per kubernetes specification, it can be overridden +for each container individually. +Defaults to: +runAsUser: 1000 +fsGroup: 1000

+
+containers
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Container + + +
+

List of containers belonging to the pod. +Containers cannot currently be added or removed. +There must be at least one container in a Pod. +Defaults to: +- image: jenkins/jenkins:lts +imagePullPolicy: Always +livenessProbe: +failureThreshold: 12 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 80 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 5 +name: jenkins-master +readinessProbe: +failureThreshold: 3 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 30 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 1 +resources: +limits: +cpu: 1500m +memory: 3Gi +requests: +cpu: “1” +memory: 600Mi

+
+imagePullSecrets
+ + +[]Kubernetes core/v1.LocalObjectReference + + +
+(Optional) +

ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. +If specified, these secrets will be passed to individual puller implementations for them to use. For example, +in the case of docker, only DockerConfig type secrets are honored. +More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod

+
+volumes
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

List of volumes that can be mounted by containers belonging to the pod. +More info: https://kubernetes.io/docs/concepts/storage/volumes

+
+basePlugins
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin + + +
+

BasePlugins contains plugins required by operator +Defaults to : +- name: kubernetes +version: 1.15.7 +- name: workflow-job +version: “2.32” +- name: workflow-aggregator +version: “2.6” +- name: git +version: 3.10.0 +- name: job-dsl +version: “1.74” +- name: configuration-as-code +version: “1.19” +- name: configuration-as-code-support +version: “1.19” +- name: kubernetes-credentials-provider +version: 0.12.1

+
+plugins
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin + + +
+(Optional) +

Plugins contains plugins required by user

+
+

JenkinsSpec +

+

+(Appears on: +Jenkins) +

+

+

JenkinsSpec defines the desired state of the Jenkins

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+master
+ + +JenkinsMaster + + +
+

Master represents Jenkins master pod properties and Jenkins plugins. +Every single change here requires a pod restart.

+
+seedJobs
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.SeedJob + + +
+(Optional) +

SeedJobs defines list of Jenkins Seed Job configurations +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines

+
+service
+ + +Service + + +
+(Optional) +

Service is Kubernetes service of Jenkins master HTTP pod +Defaults to : +port: 8080 +type: ClusterIP

+
+slaveService
+ + +Service + + +
+(Optional) +

Service is Kubernetes service of Jenkins slave pods +Defaults to : +port: 50000 +type: ClusterIP

+
+backup
+ + +Backup + + +
+(Optional) +

Backup defines configuration of Jenkins backup +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore

+
+restore
+ + +Restore + + +
+(Optional) +

Backup defines configuration of Jenkins backup restore +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore

+
+groovyScripts
+ + +GroovyScripts + + +
+(Optional) +

GroovyScripts defines configuration of Jenkins customization via groovy scripts

+
+configurationAsCode
+ + +ConfigurationAsCode + + +
+(Optional) +

ConfigurationAsCode defines configuration of Jenkins customization via Configuration as Code Jenkins plugin

+
+

JenkinsStatus +

+

+(Appears on: +Jenkins) +

+

+

JenkinsStatus defines the observed state of Jenkins

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+operatorVersion
+ +string + +
+(Optional) +

OperatorVersion is the operator version which manages this CR

+
+provisionStartTime
+ + +Kubernetes meta/v1.Time + + +
+(Optional) +

ProvisionStartTime is a time when Jenkins master pod has been created

+
+baseConfigurationCompletedTime
+ + +Kubernetes meta/v1.Time + + +
+(Optional) +

BaseConfigurationCompletedTime is a time when Jenkins base configuration phase has been completed

+
+userConfigurationCompletedTime
+ + +Kubernetes meta/v1.Time + + +
+(Optional) +

UserConfigurationCompletedTime is a time when Jenkins user configuration phase has been completed

+
+restoredBackup
+ +uint64 + +
+(Optional) +

RestoredBackup is the restored backup number after Jenkins master pod restart

+
+lastBackup
+ +uint64 + +
+(Optional) +

LastBackup is the latest backup number

+
+pendingBackup
+ +uint64 + +
+(Optional) +

PendingBackup is the pending backup number

+
+backupDoneBeforePodDeletion
+ +bool + +
+(Optional) +

BackupDoneBeforePodDeletion tells if backup before pod deletion has been made

+
+userAndPasswordHash
+ +string + +
+(Optional) +

UserAndPasswordHash is a SHA256 hash made from the username and password

+
+createdSeedJobs
+ +[]string + +
+(Optional) +

CreatedSeedJobs contains list of seed job ids already created in Jenkins

+
+appliedGroovyScripts
+ + +[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.AppliedGroovyScript + + +
+(Optional) +

AppliedGroovyScripts is a list with all applied groovy scripts in Jenkins by the operator

+
+

Mailgun +

+

+(Appears on: +Notification) +

+

+

Mailgun is handler for Mailgun email service notification channel

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+domain
+ +string + +
+
+apiKeySecretKeySelector
+ + +SecretKeySelector + + +
+
+recipient
+ +string + +
+
+from
+ +string + +
+
+

MicrosoftTeams +

+

+(Appears on: +Notification) +

+

+

MicrosoftTeams is handler for Microsoft MicrosoftTeams notification channel

+

+ + + + + + + + + + + + + +
FieldDescription
+webHookURLSecretKeySelector
+ + +SecretKeySelector + + +
+

The web hook URL to MicrosoftTeams App

+
+

Notification +

+

+

Notification is a service configuration used to send notifications about Jenkins status

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+loggingLevel
+ + +NotificationLogLevel + + +
+
+verbose
+ +bool + +
+
+name
+ +string + +
+
+slack
+ + +github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Slack + + +
+
+teams
+ + +github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.MicrosoftTeams + + +
+
+mailgun
+ + +github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Mailgun + + +
+
+

NotificationLogLevel +(string alias)

+

+(Appears on: +Notification) +

+

+

NotificationLogLevel defines logging level of Notification

+

+

Plugin +

+

+(Appears on: +JenkinsMaster) +

+

+

Plugin defines Jenkins plugin

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name is the name of Jenkins plugin

+
+version
+ +string + +
+

Version is the version of Jenkins plugin

+
+

Restore +

+

+(Appears on: +JenkinsSpec) +

+

+

Restore defines configuration of Jenkins backup restore operation

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+containerName
+ +string + +
+

ContainerName is the container name responsible for restore backup operation

+
+action
+ + +Handler + + +
+

Action defines action which performs restore backup in restore container sidecar

+
+recoveryOnce
+ +uint64 + +
+(Optional) +

RecoveryOnce if want to restore specific backup set this field and then Jenkins will be restarted and desired backup will be restored

+
+

SecretKeySelector +

+

+(Appears on: +Mailgun, +MicrosoftTeams, +Slack) +

+

+

SecretKeySelector selects a key of a Secret.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+secret
+ + +Kubernetes core/v1.LocalObjectReference + + +
+

The name of the secret in the pod’s namespace to select from.

+
+key
+ +string + +
+

The key of the secret to select from. Must be a valid secret key.

+
+

SecretRef +

+

+(Appears on: +Customization) +

+

+

SecretRef is reference to Kubernetes secret

+

+ + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+
+

SeedJob +

+

+(Appears on: +JenkinsSpec) +

+

+

SeedJob defines configuration for seed job +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+id
+ +string + +
+

ID is the unique seed job name

+
+credentialID
+ +string + +
+

CredentialID is the Kubernetes secret name which stores repository access credentials

+
+description
+ +string + +
+(Optional) +

Description is the description of the seed job

+
+targets
+ +string + +
+

Targets is the repository path where the seed job definitions are

+
+repositoryBranch
+ +string + +
+

RepositoryBranch is the repository branch where the seed job definitions are

+
+repositoryUrl
+ +string + +
+

RepositoryURL is the repository access URL. Can be SSH or HTTPS.

+
+credentialType
+ + +JenkinsCredentialType + + +
+(Optional) +

JenkinsCredentialType is the https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ credential type

+
+githubPushTrigger
+ +bool + +
+(Optional) +

GitHubPushTrigger is used for GitHub web hooks

+
+buildPeriodically
+ +string + +
+(Optional) +

BuildPeriodically is setting for scheduled trigger

+
+pollSCM
+ +string + +
+(Optional) +

PollSCM is setting for polling changes in SCM

+
+ignoreMissingFiles
+ +bool + +
+(Optional) +

IgnoreMissingFiles is setting for Job DSL API plugin to ignore files that miss

+
+additionalClasspath
+ +string + +
+(Optional) +

AdditionalClasspath is setting for Job DSL API plugin to set Additional Classpath

+
+failOnMissingPlugin
+ +bool + +
+(Optional) +

FailOnMissingPlugin is setting for Job DSL API plugin that fails job if required plugin is missing

+
+unstableOnDeprecation
+ +bool + +
+(Optional) +

UnstableOnDeprecation is setting for Job DSL API plugin that sets build status as unstable if build using deprecated features

+
+

Service +

+

+(Appears on: +JenkinsSpec) +

+

+

Service defines Kubernetes service attributes

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+annotations
+ +map[string]string + +
+(Optional) +

Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations

+
+labels
+ +map[string]string + +
+

Route service traffic to pods with label keys and values matching this +selector. If empty or not present, the service is assumed to have an +external process managing its endpoints, which Kubernetes will not +modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. +Ignored if type is ExternalName. +More info: https://kubernetes.io/docs/concepts/services-networking/service/

+
+type
+ + +Kubernetes core/v1.ServiceType + + +
+(Optional) +

Type determines how the Service is exposed. Defaults to ClusterIP. Valid +options are ExternalName, ClusterIP, NodePort, and LoadBalancer. +“ExternalName” maps to the specified externalName. +“ClusterIP” allocates a cluster-internal IP address for load-balancing to +endpoints. Endpoints are determined by the selector or if that is not +specified, by manual construction of an Endpoints object. If clusterIP is +“None”, no virtual IP is allocated and the endpoints are published as a +set of endpoints rather than a stable IP. +“NodePort” builds on ClusterIP and allocates a port on every node which +routes to the clusterIP. +“LoadBalancer” builds on NodePort and creates an +external load-balancer (if supported in the current cloud) which routes +to the clusterIP. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services—service-types

+
+port
+ +int32 + +
+

The port that is exposed by this service. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

+
+nodePort
+ +int32 + +
+(Optional) +

The port on each node on which this service is exposed when type=NodePort or LoadBalancer. +Usually assigned by the system. If specified, it will be allocated to the service +if unused, or else creation of the service will fail. +Default is to auto-allocate a port if the ServiceType of this Service requires one. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport

+
+loadBalancerSourceRanges
+ +[]string + +
+(Optional) +

If specified and supported by the platform, this will restrict traffic through the cloud-provider +the load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature.” +More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/

+
+loadBalancerIP
+ +string + +
+(Optional) +

Only applies to Service Type: LoadBalancer +LoadBalancer will get created with the IP specified in this field. +This feature depends on whether the underlying cloud-provider supports specifying +the loadBalancerIP when a load balancer is created. +This field will be ignored if the cloud-provider does not support the feature.

+
+

Slack +

+

+(Appears on: +Notification) +

+

+

Slack is handler for Slack notification channel

+

+ + + + + + + + + + + + + +
FieldDescription
+webHookURLSecretKeySelector
+ + +SecretKeySelector + + +
+

The web hook URL to Slack App

+
+
+

+Generated with gen-crd-api-reference-docs +on git commit f4c4235. +

diff --git a/website/content/en/docs/Developer Guide/_index.md b/website/content/en/docs/Getting Started/latest/developer-guide.md similarity index 82% rename from website/content/en/docs/Developer Guide/_index.md rename to website/content/en/docs/Getting Started/latest/developer-guide.md index 8b831b97..056f54ac 100644 --- a/website/content/en/docs/Developer Guide/_index.md +++ b/website/content/en/docs/Getting Started/latest/developer-guide.md @@ -137,6 +137,53 @@ kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.us kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.password}' | base64 -d ``` +# Tools + +## Configure environment variables + +```bash +export GOPATH=/home/go # example value +export GOROOT=/usr/lib/go-1.12 # example value +export PATH=$GOPATH/bin:$PATH +``` + +## goimports + +``` +go get golang.org/x/tools/cmd/goimports +cd $GOPATH/src/golang.org/x/tools/cmd/goimports +go build +go install +``` + +## golint + +``` +go get -u golang.org/x/lint/golint +cd $GOPATH/src/golang.org/x/lint/golint +go build +go install +``` + +## checkmake +``` +go get github.com/mrtazz/checkmake +cd $GOPATH/src/github.com/mrtazz/checkmake +go build +go install +``` + +## staticcheck + +``` +mkdir -p $GOPATH/src/github.com/dominikh/ +cd $GOPATH/src/github.com/dominikh/ +git clone https://github.com/dominikh/go-tools.git +cd $GOPATH/src/github.com/dominikh/go-tools/staticcheck +go build +go install +``` + [dep_tool]:https://golang.github.io/dep/docs/installation.html [git_tool]:https://git-scm.com/downloads diff --git a/website/content/en/docs/Getting Started/v0.1.x/developer-guide.md b/website/content/en/docs/Getting Started/v0.1.x/developer-guide.md new file mode 100644 index 00000000..056f54ac --- /dev/null +++ b/website/content/en/docs/Getting Started/v0.1.x/developer-guide.md @@ -0,0 +1,198 @@ +--- +title: "Developer Guide" +linkTitle: "Developer Guide" +weight: 60 +date: 2019-08-05 +description: > + Jenkins Operator for developers +--- + +{{% pageinfo %}} +This document explains how to setup your development environment. +{{% /pageinfo %}} + +## Prerequisites + +- [operator_sdk][operator_sdk] version v0.8.1 +- [git][git_tool] +- [go][go_tool] version v1.12+ +- [goimports, golint, checkmake and staticcheck][install_dev_tools] +- [minikube][minikube] version v1.1.0+ (preferred Hypervisor - [virtualbox][virtualbox]) +- [docker][docker_tool] version 17.03+ + +## Clone repository and download dependencies + +```bash +mkdir -p $GOPATH/src/github.com/jenkinsci +cd $GOPATH/src/github.com/jenkinsci/ +git clone git@github.com:jenkinsci/kubernetes-operator.git +cd kubernetes-operator +make go-dependencies +``` + +## Build and run with a minikube + +Build and run **Jenkins Operator** locally: + +```bash +make build minikube-run EXTRA_ARGS='--minikube --local' +``` + +Once minikube and **Jenkins Operator** are up and running, apply Jenkins custom resource: + +```bash +kubectl apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml +kubectl get jenkins -o yaml +kubectl get po +``` + +## Build and run with a remote Kubernetes cluster + +You can also run the controller locally and make it listen to a remote Kubernetes server. + +```bash +make run NAMESPACE=default KUBECTL_CONTEXT=remote-k8s EXTRA_ARGS='--kubeconfig ~/.kube/config' +``` + +Once minikube and **Jenkins Operator** are up and running, apply Jenkins custom resource: + +```bash +kubectl --context remote-k8s --namespace default apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml +kubectl --context remote-k8s --namespace default get jenkins -o yaml +kubectl --context remote-k8s --namespace default get po +``` + +## Testing + +Run unit tests: + +```bash +make test +``` + +### Running E2E tests on Linux + +Run e2e tests with minikube: + +```bash +make minikube-start +eval $(minikube docker-env) +make build e2e +``` + +Run the specific e2e test: + +```bash +make build e2e E2E_TEST_SELECTOR='^TestConfiguration$' +``` + +### Running E2E tests on macOS + +At first, you need to start minikube: +```bash +$ make minikube-start +$ eval $(minikube docker-env) +``` + +Build a Docker image inside the provided Linux container by: +```bash +$ make indocker +``` + +Build **Jenkins Operator** inside a container using: + + +```bash +$ make build +``` + +Then exit the container and run: +``` +make e2e +``` + +## Tips & Tricks + +### Building docker image on minikube (for e2e tests) + +To be able to work with the docker daemon on `minikube` machine run the following command before building an image: + +```bash +eval $(minikube docker-env) +``` + +### When `pkg/apis/jenkinsio/*/jenkins_types.go` has changed + +Run: + +```bash +make deepcopy-gen +``` + +### Getting the Jenkins URL and basic credentials + +```bash +minikube service jenkins-operator-http- --url +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.user}' | base64 -d +kubectl get secret jenkins-operator-credentials- -o 'jsonpath={.data.password}' | base64 -d +``` + +# Tools + +## Configure environment variables + +```bash +export GOPATH=/home/go # example value +export GOROOT=/usr/lib/go-1.12 # example value +export PATH=$GOPATH/bin:$PATH +``` + +## goimports + +``` +go get golang.org/x/tools/cmd/goimports +cd $GOPATH/src/golang.org/x/tools/cmd/goimports +go build +go install +``` + +## golint + +``` +go get -u golang.org/x/lint/golint +cd $GOPATH/src/golang.org/x/lint/golint +go build +go install +``` + +## checkmake +``` +go get github.com/mrtazz/checkmake +cd $GOPATH/src/github.com/mrtazz/checkmake +go build +go install +``` + +## staticcheck + +``` +mkdir -p $GOPATH/src/github.com/dominikh/ +cd $GOPATH/src/github.com/dominikh/ +git clone https://github.com/dominikh/go-tools.git +cd $GOPATH/src/github.com/dominikh/go-tools/staticcheck +go build +go install +``` + + +[dep_tool]:https://golang.github.io/dep/docs/installation.html +[git_tool]:https://git-scm.com/downloads +[go_tool]:https://golang.org/dl/ +[operator_sdk]:https://github.com/operator-framework/operator-sdk +[fork_guide]:https://help.github.com/articles/fork-a-repo/ +[docker_tool]:https://docs.docker.com/install/ +[kubectl_tool]:https://kubernetes.io/docs/tasks/tools/install-kubectl/ +[minikube]:https://kubernetes.io/docs/tasks/tools/install-minikube/ +[virtualbox]:https://www.virtualbox.org/wiki/Downloads +[jenkins-operator]:../README.md +[install_dev_tools]:install_dev_tools.md