|
| 1 | +# Dependency Management |
| 2 | + |
| 3 | +Kubebuilder uses [dep](https://golang.github.io/dep) to manage dependencies. |
| 4 | +Different dependency management tasks can be done using the `dep ensure` |
| 5 | +command. |
| 6 | + |
| 7 | +## Adding new dependencies |
| 8 | + |
| 9 | +{% panel style="warning", title="Kubernetes Dependencies" %} |
| 10 | + |
| 11 | +Kubebuilder-generated projects depends on a number of Kubernetes |
| 12 | +dependencies internally. Kubebuilder (using the controller-runtime |
| 13 | +library) makes sure that the parts of these dependencies that are exposed |
| 14 | +in the Kubebuilder API remain stable. |
| 15 | + |
| 16 | +It's recommended not to make use of most of these libraries directly, since |
| 17 | +they change frequently in incompatible ways. The `k8s.io/api` repository is |
| 18 | +the exception to this, and it's reccomended that you rely on the version that |
| 19 | +`kubebuilder` requires, instead of listing it as a direct dependency in |
| 20 | +`Gopkg.toml`. |
| 21 | + |
| 22 | +However, if you do add direct dependencies on any of these libraries yourself, |
| 23 | +be aware that you may encounter dependency conflicts. See [the problem with |
| 24 | +kubernetes libraries](#the-problem-with-kubernetes-libraries) below for more |
| 25 | +information. |
| 26 | + |
| 27 | +{% endpanel %} |
| 28 | + |
| 29 | +{% method %} |
| 30 | + |
| 31 | +Dep manages dependency constraints using the `Gopkg.toml` file. You can add |
| 32 | +new dependencies by adding new `[[constraint]]` stanzas to that file. |
| 33 | +Alternatively, if you're [not using `kubebuilder |
| 34 | +update`](./upgrading_kubebuilder.md#by-hand), you can use the `dep ensure -add` |
| 35 | +command to add new dependencies to your `Gopkg.toml`. |
| 36 | + |
| 37 | +{% sample lang="bash" %} |
| 38 | +```bash |
| 39 | +# edit Gopkg.toml OR perform the following: |
| 40 | +dep ensure -add github.com/pkg/errors |
| 41 | +``` |
| 42 | +{% endmethod %} |
| 43 | + |
| 44 | +## Updating existing dependencies |
| 45 | + |
| 46 | +{% method %} |
| 47 | + |
| 48 | +Update dependencies for your project to the latest minor and patch versions. |
| 49 | + |
| 50 | +{% sample lang="bash" %} |
| 51 | +```bash |
| 52 | +dep ensure -update |
| 53 | +``` |
| 54 | +{% endmethod %} |
| 55 | + |
| 56 | +## Repopulating your vendor directory |
| 57 | + |
| 58 | +{% method %} |
| 59 | + |
| 60 | +Dependency source code is stored in the vendor directory. If it ever gets |
| 61 | +deleted, you can repopulate it using the exact dependency versions stored in |
| 62 | +`Gopkg.lock`. |
| 63 | + |
| 64 | +{% sample lang="bash" %} |
| 65 | +```bash |
| 66 | +dep ensure |
| 67 | +``` |
| 68 | +{% endmethod %} |
| 69 | + |
| 70 | +## How Kubebuilder's Dependencies Work |
| 71 | + |
| 72 | +{% panel style="warning", title="Under the Hood" %} |
| 73 | + |
| 74 | +The information in this section details how Kubebuilder's dependency graph |
| 75 | +works. It's not necessary for day-to-day use of Kubebuilder, but can be useful |
| 76 | +if you want to understand how a particular version of Kubebuilder relates to |
| 77 | +a particular version of Kubernetes. |
| 78 | + |
| 79 | +{% endpanel %} |
| 80 | + |
| 81 | +### TL;DR |
| 82 | + |
| 83 | +As of Kubebuilder 1.0.2: |
| 84 | + |
| 85 | +* Projects generated with Kubebuilder list a semantic version of |
| 86 | + controller-runtime and controller-tools as their only direct |
| 87 | + dependencies. All other Kubernetes-related libraries are transative |
| 88 | + dependencies. |
| 89 | + |
| 90 | +* controller-runtime and controller-tools each list a specific, identical |
| 91 | + set of dependencies on Kubernetes libraries and related libraries. |
| 92 | + |
| 93 | +* Once you've updated your dependencies with `kubebuilder update vendor`, |
| 94 | + you'll be able to run `dep ensure` and `dep ensure --update` to safely |
| 95 | + update all your dependencies in the future. |
| 96 | + |
| 97 | +* You can depend on controller-runtime to follow [semantic versioning |
| 98 | + guarantees](https://semver.org) -- we won't break your code without |
| 99 | + introducing a new major version, for both the interfaces in |
| 100 | + controller-runtime, and the bits of the kubernetes libraries that |
| 101 | + controller-runtime actually exposes. |
| 102 | + |
| 103 | +### The Problem with Kubernetes libraries |
| 104 | + |
| 105 | +The kubernetes project exports a collection of libraries (which we'll call |
| 106 | +the **k8s-deps** from now on) that expose common functionality used when |
| 107 | +building applications that consume Kubernetes APIs (e.g. clients, |
| 108 | +informers, etc). Due to the way Kubrenetes is versioned |
| 109 | +(non-semantically), all of these dependencies must closely match -- |
| 110 | +differing versions can cause strange compilation or runtime errors. |
| 111 | + |
| 112 | +Beyond this, these libraries have their own set of dependencies which are |
| 113 | +not always the latest versions, or are occaisionally in-between versions. |
| 114 | + |
| 115 | +Collecting the correct set of dependencies for any given Kubernetes |
| 116 | +project can thus be tricky. |
| 117 | + |
| 118 | +### Using Prebaked Manifests (Kubebuilder pre-1.0.2) |
| 119 | + |
| 120 | +Before version 1.0.2, Kubebuilder shipped a pre-baked manifest of the |
| 121 | +correct dependencies. When scaffolding out at new project using |
| 122 | +`kubebuilder init` (a **kb-project**), it would copy over a `Gopkg.toml` |
| 123 | +file containing the exact dependency versions required for the project |
| 124 | +(which could then be used by `dep` dependency management tool to actually |
| 125 | +fetch the dependencies). |
| 126 | + |
| 127 | +In addition to the Kubernetes dependencies required, this also specified |
| 128 | +that all kb-projects use the master branch of the **controller-runtime** |
| 129 | +library, which provides the abstractions that Kubebuilder is built upon. |
| 130 | +Because controller-runtime wraps and consumes Kubernetes, it *also* needs |
| 131 | +specific versions of the k8s-deps, and those version *must* match the ones |
| 132 | +listed in the kb-project's Gopkg.toml, otherwise we'd have conflicting |
| 133 | +dependencies. |
| 134 | + |
| 135 | +#### The Problem with Prebaked Manifests |
| 136 | + |
| 137 | +Using the master branch as the target version of controller-runtime made |
| 138 | +it impossible to make breaking changes to controller-runtime. However, |
| 139 | +even when using a specific version of controller-runtime, it's still |
| 140 | +difficult to make changes. |
| 141 | + |
| 142 | +Since kb-projects must use an identical set of dependencies to |
| 143 | +controller-runtime, any update to the controller-runtime dependencies |
| 144 | +(say, to pull in a new feature) would have caused immediate dependency |
| 145 | +version conflicts. Effectively, any update to the dependencies had to be |
| 146 | +treated as a major version revision, and there would have been no way to |
| 147 | +tell the difference between "this release includes breaking API changes" |
| 148 | +and "this release simply switches to a newer version of the k8s-deps". |
| 149 | + |
| 150 | +### Transitive Dependencies (Kubebuilder 1.0.2+) |
| 151 | + |
| 152 | +As noted above, any dependency version in kb-projects must match |
| 153 | +dependency versions listed in controller-runtime, exactly. Furthermore, it |
| 154 | +turns out, by design, the set of k8s-deps used in controller-runtime is |
| 155 | +a superset of the set of dependencies actually imported by kb-projects. |
| 156 | + |
| 157 | +Therefore, in kb-projects generated with Kubebuilder 1.0.2+, no |
| 158 | +dependencies are listed besides controller-runtime (and controller-tools). |
| 159 | +All of the k8s-deps become transitive dependencies, whose versions are |
| 160 | +determined when `dep` (the dependency management tool) looks at the |
| 161 | +versions required by controller-runtime. |
| 162 | + |
| 163 | +controller-runtime is semantically versioned, so any changes to either the |
| 164 | +interfaces in controller-runtime, or the pieces of the k8s-deps that are |
| 165 | +exposed as part of those interfaces, means a new major version of |
| 166 | +controller-runtime will be released. Any other changes (new features, bug |
| 167 | +fixes, updates to k8s-deps which don't break interfaces) yield minor or |
| 168 | +patch versions (as per [semver](https://semver.org)), which can easily and |
| 169 | +safely be updated to by kb-projects. |
| 170 | + |
| 171 | +#### controller-tools Dependencies |
| 172 | + |
| 173 | +controller-tools is the library used to generate CRD and RBAC manifests |
| 174 | +for kb-projects. With Kubebuilder 1.0.2+, it does not directly depend on |
| 175 | +controller-runtime, but shares the same set of dependencies. It therefore |
| 176 | +must be updated in lockstep with controller-runtime. This is mostly |
| 177 | +a concern of the controller-tools/controller-runtime maintainers, and will |
| 178 | +not affect users. Like controller-runtime, controller-tools uses semver. |
0 commit comments