## File: README.md # Krew [](https://github.com/kubernetes-sigs/krew/actions) [](https://goreportcard.com/report/kubernetes-sigs/krew) [](https://github.com/kubernetes-sigs/krew/blob/master/LICENSE) [](https://github.com/kubernetes-sigs/krew/releases) Krew is the package manager for kubectl plugins. ## What does Krew do? Krew is a tool that makes it easy to use [kubectl plugins](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/). Krew helps you discover plugins, install and manage them on your machine. It is similar to tools like apt, dnf or [brew](https://brew.sh). Today, over [200 kubectl plugins][list] are available on Krew. - **For kubectl users:** Krew helps you find, install and manage kubectl plugins in a consistent way. - **For plugin developers:** Krew helps you package and distribute your plugins on multiple platforms and makes them discoverable. ## [Documentation][website] Visit the [**Krew documentation**][website] to find **Installation** instructions, **User Guide** and **Developer Guide**. You can follow the [**Quickstart**][quickstart] to get started with Krew. [website]: https://krew.sigs.k8s.io/ [quickstart]: https://krew.sigs.k8s.io/docs/user-guide/quickstart/ ## Contributor Documentation - [Releasing Krew](./docs/RELEASING_KREW.md): how to release new version of Krew. - [Plugin Lifecycle](./docs/PLUGIN_LIFECYCLE.md): how Krew installs/upgrades plugins and itself. (Not necessarily up-to-date, but it can give a good idea about how Krew works under the covers.) - [Krew Architecture](./docs/KREW_ARCHITECTURE.md): architectural decisions behind designing initial versions of Krew. (Not up-to-date.) - [Krew Logo](./docs/KREW_LOGO.md): our logo and branding assets. Visit [`./docs`](./docs) for all documentation. ## Roadmap Please check out the [Issue Tracker](https://github.com/kubernetes-sigs/krew/issues) to see the plan of record for new features and changes. ## Community ### Bug reports * If you have a problem with the Krew itself, please file an issue in this repository. * If you're having a problem with a particular plugin's installation or upgrades, file an issue at [krew-index][index] repository. * If you're having an issue with an installed plugin, file an issue for the repository the plugin's source code is hosted at. ### Communication channels * Slack: [#krew](https://kubernetes.slack.com/messages/krew) or [#sig-cli](https://kubernetes.slack.com/messages/sig-cli) * [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-cli) * [Kubernetes Community site](https://kubernetes.io/community/) ### Contributing Interested in contributing to Krew? Please refer to our [Contributing Guidelines](./docs/CONTRIBUTOR_GUIDE.md) for more details. ### Code of Conduct Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](https://github.com/kubernetes-sigs/krew/blob/master/code-of-conduct.md). [index]:https://github.com/kubernetes-sigs/krew-index [list]: https://krew.sigs.k8s.io/plugins/ --- ## File: docs/CONTRIBUTOR_GUIDE.md # Contributor Guide This guide is intended for people who want to start working on `krew` itself. If you intend to write a new plugin, see the [Developer Guide](https://krew.sigs.k8s.io/docs/developer-guide/) instead. ## Setting up the environment Krew is built with go 1.10, but newer versions will do as well. Most toolchains will expect that the krew repository is on the `GOPATH`. To set it up correctly, do ```bash mkdir -p $(go env GOPATH)/src/sigs.k8s.io/krew cd $(go env GOPATH)/src/sigs.k8s.io/krew git clone https://github.com/kubernetes-sigs/krew . git remote set-url origin --push no_push # to avoid pushes ``` ### Using macOS for development The tools provided in the `hack` folder expect you to use GNU binaries, the easiest way to install them is to use brew ```bash brew install coreutils grep gnu-sed ``` And remember to add them to your `$PATH` to make them your default binaries ```bash export PATH=$(brew --prefix coreutils)/libexec/gnubin:$PATH export PATH="$(brew --prefix grep)/libexec/gnubin:$PATH" export PATH="$(brew --prefix gnu-sed)/libexec/gnubin:$PATH" ``` ## Code style Krew adheres to standard `golang` code formatting conventions, and also expects imports sorted properly. To automatically format code appropriately, install [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports) via: ```bash go get golang.org/x/tools/cmd/goimports ``` and run: ```bash goimports -local sigs.k8s.io/krew -w cmd pkg integration_test ``` Shell scripts are automatically formatted by `shfmt`, to install and to validate run: ```bash hack/run-lint.sh ``` If format is in expected format, there will be no output. Otherwise, problematic scripts will be listed and a command will be provided to format them: ```bash shfmt -w -i=2 hack/ ``` In addition, a boilerplate license header is expected in all source files. _All new code should be covered by tests._ ## Compiling Use `hack/make-binary.sh` to make a binary in `out/bin/` for your current platform. You can use `hack/make-binaries.sh` to build binaries for all supported platforms. ## Running tests To run tests locally, the easiest way to get started is with ```bash hack/run-tests.sh ``` This will run all unit tests and code quality tools. To run a single tool independently of the other code checks, have a look at the other scripts in [`hack/`](../hack). In addition, there are integration tests to cover high-level krew functionality. To run integration tests, you will need to build the `krew` binary beforehand: ```bash hack/make-binary.sh hack/run-integration-tests.sh ``` ## Testing `krew` in a sandbox After making changes to krew, you should also check that it behaves as expected. You can do this without messing up the krew installation on the host system by setting the `KREW_ROOT` environment variable. For example: ```bash mkdir playground KREW_ROOT="$PWD/playground" krew update ``` Any changes that krew is going to apply will then be applied in the `playground/` folder, instead of the standard `~/.krew` folder. ### Testing in a docker sandbox Alternatively, if the isolation provided by `KREW_ROOT` is not enough, there is also a script to run krew in a docker sandbox: ```bash hack/run-in-docker.sh ``` --- ## File: docs/DEVELOPER_GUIDE.md # Developer Guide This page has moved from GitHub to our website: https://krew.sigs.k8s.io/docs/developer-guide/ --- ## File: docs/KREW_ARCHITECTURE.md # Architecture (This guide is intended for developers of krew.) :warning: The instructions below are not up to date for krew v0.2+. But this document is still retained as a reference to highlight some original design decisions behind Krew. - [Krew Plugins location](#krew-plugins-location) - [Directory structure](#directory-structure) - [Krew Index](#krew-index) - [Index Structure](#index-structure) - [Plugin Manifest File Format](#plugin-manifest-file-format) - [Update Index Locally](#update-index-locally) - [Plugin Package Format](#plugin-package-format) - [Installation Methods](#installation-methods) - [Why krew should not rely on OS-Package managers](#why-krew-should-not-rely-on-os-package-managers) - [Krew Itself as a Plugin](#krew-itself-as-a-plugin) - [Kubectl Plugin Descriptor (plugin.yaml) File Generation](#kubectl-plugin-descriptor-pluginyaml-file-generation) - [Single Binary](#single-binary) - [Note on Potential Changes to Kubectl Plugin System](#note-on-potential-changes-to-kubectl-plugin-system) ## Krew Plugins location Kubernetes plugins can be installed to: 1. `${KUBECTL_PLUGINS_PATH}` If specified. 2. `${XDG_DATA_DIRS}/kubectl/plugins` 3. `~/.kube/plugins` It's up to the user to specify one of the above options. In this document the path will be referenced as `~/.kube/plugins`. This is not implementation specific. Krew installs itself in the default plugin directory for the user. ### Directory structure Krew installs plugins in its root path under `~/.krew/store`. Each plugin has a directory with its uncompressed content from the URI. Kubectl will recursively search the plugin path for plugin.yaml files. The download directory is a temporary directory which only exists during the execution of the install or upgrade command. Directory structure: ```text . ($HOME) └── .krew/ ├── bin/ | ├── kubectl-foo ├── index/ | ├── foo.yaml | └── krew.yaml └── store/ ├── foo// | ├── plugin.yaml | └── foo.sh └── krew// ├── commands/ | ├── install/ | | └── plugin.yaml | └── upgrade/ | └── plugin.yaml ├── krew-install └── krew-upgrade ${TMPDIR}/krew/ └── download/ (This directory is only available during installation and upgrade) └── foo// ├── plugin.yaml └── foo.sh ``` ### Krew Index As a starting point, the index holds information about all available plugins. The index will be synced to a user machine through git. The user operates on their local index. The index exists as a git repository, hosted on GitHub. This allows partial updates of the index, GPG verification of committers and rollbacks. #### Index Structure The repository will hold a directory of yaml files. Each describes a single plugin. This directory is called Plugin Manifest. The file name must match with the plugin name `.yaml`. To avoid conflicting commands, there should only be one new top level command for each plugin. ### Plugin Manifest File Format The Plugin Manifest for a plugin itself is a yaml file. It describes the plugin name, plugin download URI, verification hash and plugin version. Plugin manifest supports having different installation steps to support incompatible platforms like Unix systems and Windows. An example Plugin Manifest file of a plugin "foo", named `foo.yaml`, can look like this: ```yaml apiVersion: krew.googlecontainertools.github.com/v1alpha2 kind: Plugin metadata: name: foo spec: platforms: - uri: https://github.com/barbaz/foo/archive/windows-v0.5.0.tar.gz sha256: 29C9C411AF879AB85049344B81B8E8A9FBC1D657D493694E2783A2D0DB240775 # This is used during installation. It uses file Globs to copy required files. files: - from: "/posix/*" to: "." selector: # A regular Kubernetes label selector matchExpressions: - {key: os, operator: In, values: [macos, linux]} - uri: https://github.com/barbaz/foo/archive/windows-v0.5.0.tar.gz sha256: 29C9C411AF879AB85049344B81B8E8A9FBC1D657D493694E2783A2D0DB240775 files: - from: "/win/utils" to: "/utils" selector: matchLabels: os: "windows" # Version does not follow any conventions and is not functional. version: "v0.5.0" shortDesciption: Short description of foo! This is a long description it will be shown to elaborate The plugins purpose. caveats: | This plugin needs the following programs: * fzf * jq For a better user experience: export $TERM=vt220 ``` ### Update Index Locally To sync the index to the user's machine, krew requires that curl and git is installed on the host machine. Krew is cloning or pulling the index repository to `~/.kube/plugins/krew/index` on a `krew update`. The first pull can take some time due to a long history, but will be fast on incremental changes. We use git as a backend because it does already implement downloading, incremental updates with patches and GPG signing. ### Plugin Package Format The plugin package is found under the download URI in the Plugin Manifest. Currently, krew only supports downloading plugin packages of formats `.tar.gz` and `.zip` over HTTP(S) protocol. Plugins must meet some standards even though kubectl does allow more. Krew allows to download repositories and later copy only the needed files to a new directory using File Globs under `.spec.platforms[].files[]`. The file field mimics the posix mv command `mv `. The "to" field will be defaulted to ".". (See example manifest for a use case.) * To allow plugin scans and verification, the plugin.yaml file must be present in the root directory of the package after the files have been moved. * There should also be only one plugin.yaml in the package. * The plugin.yaml also has to reference an executable that is not in the parent repository. * A package also should not contain symlinks. ## Installation Methods Krew itself is also a krew plugin. To reduce the total maintenance and setup procedure, krew is bootstrapping and dogfooding itself. The installation on windows and linux works as follows: 1. Download the krew binary to a temp path 2. Run `krew update` 3. Run `krew install krew` 4. Delete current executed krew from the temp path ### Why krew should not rely on OS-Package managers We can’t easily cover all possible package managers. Trying this introduces a high maintenance overhead and a huge build pipeline. Maintaining many different packages can also lead to various errors that need domain knowledge to resolve. ## Krew Itself as a Plugin ### Kubectl Plugin Descriptor (plugin.yaml) File Generation Krew should be able to generate its own plugin.yaml files in its build pipeline to reduce human errors and toil work. As a CLI framework krew should use spf13’s cobra framework. It is possible to parse the cobra command tree and convert it into a plugin manifest. ### Single Binary To reduce the amount of disk space we compile krew as a single binary and generate multiple plugin.yaml files with different entry points to the binary. The binary then uses argv to determine which subcommand is called. ## Note on Potential Changes to Kubectl Plugin System Kubectl Plugin system is currently alpha and is undergoing a lot of change by SIG CLI. We are expecting the following changes may impact Krew heavily: Intention to move away from plugin.yaml: Community is planning to implement Git plugin model which does not require a plugin.yaml. Intention to move away from `~/.kube/plugins`: Community is planning to move a `$PATH` based discovery, like the Git plugin system. This way the plugin "foo" would be named "kubectl-foo" and placed in the `$PATH`. This will break Krew, but can be addressed through creating a `.../krew/bin` directory and symlinking the plugin executables there. This is very similar to what [brew](https://brew.sh/) does today. --- ## File: docs/KREW_LOGO.md # Krew logo Krew logo is designed by [@iboonox](https://twitter.com/iboonox) and it is licensed under Apache 2.0 license. Krew logo follows the nautical theme of Kubernetes: The tentacles wrapping around the crate refer to tentacles of a cuttlefish, which is the mascot of [kubectl](https://github.com/kubernetes/kubectl#kubectl) project, and the crate represents a kubectl plugin package. ## Available logo types | Type | Preview | | --- | --- | | Horizontal | | | Stacked | | | Icon-only | | ## Logo assets | Type | Color Scheme | Format | |--|--|--| | horizontal (text next to the icon) | colored | [[png]](../assets/logo/horizontal/color/krew-horizontal-color.png) [[svg]](../assets/logo/horizontal/color/krew-horizontal-color.svg) | | horizontal (text next to the icon) | black | [[png]](../assets/logo/horizontal/black/krew-horizontal-black.png) [[svg]](../assets/logo/horizontal/black/krew-horizontal-black.svg) | | horizontal (text next to the icon) | white | [[png]](../assets/logo/horizontal/white/krew-horizontal-white.png) [[svg]](../assets/logo/horizontal/white/krew-horizontal-white.svg) | | stacked (text below the icon) | colored | [[png]](../assets/logo/stacked/color/krew-stacked-color.png) [[svg]](../assets/logo/stacked/color/krew-stacked-color.svg) | | stacked (text below the icon) | black | [[png]](../assets/logo/stacked/black/krew-stacked-black.png) [[svg]](../assets/logo/stacked/black/krew-stacked-black.svg) | | stacked (text below the icon) | white | [[png]](../assets/logo/stacked/white/krew-stacked-white.png) [[svg]](../assets/logo/stacked/white/krew-stacked-white.svg) | | icon-only | colored | [[png]](../assets/logo/icon/color/krew-icon-color.png) [[svg]](../assets/logo/icon/color/krew-icon-color.svg) | | icon-only | black | [[png]](../assets/logo/icon/black/krew-icon-black.png) [[svg]](../assets/logo/icon/black/krew-icon-black.svg) | | icon-only | white | [[png]](../assets/logo/icon/white/krew-icon-white.png) [[svg]](../assets/logo/icon/white/krew-icon-white.svg) | --- ## File: docs/NAMING_GUIDE.md # Plugin Naming Style Guide This page has moved to our website: https://krew.sigs.k8s.io/docs/developer-guide/develop/naming-guide/ --- ## File: docs/PLUGIN_LIFECYCLE.md # Plugin Lifecycle (This guide is intended for developers of Krew.) :warning: The instructions below may not be up to date for krew v0.2 and higher. It is provided as a reference to learn how Krew works under the covers, but may not be entirely accurate. ## Installation The plugins will be downloaded and checked against its sha256 to verify the integrity. The package will be uncompressed into a directory called `${TMP}/krew/download///`. Then the directory will be renamed (mv) to `~/.krew/store///`. This ensures a partially atomic and idempotent operation on most file systems. ## Upgrade Upgrading is more difficult because we already have a plugin that is working. Krew should not destroy a working environment. The operations should be idempotent. If something fails we should be able to recover to the wanted state. Upgrading works by iterating over the `~/.krew/store/` directory names and comparing the current hash to the corresponding index file. When a hash differs the plugin gets installed again. Install the plugin: 1. Delete the old version 2. Therefore it‘s not possible for plugins to store data in the plugin directory. In case any plugin operation does not succeed the plugin directory is not damaged under the assumption that mv is atomic. If another plugin upgrade/install command is issued and a directory in download still exists or two plugin version directories exist in `/store//`, krew assumes that the previous operation failed. Krew informs the user and retries to reinstall the package. On Windows it is not possible to modify a file/directory which is currently in use. This requires a special case for upgrading krew, which itself is a plugin, from krew. If krew upgrades itself, it is installing itself, instead of deleting the whole old directory it just deletes the old `/commands/` directory witch holds all the plugin descriptor files. This way only the new krew version is executed. If krew upgrade is executed again the old version directory gets deleted. --- ## File: docs/RELEASING_KREW.md # Releasing Krew (This document is intended for maintainers of Krew only.) ### Build/Test the release locally 1. Build krew release assets locally: hack/make-all.sh 2. Try krew installation on each platform: ```sh krew=out/bin/krew-darwin_amd64 # assuming macOS amd64 for osarch in darwin_amd64 darwin_arm64 linux_amd64 linux_arm linux_arm64 linux_ppc64le windows_amd64; do KREW_ROOT="$(mktemp -d --tmpdir krew-XXXXXXXXXX)" KREW_OS="${osarch%_*}" KREW_ARCH="${osarch#*_}" \ $krew install --manifest=out/krew.yaml --archive="out/krew-${osarch}.tar.gz" done ``` ### Release a new version Krew follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). Krew tags versions starting with `v`. Example: `v0.2.0-rc.1`. 1. **Decide on a version number:** set it to `$TAG` variable: ```sh TAG=v0.3.2-rc.1 # <- change this ``` 1. **Create a release commit:** ```sh git commit -am "Release ${TAG:?TAG required}" --allow-empty git push origin master ``` (Only repository administrators can directly push to master branch.) 1. **Wait until the build succeeds:** Wait for CI to show green for the build of the commit you just pushed to master branch. 1. **Tag the release:** git tag "${TAG:?TAG required}" 1. **Push the tag:** git push origin "${TAG:?TAG required}" 1. **Verify on Releases tab on GitHub:** Make sure `krew.yaml`, `krew.tar.gz` and other release assets show up on "Releases" tab. 1. **Make the new version available on krew index:** Get the latest `krew.yaml` from curl -LO https://github.com/kubernetes-sigs/krew/releases/download/"${TAG:?TAG required}"/krew.yaml and make a pull request to [krew-index](https://github.com/kubernetes-sigs/krew-index/) repository. This will make the plugin available to upgrade for users using older versions of krew. 1. **Update krew-index CI**: The CI tests for `krew-index` repository relies on tools from main `krew` repository, and they should use the latest version. When there's a new version, update `.github/workflows/ci.yml` in `krew-index` repo. ## Release artifacts When a tag is pushed to the repository, GitHub workflow will make a release on GitHub, and upload the release artifacts as files on the release. --- ## File: docs/USER_GUIDE.md # User Guide This page has moved from GitHub to our website: https://krew.sigs.k8s.io/docs/user-guide/