github.com/inspektor-gadget/inspektor-gadget@v0.28.1/docs/devel/CONTRIBUTING.md (about) 1 --- 2 title: Contributing 3 weight: 50 4 description: > 5 How to contribute to Inspektor Gadget. 6 --- 7 8 Here you can learn how you can contribute to Inspektor Gadget. 9 10 ## Getting started 11 12 To better understand how the pieces fit together, we recommend reading the 13 [architecture](../core-concepts/architecture.md) documentation before starting to play with 14 Inspektor Gadget. 15 16 ### Setup developer environment 17 18 - [Fork](https://github.com/inspektor-gadget/inspektor-gadget/fork) and clone this repo: 19 - `git clone git@github.com:your_account/inspektor-gadget.git`. 20 - Install [Docker](https://docs.docker.com/get-docker/), [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx) and [Golang](https://golang.org/doc/install). 21 - To be able to cross build our different container images, you will also need [`qemu-user-static`](https://github.com/multiarch/qemu-user-static). 22 23 ## Building the code 24 25 Inspektor Gadget is composed of a client executable that runs on the 26 operator's machine, and a container image that runs in the Kubernetes 27 cluster. They can be built together or independently. 28 29 ### Building the client executable 30 31 You can compile the client executable for your platform by running `make kubectl-gadget`. 32 33 To cross compile for all supported platforms, you can run `make 34 kubectl-gadget-all` or select a specific one with `make 35 kubectl-gadget-linux-amd64` or `make kubectl-gadget-darwin-amd64`. 36 37 ### Building the gadget container image 38 39 You can build and push the container gadget image by running the following commands: 40 41 ```bash 42 $ make gadget-container 43 $ make push-gadget-container 44 ``` 45 46 The eBPF code is built using a Docker container, so you don't have to worry 47 installing the compilers to build it. 48 49 If you push the container images to another registry, you can use the `--image` 50 argument when deploying to the Kubernetes cluster. 51 52 #### Notes 53 54 - Using a locally built container image requires pushing it to a container 55 registry, either local or remote. The default registry can be overridden by 56 changing the value of the `CONTAINER_REPO` env variable, which defaults to 57 `ghcr.io/inspektor-gadget/inspektor-gadget` if not defined. 58 - The compilation uses `tools/image-tag` to choose the tag of the container 59 image to use according to the branch that you are compiling. 60 - It is also possible to change the BCC to be used as described in 61 [BCC](#Updating-BCC-from-upstream) section. 62 - You can generate the required BTF information for some well known 63 kernel versions by setting `ENABLE_BTFGEN=true` 64 65 66 ### Building the eBPF object files 67 68 If you need to compile the eBPF code of the gadgets, the ebpf-objects target 69 will help you in this task: 70 71 ```bash 72 $ make ebpf-objects 73 ... 74 go: downloading github.com/giantswarm/crd-docs-generator v0.7.1 75 ... 76 Wrote /work/pkg/gadgettracermanager/containers-map/containersmap_bpfel.go 77 ``` 78 79 ### Building `ig` 80 81 Inspektor Gadget also provides the [`ig`](../ig.md) tool to 82 trace containers without Kubernetes. It can be built independently from the 83 `kubectl-gadget` and the gadget container image. 84 85 ```bash 86 $ make ig 87 ``` 88 89 ## Testing 90 91 ### Development environment on minikube 92 93 For faster iteration, it's possible to make changes to Inspektor Gadget and 94 test them on minikube locally without pushing container images to any 95 registry. 96 97 * Follow the specific [installation instructions](../getting-started/install-kubernetes.md#minikube) for minikube or use `make minikube-start` to start it. 98 * Deploy the locally modified version of Inspektor Gadget to an already 99 running minikube cluster with `make minikube-deploy`. 100 101 ### Unit tests 102 103 You can run the different unit tests with: 104 105 ```bash 106 $ make test 107 ``` 108 109 ### Regenerating testdata 110 111 Some unit tests depend on precompiled files on [testdata](../../testdata/). These files can be 112 regenerated by running 113 114 ```bash 115 $ make testdata 116 ``` 117 118 ### Integration tests 119 120 The integration tests use a Kubernetes cluster to deploy and test Inspektor Gadget. 121 Be sure that you have a valid kubeconfig and run: 122 123 ```bash 124 $ export KUBECONFIG=... # not needed if valid config in $HOME/.kube/config 125 $ make integration-tests 126 ``` 127 128 ### Integration tests for `ig` 129 130 #### Kubernetes 131 132 The integration tests for `ig` uses minikube for testing different container runtimes. 133 The default minikube driver used for testing is `docker`. Currently supported 134 container runtimes are `docker`, `containerd` and `cri-o`. You can start minikube using: 135 136 ```bash 137 $ make minikube-start-all 138 # for single container runtime e.g containerd 139 $ make CONTAINER_RUNTIME=containerd minikube-start 140 # for minikube driver other than docker e.g kvm2 141 $ make MINIKUBE_DRIVER=kvm2 minikube-start 142 ``` 143 144 And run the test using: 145 146 ```bash 147 $ make -C integration/k8s test-all 148 # for single container runtime e.g containerd 149 $ make -C integration/k8s CONTAINER_RUNTIME=containerd test 150 ``` 151 152 if no `CONTAINER_RUNTIME` is specified `docker` will be used as a default runtime. 153 154 #### Non-Kubernetes 155 156 The `ig` integration tests for non-Kubernetes containers directly interact 157 with container runtime. The tests assume that you already have the desired container 158 runtime installed. Currently supported runtime is `docker` only, You can run the test using: 159 160 ```bash 161 $ make -C integration/ig/non-k8s test-docker 162 ``` 163 164 ### Benchmarks 165 166 You can run the different benchmark tests with: 167 168 ```bash 169 $ make gadgets-benchmarks 170 ``` 171 172 Or you can run an individual test with: 173 174 ```bash 175 $ go test -exec sudo \ 176 -bench='BenchmarkAllGadgetsWithContainers/container10$/trace-tcpconnect' \ 177 -run=Benchmark \ 178 ./internal/benchmarks/... 179 ``` 180 181 Records of previous benchmarks are available [here](https://inspektor-gadget.github.io/ig-benchmarks/dev/bench/index.html). 182 See details in the [CI documentation (benchmarks)](ci.md#benchmarks). 183 184 #### Explaining performance improvements in a PR 185 186 If you want to contribute a performance improvement, it is useful to use benchmarks to explain the impact on 187 performances. I will use the example of an improvement on the networking gadgets from 188 [#1430](https://github.com/inspektor-gadget/inspektor-gadget/pull/1430): 189 190 * Run the benchmarks both on the `main` and the feature branches and saving the output in two files. 191 ```bash 192 $ git checkout main 193 $ go test -exec sudo \ 194 -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/trace-(dns|sni)' \ 195 -run=Benchmark \ 196 ./internal/benchmarks/... \ 197 -count 10 | tee main.bench 198 $ git checkout myfeature 199 $ go test -exec sudo \ 200 -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/trace-(dns|sni)' \ 201 -run=Benchmark \ 202 ./internal/benchmarks/... \ 203 -count 10 | tee patched.bench 204 ``` 205 206 Please use `-count` to gather a statistically significant sample of results. 207 The [benchstat's documentation](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat) recommends 10 times. 208 209 * Compare the results with `benchstat`: 210 ```bash 211 $ go install golang.org/x/perf/cmd/benchstat@latest # if not already installed 212 $ benchstat main.bench patched.bench 213 goos: linux 214 goarch: amd64 215 pkg: github.com/inspektor-gadget/inspektor-gadget/internal/benchmarks 216 cpu: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz 217 │ main.bench │ patched.bench │ 218 │ sec/op │ sec/op vs base │ 219 AllGadgetsWithContainers/container100/trace-dns-4 2.941 ± 3% 1.489 ± 4% -49.38% (p=0.000 n=10) 220 AllGadgetsWithContainers/container100/trace-sni-4 4.440 ± 19% 1.495 ± 6% -66.34% (p=0.000 n=10) 221 geomean 3.613 1.492 -58.72% 222 ``` 223 224 * Include the commands used and the output of `benchstat` in your pull request description 225 226 #### Profiling benchmarks 227 228 You can run the different benchmark tests while using the 229 [bcc profile tool](https://github.com/iovisor/bcc/blob/master/tools/profile_example.txt). 230 To be able to see the symbols in the profile, you need to build the binary with 231 `-ldflags="-s=false"`. 232 233 ```bash 234 $ go test -exec sudo \ 235 -ldflags="-s=false" \ 236 -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/snapshot-socket' \ 237 -run=Benchmark \ 238 ./internal/benchmarks/... \ 239 -count 100 240 ``` 241 242 Example of output showing a stack trace including both the userspace and kernel parts: 243 244 ```bash 245 $ sudo /usr/share/bcc/tools/profile -p $(pidof benchmarks.test) 246 b'established_get_first' 247 b'established_get_first' 248 b'tcp_seek_last_pos' 249 b'bpf_iter_tcp_batch' 250 b'bpf_iter_tcp_seq_next' 251 b'bpf_seq_read' 252 b'vfs_read' 253 b'ksys_read' 254 b'do_syscall_64' 255 b'entry_SYSCALL_64_after_hwframe' 256 runtime/internal/syscall.Syscall6 257 syscall.Syscall 258 syscall.read 259 internal/poll.(*FD).Read 260 os.(*File).Read 261 bufio.(*Scanner).Scan 262 github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).RunCollector.func1 263 github.com/inspektor-gadget/inspektor-gadget/pkg/netnsenter.NetnsEnter 264 github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).RunCollector 265 github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/tracer.(*Tracer).Run 266 github.com/inspektor-gadget/inspektor-gadget/pkg/runtime/local.(*Runtime).RunGadget 267 github.com/inspektor-gadget/inspektor-gadget/internal/benchmarks.BenchmarkAllGadgetsWithContainers.func1.1 268 testing.(*B).runN 269 testing.(*B).launch 270 testing.(*B).doBench.func1 271 runtime.goexit.abi0 272 - benchmarks.test (3452330) 273 22 274 ``` 275 276 It is also possible to use [pprof](https://pkg.go.dev/runtime/pprof) to profile 277 the benchmarks with the `-cpuprofile` and `-memprofile` flags. 278 279 ```bash 280 go test \ 281 -cpuprofile cpu.prof -memprofile mem.prof \ 282 -exec sudo \ 283 -ldflags="-s=false" \ 284 -bench='^BenchmarkAllGadgetsWithContainers$/^container100$/snapshot-socket' \ 285 -run=Benchmark ./internal/benchmarks/... \ 286 -count 5 287 $ go tool pprof -top cpu.prof 288 $ go tool pprof -top mem.prof 289 ``` 290 291 ### Continuous Integration 292 293 Inspektor Gadget uses GitHub Actions as CI. Please check dedicated [CI 294 documentation](ci.md) for more details. 295 296 Some integration tests (like AKS and ARO) are only run when a commit is pushed to the main branch or 297 a new tag is pushed. It's also possible to run those by pusing a branch named `citest/...`. Please 298 notice that the container images will be pushed to 299 https://github.com/inspektor-gadget/inspektor-gadget/pkgs/container/inspektor-gadget and those 300 should be manually cleaned up. 301 302 ## Getting Help 303 304 If you are having any issues with your contribution, or want to discuss anything about it, feel free 305 to reach out to us on [Slack](https://kubernetes.slack.com/messages/inspektor-gadget/) or on our 306 [community 307 meeting](https://docs.google.com/document/d/1cbPYvYTsdRXd41PEDcwC89IZbcA8WneNt34oiu5s9VA/edit) 308 309 ## Contribution Guidelines 310 311 ### Code of Conduct 312 313 Inspektor Gadget follows the CNCF 314 [Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). 315 316 ### Authoring PRs 317 318 For making PRs/commits consistent and easier to review, please check out 319 Kinvolk's [contribution guidelines on git](https://github.com/kinvolk/contribution/blob/master/topics/git.md). 320 321 We require all commits on a PR to be signed off certifying the [Developer Certificate of Origin](https://developercertificate.org/): 322 323 324 ``` 325 Developer Certificate of Origin 326 Version 1.1 327 328 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 329 330 Everyone is permitted to copy and distribute verbatim copies of this 331 license document, but changing it is not allowed. 332 333 334 Developer's Certificate of Origin 1.1 335 336 By making a contribution to this project, I certify that: 337 338 (a) The contribution was created in whole or in part by me and I 339 have the right to submit it under the open source license 340 indicated in the file; or 341 342 (b) The contribution is based upon previous work that, to the best 343 of my knowledge, is covered under an appropriate open source 344 license and I have the right under that license to submit that 345 work with modifications, whether created in whole or in part 346 by me, under the same open source license (unless I am 347 permitted to submit under a different license), as indicated 348 in the file; or 349 350 (c) The contribution was provided directly to me by some other 351 person who certified (a), (b) or (c) and I have not modified 352 it. 353 354 (d) I understand and agree that this project and the contribution 355 are public and that a record of the contribution (including all 356 personal information I submit with it, including my sign-off) is 357 maintained indefinitely and may be redistributed consistent with 358 this project or the open source license(s) involved. 359 ``` 360 361 It can be done by using `git commit -s`, `git commit --sign-off` or by manually adding a line like 362 to the commit message. 363 364 ``` 365 Signed-off-by: Joe Smith <joe.smith@email.com> 366 ``` 367 368 ### Good first issues 369 370 If you're looking where to start, you can check the issues with the 371 `good first issue` label on 372 [Inspektor Gadget](https://github.com/inspektor-gadget/inspektor-gadget/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). 373 Don't hesitate to 374 [talk to us](https://github.com/inspektor-gadget/inspektor-gadget#discussions) 375 if you need further help. 376 377 ### Proposing new features 378 379 If you want to propose a new feature or do a big change in the architecture 380 it's highly recommended to open an issue first to discuss it with the team. 381 382 ### Writing tests 383 384 We use `github.com/stretchr/testify` to make tests less verbose. 385 386 ## Planning 387 388 Our planning is published through two different project boards: 389 390 * [Inspektor Gadget Roadmap](https://github.com/orgs/inspektor-gadget/projects/1) 391 has the high level view of the big issues that we are planning to tackle 392 in the upcoming months. 393 * [Inspektor Gadget Sprint Planning](https://github.com/orgs/inspektor-gadget/projects/2) 394 has the week-to-week plans of which bugs we are currently working on, 395 and the different priorities of the issues involved. 396 397 ## BCC 398 399 ### Porting BCC gadgets 400 401 This project uses some gadgets based on [BCC](https://github.com/iovisor/bcc/). In the past, we 402 modified the BCC gadgets and executed them from our process, however it was very inflexible and we 403 decided to integrate those gadgets directly into our code base by rewriting their control plane in 404 Golang. 405 406 If you want to implement support for a BCC gadget, please read the [Rewriting the Control Plane of 407 BCC Tools in Golang](https://www.inspektor-gadget.io/blog/2022/09/rewriting-the-control-plane-of-bcc-tools-in-golang/) 408 blogpost that contains all the details about this process. 409 410 ## Security 411 412 For security, we invite you to take at look at the [dedicated document](../SECURITY.md).