Project: Inspektor Gadget (Observability and Analysis / Observability)
File: CONTRIBUTING.md

title: Contributing weight: 50 description: > How to contribute to Inspektor Gadget. Here you can learn how you can contribute to Inspektor Gadget. To better understand how the pieces fit together, we recommend reading the documentation before starting to play with Inspektor Gadget. and clone this repo: `git clone git@github.com:your_account/inspektor-gadget.git`. Install , and . To be able to cross build our different container images, you will also need . Inspektor Gadget is composed of a client executable that runs on the operator's machine, and a container image that runs in the Kubernetes cluster. They can be built together or independently. You can compile the client executable for your platform by running `make kubectl-gadget`. To cross compile for all supported platforms, you can run `make kubectl-gadget-all` or select a specific one with `make kubectl-gadget-linux-amd64` or `make kubectl-gadget-darwin-amd64`. You can build and push the container gadget image by running the following commands: ```bash $ make gadget-container $ make push-gadget-container ``` The eBPF code is built using a Docker container, so you don't have to worry installing the compilers to build it. If you push the container images to another registry, you can use the `--image` argument when deploying to the Kubernetes cluster. Using a locally built container image requires pushing it to a container registry, either local or remote. The default registry can be overridden by changing the value of the `CONTAINER_REPO` env variable, which defaults to `ghcr.io/inspektor-gadget/inspektor-gadget` if not defined. The compilation uses `tools/image-tag` to choose the tag of the container image to use according to the branch that you are compiling. It is also possible to change the BCC to be used as described in section. You can generate the required BTF information for some well known kernel versions by setting `ENABLE_BTFGEN=true` If you need to compile the eBPF code of the gadgets, the ebpf-objects target will help you in this task: ```bash $ make ebpf-objects ... go: downloading github.com/giantswarm/crd-docs-generator v0.7.1 ... Wrote /work/pkg/gadgettracermanager/containers-map/containersmap_bpfel.go ``` Inspektor Gadget also provides the tool to trace containers without Kubernetes. It can be built independently from the `kubectl-gadget` and the gadget container image. ```bash $ make ig ``` For faster iteration, it's possible to make changes to Inspektor Gadget and test them on minikube locally without pushing container images to any registry. Follow the specific for minikube or use `make minikube-start` to start it. Deploy the locally modified version of Inspektor Gadget to an already running minikube cluster with `make minikube-deploy`. You can run the different unit tests with: ```bash $ make test ``` Some unit tests depend on precompiled files on . These files can be regenerated by running ```bash $ make testdata ``` The integration tests use a Kubernetes cluster to deploy and test Inspektor Gadget. Be sure that you have a valid kubeconfig and run: ```bash $ export KUBECONFIG=... # not needed if valid config in $HOME/.kube/config $ make integration-tests ``` The integration tests for `ig` uses minikube for testing different container runtimes. The default minikube driver used for testing is `docker`. Currently supported container runtimes are `docker`, `containerd` and

You can start minikube using: ```bash $ make minikube-start-all $ make CONTAINER_RUNTIME=containerd minikube-start $ make MINIKUBE_DRIVER=kvm2 minikube-start ``` And run the test using: ```bash $ make -C integration/k8s test-all $ make -C integration/k8s CONTAINER_RUNTIME=containerd test ``` if no `CONTAINER_RUNTIME` is specified `docker` will be used as a default runtime. The `ig` integration tests for non-Kubernetes containers directly interact with container runtime. The tests assume that you already have the desired container runtime installed. Currently supported runtime is `docker` only, You can run the test using: ```bash $ make -C integration/ig/non-k8s test-docker ``` You can run the different benchmark tests with: ```bash $ make gadgets-benchmarks ``` Or you can run an individual test with: ```bash $ go test -exec sudo \ -bench='BenchmarkAllGadgetsWithContainers/container10$/trace-tcpconnect' \ -run=Benchmark \ ./internal/benchmarks/... ``` Records of previous benchmarks are available . See details in the . If you want to contribute a performance improvement, it is useful to use benchmarks to explain the impact on performances. I will use the example of an improvement on the networking gadgets from : Run the benchmarks both on the `main` and the feature branches and saving the output in two files. ```bash $ git checkout main $ go test -exec sudo \ -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/trace-(dns|sni)' \ -run=Benchmark \ ./internal/benchmarks/... \ -count 10 | tee main.bench $ git checkout myfeature $ go test -exec sudo \ -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/trace-(dns|sni)' \ -run=Benchmark \ ./internal/benchmarks/... \ -count 10 | tee patched.bench ``` Please use `-count` to gather a statistically significant sample of results. The recommends 10 times. Compare the results with `benchstat`: ```bash $ go install golang.org/x/perf/cmd/benchstat@latest # if not already installed $ benchstat main.bench patched.bench goos: linux goarch: amd64 pkg: github.com/inspektor-gadget/inspektor-gadget/internal/benchmarks cpu: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz main.bench patched.bench sec/op sec/op vs base AllGadgetsWithContainers/container100/trace-dns-4 2.941 3% 1.489 4% -49.38% (p=0.000 n=10) AllGadgetsWithContainers/container100/trace-sni-4 4.440 19% 1.495 6% -66.34% (p=0.000 n=10) geomean 3.613 1.492 -58.72% ``` Include the commands used and the output of `benchstat` in your pull request description You can run the different benchmark tests while using the . To be able to see the symbols in the profile, you need to build the binary with `-ldflags="-s=false"`. ```bash $ go test -exec sudo \ -ldflags="-s=false" \ -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/snapshot-socket' \ -run=Benchmark \ ./internal/benchmarks/... \ -count 100 ``` Example of output showing a stack trace including both the userspace and kernel parts: ```bash $ sudo /usr/share/bcc/tools/profile -p $(pidof benchmarks.test) b'establishedgetfirst' b'establishedgetfirst' b'tcpseeklast_pos' b'bpfitertcp_batch' b'bpfitertcpseqnext' b'bpfseqread' b'vfs_read' b'ksys_read' b'dosyscall64' b'entrySYSCALL64afterhwframe' runtime/internal/syscall.Syscall6 syscall.Syscall syscall.read internal/poll.(*FD).Read os.(*File).Read bufio.(*Scanner).Scan github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).RunCollector.func1 github.com/inspektor-gadget/inspektor-gadget/pkg/netnsenter.NetnsEnter github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).RunCollector github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).Run github.com/inspektor-gadget/inspektor-gadget/pkg/runtime/local.(*Runtime).RunGadget github.com/inspektor-gadget/inspektor-gadget/internal/benchmarks.BenchmarkAllGadgetsWithContainers.func1.1 testing.(*B).runN testing.(*B).launch testing.(*B).doBench.func1 runtime.goexit.abi0 benchmarks.test (3452330) 22 ``` It is also possible to use to profile the benchmarks with the `-cpuprofile` and `-memprofile` flags. ```bash go test \ -cpuprofile cpu.prof -memprofile mem.prof \ -exec sudo \ -ldflags="-s=false" \ -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/snapshot-socket' \ -run=Benchmark ./internal/benchmarks/... \ -count 5 $ go tool pprof -top cpu.prof $ go tool pprof -top mem.prof ``` Inspektor Gadget uses GitHub Actions as CI. Please check dedicated [CI documentation](ci.md) for more details. Some integration tests (like AKS and ARO) are only run when a commit is pushed to the main branch or a new tag is pushed. It's also possible to run those by pusing a branch named `citest/...`. Please notice that the container images will be pushed to

and those should be manually cleaned up. If you are having any issues with your contribution, or want to discuss anything about it, feel free to reach out to us on or on our [community meeting](https://docs.google.com/document/d/1cbPYvYTsdRXd41PEDcwC89IZbcA8WneNt34oiu5s9VA/edit) Inspektor Gadget follows the CNCF . For making PRs/commits consistent and easier to review, please check out Kinvolk's . We require all commits on a PR to be signed off certifying the : ``` Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` It can be done by using `git commit -s`, `git commit --sign-off` or by manually adding a line like to the commit message. ``` Signed-off-by: Joe Smith <joe.smith@email.com> ``` If you're looking where to start, you can check the issues with the `good first issue` label on . Don't hesitate to if you need further help. If you want to propose a new feature or do a big change in the architecture it's highly recommended to open an issue first to discuss it with the team. We use `github.com/stretchr/testify` to make tests less verbose. Our planning is published through two different project boards: has the high level view of the big issues that we are planning to tackle in the upcoming months. has the week-to-week plans of which bugs we are currently working on, and the different priorities of the issues involved. This project uses some gadgets based on . In the past, we modified the BCC gadgets and executed them from our process, however it was very inflexible and we decided to integrate those gadgets directly into our code base by rewriting their control plane in Golang. If you want to implement support for a BCC gadget, please read the [Rewriting the Control Plane of BCC Tools in Golang](https://www.inspektor-gadget.io/blog/2022/09/rewriting-the-control-plane-of-bcc-tools-in-golang/) blogpost that contains all the details about this process. For security, we invite you to take at look at the .