Skip to content

Commit

Permalink
feat: s/ksonnet-lib/k8s-alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
Duologic committed May 20, 2021
1 parent 61655fb commit ca78824
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 103 deletions.
15 changes: 10 additions & 5 deletions cmd/tk/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func initCmd() *cli.Command {

force := cmd.Flags().BoolP("force", "f", false, "ignore the working directory not being empty")
installK8sLibFlag := cmd.Flags().Bool("k8s", true, "set to false to skip installation of k.libsonnet")
installK8sVersion := cmd.Flags().String("k8sversion", "1.20", "set to false to skip installation of k.libsonnet")
inline := cmd.Flags().BoolP("inline", "i", false, "create an inline environment")

cmd.Run = func(cmd *cli.Command, args []string) error {
Expand Down Expand Up @@ -54,14 +55,18 @@ func initCmd() *cli.Command {
}

if *installK8sLibFlag {
if err := installK8sLib(); err != nil {
if err := installK8sLib(*installK8sVersion); err != nil {
// This is not fatal, as most of Tanka will work anyways
log.Println("Installing k.libsonnet:", err)
failed = true
}
}

fmt.Println("Directory structure set up! Remember to configure the API endpoint:\n`tk env set environments/default --server=https://127.0.0.1:6443`")
if *inline {
fmt.Println("Directory structure set up! Remember to configure the API endpoint in environments/default/main.jsonnet")
} else {
fmt.Println("Directory structure set up! Remember to configure the API endpoint:\n`tk env set environments/default --server=https://127.0.0.1:6443`")
}
if failed {
log.Println("Errors occured while initializing the project. Check the above logs for details.")
}
Expand All @@ -71,7 +76,7 @@ func initCmd() *cli.Command {
return cmd
}

func installK8sLib() error {
func installK8sLib(version string) error {
jbBinary := "jb"
if env := os.Getenv("TANKA_JB_PATH"); env != "" {
jbBinary = env
Expand All @@ -82,11 +87,11 @@ func installK8sLib() error {
}

var initialPackages = []string{
"github.com/ksonnet/ksonnet-lib/ksonnet.beta.4",
"github.com/jsonnet-libs/k8s-alpha/" + version,
"github.com/grafana/jsonnet-libs/ksonnet-util",
}

if err := writeNewFile("lib/k.libsonnet", "import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet'\n"); err != nil {
if err := writeNewFile("lib/k.libsonnet", "import 'github.com/jsonnet-libs/k8s-alpha/"+version+"/main.libsonnet'\n"); err != nil {
return err
}

Expand Down
15 changes: 8 additions & 7 deletions docs/docs/directory-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ Tanka uses the following directories and special files:
├── jsonnetfile.json # direct dependencies
├── jsonnetfile.lock.json # all dependencies with exact versions
├── lib # libraries for this project only
│   └── k.libsonnet # alias file for vendor/github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet
│   └── k.libsonnet # alias file for vendor/github.com/jsonnet-libs/k8s-alpha/1.21/main.libsonnet
└── vendor # external libraries installed using jb
├── github.com
│   ├── grafana
│   │   └── jsonnet-libs
│   │   └── ksonnet-util # Grafana Labs' usability extensions to k.libsonnet
│   │   ├── ...
│   │   └── kausal.libsonnet
│   └── ksonnet
│   └── ksonnet-lib
│   └── ksonnet.beta.4 # kubernetes library
│   ├── k8s.libsonnet
│   └── k.libsonnet
├── ksonnet.beta.4 -> github.com/ksonnet/ksonnet-lib/ksonnet.beta.4
│   └── jsonnet-libs
│   └── k8s-alpha
│   └── 1.21 # kubernetes library
│   ├── ...
│   └── main.libsonnet
├── 1.21 -> github.com/jsonnet-libs/k8s-alpha/1.21
└── ksonnet-util -> github.com/grafana/jsonnet-libs/ksonnet-util
```

Expand Down
17 changes: 7 additions & 10 deletions docs/docs/known-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,26 @@ Below is a list of common errors and how to address them.

When migrating from `ksonnet`, this error might occur, because Tanka does not
provide the global `__ksonnet` variable, nor does it strictly have the concept
of components.
of components.
You will need to use the plain Jsonnet `import` feature instead. Note that this
requires your code to be inside of one of the
[import paths](directory-structure/#import-paths).

### Evaluating jsonnet: RUNTIME ERROR: couldn't open import "k.libsonnet": no match locally or in the Jsonnet library paths

This error can occur when the `ksonnet` kubernetes libraries are missing in the
import paths. While `ksonnet` used to magically include them, Tanka follows a
This error can occur when the `k8s-alpha` kubernetes libraries are missing in the
import paths. While `k8s-alpha` used to magically include them, Tanka follows a
more explicit approach and requires you to install them using `jb`:

```bash
$ jb install github.com/ksonnet/ksonnet-lib/ksonnet.beta.4
$ echo "import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet'" > lib/k.libsonnet
$ jb install github.com/jsonnet-libs/k8s-alpha/1.21
$ echo "import 'github.com/jsonnet-libs/k8s-alpha/1.21/main.libsonnet'" > lib/k.libsonnet
```

This does 2 things:

1) It installs the ksonnet library (in `vendor/github.com/ksonnet/ksonnet-lib/ksonnet.beta.4`).
If you need a specific version, take a look at
https://github.com/ksonnet/ksonnet-lib. When a pre-compiled version is
available, install it using `jb`, otherwise compile it yourself and place it
under `lib/`.
1) It installs the `k8s-alpha` library (in `vendor/github.com/jsonnet-libs/k8s-alpha/1.21/`).
You can replace the `1.21` matching the Kubernetes version you want to run against.

2) It makes an alias for libraries importing `k.libsonnet` directly. See
https://tanka.dev/tutorial/k-lib#aliasing for the alias rationale.
Expand Down
107 changes: 58 additions & 49 deletions docs/docs/tutorial/k-lib.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,56 @@ Writing and maintaining such a library could be a full-time job on it's own.
Luckily, it is possible to generate such a library from the Kubernetes OpenAPI
specification! Even better, it has already been done for you.

## k.libsonnet
## k8s-alpha

The library is called `k.libsonnet` (sometimes also `ksonnet-lib`), currently
available at https://github.com/ksonnet/ksonnet-lib.
The library is called `k8s-alpha` (replacing the discontinued `ksonnet-lib`),
currently available at https://github.com/jsonnet-libs/k8s-alpha.

> **Note**: Being part of the discontinued `ksonnet` project, the library is not
> really maintained at the moment. However, Grafana Labs will soon pick this up and
> take care of it :D
> Nevertheless, it has already proven to be stable enough for our own production
> setup to rely on it.
> **Note**: The `ksonnet` project has been abandoned, the library is not maintained
> anymore. However, the community backed by Grafana Labs has picked up on this with
> the `k8s-alpha` library.
However while using it internally we have discovered that the exposed API has
several annoyances. To address them, we developed another library that builds on
top of the generated one but improves the developer experience:
As `k8s-alpha` has broken compatibility in a few places with `ksonnet-lib` (for good
reason), we have instrumented the widely used `ksonnet-util` library with a
compatibility layer to improve the developer and user experience:
https://github.com/grafana/jsonnet-libs/tree/master/ksonnet-util

If you do not have any strong reasons against it, just adopt the wrapper as
well, it will ease your work. Ultimately, we hope to integrate our enhancements
in the original library as well.
well, it will ease your work. Many of the original `ksonnet-util` enhancements
have already made their way into `k8s-alpha`.

The docs for `k8s-alpha` library can be found here:
https://jsonnet-libs.github.io/k8s-alpha/

## Installation

Like every other external library, `ksonnet-lib` can be installed using
`jsonnet-bundler`.
Like every other external library, `k8s-alpha` can be installed using
`jsonnet-bundler`.
However, Tanka already **did this for you** during [project
creation (`tk init`)](/tutorial/jsonnet#creating-a-new-project):

```bash
$ tk init
└─ jb install github.com/ksonnet/ksonnet-lib/ksonnet.beta.4 github.com/grafana/jsonnet-libs/ksonnet-util
└─ jb install github.com/jsonnet-libs/k8s-alpha/1.21 github.com/grafana/jsonnet-libs/ksonnet-util

```

This created the following files in `/vendor`:
This created the following structure in `/vendor`:

```bash
vendor
├── github.com
│   ├── grafana
│   │   └── jsonnet-libs
│   │   └── ksonnet-util
│   │   ├── ...
│   │   └── kausal.libsonnet # Grafana's wrapper
│   └── ksonnet
│   └── ksonnet-lib
│   └── ksonnet.beta.4
│   ├── k8s.libsonnet # literally the entire API as a library. Very huge file
│   └── k.libsonnet # human friendly wrapper (this is what we use in our code)
├── ksonnet.beta.4 -> github.com/ksonnet/ksonnet-lib/ksonnet.beta.4
│   └── jsonnet-libs
│   └── k8s-alpha
│   └── 1.21
│   ├── ...
│   └── main.libsonnet # k8s-alpha entrypoint
├── 1.21 -> github.com/jsonnet-libs/k8s-alpha/1.21
└── ksonnet-util -> github.com/grafana/jsonnet-libs/ksonnet-util
```

Expand All @@ -70,44 +73,47 @@ vendor
> for more information.
#### Aliasing
Because of how `jb` works, the library can be imported as `github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet`.
Most external libraries (including our wrapper) expect it as a simple `k.libsonnet` (without
Because of how `jb` works, the library can be imported as
`github.com/jsonnet-libs/k8s-alpha/1.21/main.libsonnet`. Most external
libraries (including our wrapper) expect it as a simple `k.libsonnet` (without
the package prefix).

To support both, Tanka automatically created an alias file for you: `/lib/k.libsonnet` that just imports actual library, exposing it under this alternative name as well.
To support both, Tanka automatically created an alias file for you:
`/lib/k.libsonnet` that just imports actual library, exposing it under this
alternative name as well.

> **More information**:
> This works, because `import` behaves like copy-pasting. So
> the contents of `ksonnet.beta.4` are "copied" into our new file, making them
> behave exactly the same.
> **More information**:
> This works, because `import` behaves like copy-pasting. So the contents of
> `k8s-alpha/1.21` are "copied" into our new file, making them behave exactly the
> same.
## Using it

First we need to import it in `main.jsonnet`:

```diff
- (import "kubernetes.libsonnet") +
+ (import "github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet") +
(import "grafana.jsonnet") +
(import "prometheus.jsonnet") +
- local k = import "kubernetes.libsonnet";
+ local k = import "github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet";
local grafana import "grafana.jsonnet";
local prometheus = import "prometheus.jsonnet";
{ /* ... */ }
```

> **Note**: `kausal.libsonnet` imports literal `k.libsonnet`, so
> [aliasing](#aliasing) is a must here. This works, because `/lib` and `/vendor`
> are automatically searched for libraries, and `k.libsonnet` can be found in
> `/lib` due to aforementioned aliasing.
> **Note**: `ksonnet-util` imports literal `k.libsonnet`, so [aliasing](#aliasing) is
> a must here. This works, because `/lib` and `/vendor` are automatically searched
> for libraries, and `k.libsonnet` can be found in `/lib` due to aforementioned
> aliasing.
Now that we have installed the correct version, let's use it in
`/environments/default/grafana.jsonnet` instead of our own helper:

```jsonnet
{
// use locals to extract the parts we need
local deploy = $.apps.v1.deployment,
local container = $.core.v1.container,
local port = $.core.v1.containerPort,
local service = $.core.v1.service,
local deploy = k.apps.v1.deployment,
local container = k.core.v1.container,
local port = k.core.v1.containerPort,
local service = k.core.v1.service,
// defining the objects:
grafana: {
// deployment constructor: name, replicas, containers
Expand All @@ -134,7 +140,8 @@ merge it all back into a single file (`main.jsonnet`) and take a look at the
whole picture:

```jsonnet
(import "ksonnet-util/kausal.libsonnet") +
local k = import "ksonnet-util/kausal.libsonnet";
{
_config:: {
grafana: {
Expand All @@ -147,10 +154,10 @@ whole picture:
}
},
local deployment = $.apps.v1.deployment,
local container = $.core.v1.container,
local port = $.core.v1.containerPort,
local service = $.core.v1.service,
local deployment = k.apps.v1.deployment,
local container = k.core.v1.container,
local port = k.core.v1.containerPort,
local service = k.core.v1.service,
prometheus: {
deployment: deployment.new(
Expand All @@ -160,7 +167,7 @@ whole picture:
+ container.withPorts([port.new("api", $._config.prometheus.port)]),
],
),
service: $.util.serviceFor(self.deployment),
service: k.util.serviceFor(self.deployment),
},
grafana: {
deployment: deployment.new(
Expand All @@ -170,7 +177,9 @@ whole picture:
+ container.withPorts([port.new("ui", $._config.grafana.port)]),
],
),
service: $.util.serviceFor(self.deployment) + service.mixin.spec.withType("NodePort"),
service:
k.util.serviceFor(self.deployment)
+ service.mixin.spec.withType("NodePort"),
},
}
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
(import "ksonnet-util/kausal.libsonnet") +
(import "prom-grafana/prom-grafana.libsonnet")
import 'prom-grafana/prom-grafana.libsonnet'
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
(import "ksonnet-util/kausal.libsonnet") +
(import "prom-grafana/prom-grafana.libsonnet") +
(import 'prom-grafana/prom-grafana.libsonnet') +
{
promgrafana+: {
prometheus+: {
deployment+: {
metadata+: {
labels+: {
foo: "bar"
}
}
}
}
}
foo: 'bar',
},
},
},
},
},
}
14 changes: 11 additions & 3 deletions examples/prom-grafana/jsonnetfile.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{
"source": {
"git": {
"remote": "https://github.com/grafana/jsonnet-libs",
"remote": "https://github.com/grafana/jsonnet-libs.git",
"subdir": "ksonnet-util"
}
},
Expand All @@ -13,11 +13,19 @@
{
"source": {
"git": {
"remote": "https://github.com/ksonnet/ksonnet-lib",
"subdir": "ksonnet.beta.4"
"remote": "https://github.com/jsonnet-libs/k8s-alpha.git",
"subdir": "1.21"
}
},
"version": "master"
},
{
"source": {
"local": {
"directory": "vendor"
}
},
"version": ""
}
],
"legacyImports": true
Expand Down
Loading

0 comments on commit ca78824

Please sign in to comment.