Skip to content

Latest commit

 

History

History
275 lines (192 loc) · 8.32 KB

development.md

File metadata and controls

275 lines (192 loc) · 8.32 KB

Development Guide

Setting up the environment

Pre-commit

Pre-commit is used to enforce code quality and style. You should install python and pip using your package manager. To install pre-commit, run:

pip install pre-commit

Then, install the pre-commit hooks:

pre-commit install

You can run pre-commit manually on all files with:

pre-commit run --all-files

pre-commit will automatically run on every commit, ensuring that your code adheres to the specified style and quality checks.

To add additional hooks, you can modify the .pre-commit-config.yaml file. For more details on configuring pre-commit hooks, refer to the official pre-commit documentation.

The most important hook for our project is the golangci-lint hook. It enforces the Go code style and checks for common mistakes. It is configured in the .golangci.yml file. To see the available linters, refer to the golangci-lint documentation.

If you receive a comment on a PR that could have been caught by a linter and fixed automatically, consider searching for a pre-commit hook or golangci-lint linter that could have caught the issue. If you find one, please add it to the .pre-commit-config.yaml file and the .golangci.yml file. This will help ensure that the issue is caught in the future and that the code adheres to the specified style and quality checks.

Building the project

Prerequisites

The rest of the utilities are installed automatically by the Makefile.

Building the binary

To build the project, run:

make build

This builds both project binaries:

./bin/local-csi-driver --version
./bin/local-csi-manager --version

Use make build-driver or make build-manager to build only one binary.

Building and pushing the Docker image

The Docker build uses Buildx with OUTPUT_TYPE=type=registry by default, so it builds and pushes both images in one target:

REGISTRY=<your registry> make docker-build

Substitute <your registry> with the desired Docker registry. To build images into the local Docker image store instead, override the output type:

OUTPUT_TYPE=type=docker REGISTRY=<your registry> make docker-build

Base image signature verification

On pushes to main and pull requests targeting main or release branches, CI uses Notation to verify the digest-pinned MCR base images in the Dockerfiles, including Dockerfile.manager. Verification requires the Microsoft supply-chain signer under a strict trust policy. The Microsoft supply-chain and timestamp trust roots are downloaded with pinned SHA-256 checksums.

The workflow fails if an MCR base image is not digest-pinned or its signature cannot be verified. It verifies upstream base images, not the driver or manager images built by this project.

Building the Helm chart

To build the Helm chart, run:

make helm-build

This will package a helm chart for the project and place it in the dist directory.

Deploying the project

Creating a local Kubernetes cluster

Some development can be done in a local Kubernetes cluster. To create a local Kubernetes cluster, you can use kind. To create a local cluster, run:

make single

This will create a local Kubernetes cluster using kind. You can then use this cluster to test the project. To delete the cluster, run:

make clean

Creating an AKS cluster

Most of the development is done in an AKS cluster. To create an AKS cluster, you can use the make target aks. The AKS cluster is created using bicep.

To create a cluster, run:

make aks

For more details on the bicep template and available parameters, refer to the deploy/README.md file.

To Deploy

Build and push the Docker images and Helm chart to your registry:

REGISTRY=<registry> make docker-build helm-build helm-push

To deploy the project to your Kubernetes cluster, you can call all the make targets in one command:

REGISTRY=<registry> make docker-build helm-build helm-push helm-install

This builds and pushes the Docker images, packages and pushes the Helm chart, and installs the project in your Kubernetes cluster.

To Uninstall

To uninstall the project from your Kubernetes cluster, run:

make uninstall-helm

This will remove the project from your cluster.

Testing the project

The project has a number of tests that can be run to ensure that the project is working correctly. The tests are divided into categories: unit tests, E2E tests, External E2E tests, and sanity tests. The tests are written in Go.

Generally, if something can be tested with a unit test, it should be. If something is too complex to test with a unit test, it should be tested with an E2E test. The sanity and external E2E tests are conformance tests provided by the Kubernetes community to test CSI drivers. For more details on the tests, refer to the test/README.md file. Unit tests can be found throughout the project, but other tests are located in the test directory.

Unit tests

To run the unit tests, run:

make test

This will run all the unit tests in the project.

E2E Tests

These tests are run in a Kubernetes cluster. To run the E2E tests, you need to set up a Kubernetes cluster and install the project in it. You can do this with:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-e2e

Those tests that are part of e2e suite are run in the cluster. The tests are written in Go and use the Ginkgo testing framework. The tests are located in the test/e2e directory. By default, the test-e2e test target will include tests that we can run in a kind cluster. If you have a real AKS cluster, you can run the tests

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-e2e-aks

This will run the E2E tests in the AKS cluster. The tests are written in Go and are chosen with the "aks" and "e2e" label selectors.

You can also run the E2E tests in a local Kubernetes cluster using kind. To do this, create a multi-node cluster with a loop-backed LVM volume group on each node:

make kind-e2e-bootstrap

Tests labeled for AKS-specific behavior are skipped in this mode.

External E2E Tests

To run the external E2E tests, use a cluster with eligible local storage and install the project in it. You can do this with:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-external-e2e

This runs the non-disruptive external E2E suite against the current cluster. The tests are written in Go and use the Ginkgo testing framework. There are two test configurations, lvm and lvm-annotation.

The lvm tests only run the generic ephemeral volume tests, which is the only kind of volume permitted by default by the driver. The lvm-annotation tests run all the tests specified by the external tests.

It uses kyverno to add the localdisk.csi.acstor.io/accept-ephemeral-storage: "true" annotation to the persistent volume claim. This allows the tests to test the "accept-ephemeral-storage" mode of the driver. The tests are located in the test/external directory.

Sanity Tests

To run the sanity tests, run:

REGISTRY=<registry>.azurecr.io make docker-build helm-build helm-push test-sanity

The sanity tests are conformance tests that check whether the driver adheres to the CSI specification. The tests are written in Go and use the Ginkgo testing framework. The implementation can be found in the kubernetes-csi/csi-test repo. The tests are located in the test/sanity directory.

The tests run against the current Kubernetes cluster. If a change breaks the tests, refer to the container-storage-interface/spec repo to review the spec.