Skip to content

Getting started with Longhorn Development

Eric Weber edited this page Mar 29, 2023 · 20 revisions

Setting up for Longhorn development

This page will go over setting up your environment for Longhorn development. Since Longhorn(especially engine) uses some Linux system functionalities, it needs to be developed and tested in a Linux environment.

Longhorn is mostly built with Go. We recommended using vim + vim-go (https://github.com/fatih/vim-go) in a Linux environment for development. An alternative is using IDE (e.g. GoLand) with your macOS, with a Linux environment set up for building and testing.

Installations

Install Go

Follow the instructions on https://golang.org/doc/install . Recommend version v1.13.3+.

IDE

vim + vim-go

Follow the instructions on https://github.com/fatih/vim-go

GoLand on macOS + a Linux environment

We recommended using GoLand's code synchronization function to a Linux environment for the final build and test.

Sync your code with remote server

  1. Click Tools -> Deployment -> Configuration -> “+” button

    1. Choose SFTP

    2. In Connection

      1. Host: IP address of the remote server

      2. User Name: user name of the remote host

      3. Authentication: choose Key pair, find your private key path (usually ~/.ssh/id_rsa).

        If you meet error Keypair '/home/xxx/.ssh/id_rsa' is corrupt or has unknown format. Only SSH2 keys in OpenSSH format (DSA, RSA or ECDSA) or PuTTY private key *.ppk keys are supported......, you can run ssh-keygen -m PEM -C "<Your_Email>" to re-generate key for GoLand. See https://intellij-support.jetbrains.com/hc/en-us/community/posts/360001301679-invalid-priatekey-error

      4. Root path: click Autodetect

    3. In Mappings

      1. Local path: your repo path
      2. Deployment path: the corresponding repo path on your remote host
  2. Click Tools -> Deployment -> Options Upload changed files automatically to the default server: choose Always or On explicit save action

Warning: Since the local repo and the remote repo are different local repos from git perspective, please keep git commit operations in the same local repo.

Run go fmt on explicit save

Click GoLand -> Preference -> Tools -> File Wathcers -> "+" button -> choose "go fmt"

Install Docker on Linux

curl -L https://releases.rancher.com/install-docker/18.09.sh | sh

You can choose other version here:

install-docker supported by rancher

Then add user in 'docker' group:

sudo usermod -aG docker $USER

Install K3S on Linux

You can develop Longhorn in a single-node installation using K3S.

You can use the --disable=traefik option to make your dev machine's port 80 available to Longhorn UI instead of Traefik. When using the Quick-Start Install Script, this looks like curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -.

Install open-iscsi package on Linux

sudo apt install -y open-iscsi

Install Dapper

Dapper - Docker Build Wrapper

go get github.com/rancher/dapper or go install github.com/rancher/dapper in Go 1.17+

Development

Components

For backend, Longhorn is consists of manager, engine and ui, along with Longhorn tests as integration tests, and longhorn charts for Rancher to deploy Longhorn.

Build

Run make in the project's root directory. It will produce a Docker image with the latest build if succeed.

How to update dependencies

Though Longhorn uses go mod to manage the dependency, we still keep /vendor for the convenience of the building without depending on the Internet.

  • If you've modified the dependency of the code, use go get <github.com/xxx>@<version/commit> on the root directory to update the go.mod to the specified version if needed.
  • Before submitting the PR, run go mod tidy and go mod vendor to update the dependency.
  • Use replace section in the go.mod to test your own changes before checking it in.
  • Make sure when submitting PR, separate the change of go.mod, go.sum and vendor directory into a separate commit.

How to deploy modified Longhorn

Use script to help the deployment

You can use lm-update.sh to perform a quick update on Longhorn manager deployment. Run

make
lm-update.sh <docker-username>

Would update the existing Longhorn deployment to use the latest changes.

Noted that lm-update.sh only works with an existing Longhorn deployment since it will skip unnecessary steps to deploy other Kubernetes components.

If you prefer not to use lm-update.sh, following the steps below to update the deployment:

Package your modified project

Because all things are containerized, you should package your project as a docker image by running make.

  • make also accepts an environment variable REPO= for overriding the default repository. For example, you can run make REPO=yasker to product images like yasker/longhorn-manager:1234567 instead of rancher/longhorn-manager:1234567.

Upload the image

Kubernetes always fetches images from DockerHub to create containers. Hence you need to push your images to DockerHub repo.

If you haven't get one, please register here.

Then you need to login on your dev machine.

docker login

Now you can push your image

docker push <USER_NAME>/<REPO_NAME>:<VERSION>

Deploy/Update your Longhorn

After you get a new docker image for this commit, you also need to update your deployment by modifying corresponding image value of those .yaml file in /deploy dir.

You can use update_image.sh to update them. Before using the script, environment variable REPO needs to be set as your DockerHub username, and the initial image value should be unchanged.

The script only works with Linux.

e.g.

git checkout -- ./deploy
./deploy/update_image.sh

Then you can re-create or update your longhorn components with these new yaml files.

Use script to change imagePullPolicy back to Always

We set the imagePullPolicy to IfNotPresent so that the users can easily install Longhorn in air-gap installation without setting up a registry. As a result, K8s will not pull new images if there are existing images on the local node in the cluster. However, this is annoying to developers who use the tag master and expect to always have the newest images pulled. Therefore, you can use this bash script to quickly change all the imagePullPolicies back to Always for Longhorn manager daemonset, UI deployment, Driver Deploymentdeployment, Engine Image daemonset.

Test

For unit tests, They will be run when you make a new docker image.

For integration tests, we're using pytest.

Longhorn manager & Longhorn tests

longhorn-manger unit tests are in directory /controller, /scheduler and so on. If you modified these module, you may need to add/modify the unit tests too.

Besides, longhorn-manger integration tests are in longhorn-tests. After modifying longhorn-manager, it's better to check whether adding/modifying integration tests is needed and run this test. You need to manually create a new image and deploy them. The procedures are similar to Development. By the way, you can modify pytest flags in test.yaml to run separate tests or enable more verbose output.

Longhorn engine

The integration tests are in the directory /integration. This integration tests will also be run when you make new image.

If you just want to check a specific test case, you can use dapper command.

e.g. dapper ./scripts/integration-test -- -s -x -k test_cli

Backupstore

It's a key dependency of the Longhorn engine. And the integration test of the Longhorn engine will cover some use cases of this repo. But you can run make to build and run the unit tests for the repo. Before testing the repo, you need to install NFS kernel server:

sudo apt install nfs-kernel-server

Other dependencies of longhorn-engine

Before running the integration test, you may need to push the commit to your personal repo, set the associated repo URL and commit ID in go.mod then update /vendor. See here for the details.

Charts

After you modified yaml files in /deploy, e.g. added a new flag, you may also need to update the corresponding fields in Longhorn Chart.

We don't allow modification of the existing charts.

When you're creating a new chart, it should at least consist of two commits:

  1. Copy the existing latest chart to a new directory.
  2. Update the content of latest chart and bump up the version number.

Project management

We're using ZenHub for Longhorn's project management. You can download the browser extension here.

After installing it, you can navigate to here to take a look at Longhorn's issue dashboard.

Tools of the trade

Familiar with those tools is the pre-requirement for developing with Longhorn.

Git

Concepts

commit, branch, remote, HEAD, HEAD^

Commands

checkout (-b), rebase (-i), remote add, push, pull --rebase, add, rm, commit (--amend), log, show, diff, status

Github

Fork, PR

Kubernetes

Concepts

pod, namespace, deployment, statefulset, daemonset, pv, pvc, crd, node, yaml

kubectl commands

get, describe, log, exec, create, delete, apply

Common aliases

alias k="kubectl"
alias kdesc="kubectl describe"
alias kl="kubectl -n longhorn-system"
alias kldesc="kubectl -n longhorn-system describe"

Tools

https://github.com/johanhaleby/kubetail

Clone this wiki locally