A guide to

  * Developing source code changes.
  * Setting up a Kubernetes environment on your laptop

# Development of source code

Locally install tool dependencies using [retool](https://github.com/twitchtv/retool). just `retool` will be globally installed.

    make setup

Run lints and tests

    make && make check && make test

This and e2e tests are automatically ran on our Jenkins CI server.
Additionally, you can run some slower, more extensive linters.

    make lint-slow


# Environment

## GO

To build tidb-operator, Golang compiler version >= 1.9 is required.

## Kubernetes

First we need to run a Kubernetes cluster. `minikube` is the popular option for that. However, minikube only creates one Kubernetes node. To run TiDB, we need multiple Kubernetes nodes. There are a few options for this, but we have found a way to make DinD (Docker in Docker) work.

DinD (Docker in Docker) allows running the docker daemon inside a top-level docker container. This means the top-level container to simulate a Kubernetes node and have containers launched inside it. The kubeadm-dind-cluster project starts multiple docker containers as a k8s nodes on a standalone machine through DinD, and then start a k8s cluster by using docker to start k8s components on these nodes.


### Prepare local DinD kubernetes cluster

#### Install kubectl

TiDB Operator has been tested with Kubernetes v1.10, but newer versions may work.

	wget https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/darwin/amd64/kubectl
	chmod +x kubectl
	sudo mv kubectl /usr/local/bin

Configure kubectl auto completion for bash:

    echo "source <(kubectl completion bash)" >> $HOME/.bash_profile && source $HOME/.bash_profile

or zsh:

    echo "source <(kubectl completion zsh)" >> $HOME/.zshrc && source $HOME/.zshrc

#### Bring up the DinD K8s

We use [kubeadm-dind-cluster](https://github.com/kubernetes-sigs/kubeadm-dind-cluster) to bring up a local DinD K8s cluster.

	wget https://cdn.rawgit.com/kubernetes-sigs/kubeadm-dind-cluster/master/fixed/dind-cluster-v1.10.sh
	chmod +x dind-cluster-v1.10.sh
	NUM_NODES=4 ./dind-cluster-v1.10.sh up

*Note*: If you can't bring up DinD K8s using above method due to GFW network in China. You can try the following method (the Docker images used are pulled from [UCloud Docker Registry](https://docs.ucloud.cn/compute/uhub/index)):

	git clone https://github.com/pingcap/kubeadm-dind-cluster.git
	cd kubeadm-dind-cluster
	NUM_NODES=4 ../kubeadm-dind-cluster/tools/multi_k8s_dind_cluster_manager.sh rebuild e2e-v1.10

Ensure the DinD cluster works:

    kubectl get node,componentstatus
    kubectl get pod -n kube-system
    # view http://localhost:8080/ui in your browser

#### Install K8s package manager [Helm](https://helm.sh)

We'll use Helm to install tidb-operator and tidb-cluster on K8s. Use following command to install helm.

	export os=linux  # change `linux` to `darwin` if you use MacOS
	wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-${os}-amd64.tar.gz
	tar xzf helm-v2.9.1-${os}-amd64.tar.gz
	sudo mv ${os}-amd64/helm /usr/local/bin

#### Setup Local Persistent Volumes

We'll use [LocalPersistentVolume](https://kubernetes.io/docs/concepts/storage/volumes/#local) to persistent PD/TiKV data. The [local persistent volume provisioner](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume) doesn't work right in DinD, we need to modify its deployment. And it doesn't support [dynamic provision](https://github.com/kubernetes/community/pull/1914) yet, we need to manually mount disks or directory to mount points. It's a little tricky so we provide some [scripts](../manifests/local-dind) to help setup the development environment.

    cd /path/to/tidb-operator # go to tidb-operator source directory
    ./manifests/local-dind/pv-hosts.sh
	kubectl apply -f manifests/local-dind/local-volume-provisioner.yaml


### Deploying and testing TiDB clusters

Now we've setup a Kubernetes cluster, we can now run tidb operator as per the [README](../README.md) against your local k8s cluster.


# Local Deploy of source code changes

## Setup

As per the README, edit `./charts/tidb-operator/values.yaml`.

## Lifecycle

Make a change to code. Write tests and test it with `make test`. To deploy to your laptop run:

    make dind-reload

If you haven't already, install the cluster chart.

Now connect to the tidb cluster

    make dind-mysql

## Troubleshooting

If a pod is pending for a long time, check pod and pvc status

	kubectl describe pod <pod-name> -n <ns>
	kubectl describe pvc <pvc-name> -n <ns>


# Source code

## Generation

Code under `pkg/client` is generated by `./hack/codegen.sh'.
