Skip to main content

How to add a Package to Glasskube

As of the end of June 2024 Glasskube is now officially the second most popular Package mananger for Kubernetes (by measure of GitHub stars) behind Helm. This is a huge achievement for us, and don’t get me wrong we are humbled and hugely appreciative to the community for all the adoption, feedback and usage.

But there is an elephant in the room.

As a user, you will only adopt a new package manager if it supports the packages you use and if it is easier to use than the alternatives.

As a small team, we are doing our best to support new packages every week. But there are other features and expansions we have planned in the upcoming roadmap that don’t allow us to add new packages to the Glasskube catalogue at a fast enough pace. Luckily, adding new packages to Glasskube is surprisingly straightforward. Through this guide I want to show you just how easily you can add your own packages, both to the Public Glasskube package repo or to your own private repo.

In this guide we will learn how to add a Package by integrating the Argo Workflows controller.

Prerequisites

Install Glasskube

If you already installed glasskube you can skip this step. If not, glasskube can easily be installed the way you usually install packages for your operating system.

On macOS, you can use Homebrew to install and update Glasskube.

brew install glasskube/tap/glasskube

After installing Glasskube on your local machine, make sure to install the necessary components in your Kubernetes cluster by running glasskube bootstrap. For more information, check out our bootstrap guide.

What is Glasskube? 🧊

Glasskube is an Open Source package manager for Kubernetes. It makes deploying, updating, and configuring packages on Kubernetes 20 times faster than tools like Helm or Kustomize by simplifying package configuration options and prioritising package maintainability and automation. Inspired by the simplicity of Homebrew and npm, you can decide if you want to use the Glasskube UI, CLI, or directly deploy packages via GitOps.

Glasskube deploys packages that are defined in package definition repositories. When you install Glasskube for the first time you can see the default configured package repo by running:

glasskube repo list

This is the URL for the public Glasskube package repo which comes configured by default:

NAME       URL                                         DEFAULT  AUTHENTICATION  STATUS  MESSAGE
glasskube https://packages.dl.glasskube.dev/packages Yes None Ready repo has 16 packages

Find the repo here.

If you would like us to add a package to the official catalogue, open an issue here.

To add a new package to the Glasskube package repo you can open a PR (please open an issue first) or create your own package repository and add it as an alternative package backend.

Glasskube components diagram

Glasskube consists of distinct client-side and server-side components:

Client-side:

  • UI
  • CLI

Server-side:

  • PackageInfoController: reads the package definitions files from the configured repositories and has a reconciliation process to apply any changes to the repos.
  • PackageController: reconciles with KubernetesAPI and PackageInfoController to compare the state of in-cluster packages and deploy the desired package changes.
  • PackageRepositoryController: reconciles the configured repositories.

Package definition repositories

argo-workflow-gif

Package repository structure 🏗️

Link to more in depth repository structure documentation

package-repo-structure

Level 0

  • Root packages folder: where all packages definition files can be found

Level 1

  • Folder per package
  • index.yaml File which holds important information about each package (updated automatically during CI but manually during testing)

Level 2

  • Folder per package version
  • versions.yaml File containing reference to all available versions as well as the reference to the latest package version

Level 3

  • package.yaml file where the package definition for a certain package version is found

Understanding the Package Definition file

1. Basic Structure

Your package definition file follows a specific schema. The schema ensures your file has the correct structure and required fields. Below is an outline of the sections you’ll need to configure:

  • name: The name of your package.
  • scope: Specifies if the package is cluster-wide (Cluster) or limited to a namespace (Namespaced).
  • shortDescription: A brief description of the package.
  • longDescription: A detailed description of the package.
  • iconUrl: URL of an icon representing the package.
name: my-package
scope: Cluster
shortDescription: A short description of the package
longDescription: |
# Markdown syntax is also supported here
A longer description to be displayed in the UI
iconUrl: https://avatars.githubusercontent.com/u/<iconNumber>

2. Helm Manifest (Optional)

If your package references a Helm chart, include the helm section:

  • chartName: The name of the Helm chart.
  • chartVersion: The version of the Helm chart.
  • repositoryUrl: URL of the Helm chart repository.
  • values: Optional. Hardcode specific values for the Helm chart.
helm:
chartName: my-chart
chartVersion: <version>
repositoryUrl: https://helm.repo.url
values:
serviceAccount:
name: my-service-account

3. Kubernetes Manifest (Optional)

If your package references Kubernetes manifests, include the manifests section:

  • url: URL to the Kubernetes manifest file.

Example:

manifests:
- url: https://k8s.manifest.url

4. Value Definitions (Optional)

Link to the official package config documentation

Use the valueDefinitions section for interactive package configuration. This allows users to input values that modify the package configuration.

  • metadata: Description of the value.
  • type: Type of the value (e.g. text).
  • targets: Specifies where to apply the value in the Helm chart, use the add operation under patch to inject data to the values file.
valueDefinitions:
automaticHTTPS:
metadata:
description: Add your email address for automatic HTTPS - "your@email.com"
type: text
targets:
- chartName: chartName
patch:
op: add
path: /ingressController/config/email

5. Values (Optional)

In case you want to hard code or create paths that are empty in the base values file.

An example of hard coding values:

  values:
serviceAccount:
name: my-service-account

A current limitation of value definitions is that they can only patch helm values in existing paths, in like the caddy-ingress-controller we instantiate them like so:

  values:
ingressController:
config: {}

6. References (Optional)

Add references to external resources related to your package.

  • label: Descriptive label for the reference.
  • url: URL of the reference.
references:
- label: ArtifactHub
url: https://artifacthub.url

7. Entrypoints (Optional)

Define entrypoints if your package includes a frontend component.

  • serviceName: The name of the service.
  • port: The service port.
  • localPort: The local port for accessing the service.
  • name: Name of the entry point.
entrypoints:
- serviceName: my-service
port: 80
localPort: 8030
name: ui

Complete example template

# yaml-language-server: $schema=https://glasskube.dev/schemas/v1/package-manifest.json

name: my-package
scope: Cluster
shortDescription: A short description of the package
longDescription: |
A longer description to be displayed in the UI
iconUrl: https://avatars.githubusercontent.com/u/12345678

helm:
chartName: my-chart
chartVersion: <version>
repositoryUrl: https://helm.repo.url
values:
serviceAccount:
name: my-service-account
ingressController:
config: {}

manifests:
- url: https://k8s.manifest.url

valueDefinitions:
automaticHTTPS:
metadata:
description: Add your email address for automatic HTTPS - "your@email.com"
type: text
targets:
- chartName: chartName
patch:
op: add
path: /ingressController/config/email

references:
- label: ArtifactHub
url: https://artifacthub.url

entrypoints:
- serviceName: my-service
port: 80
localPort: 8030
name: ui

Pre-integration checklist ✅

Questions you should ask yourself before integrating a new package:

  1. Is the package Cluster or Namespace scoped?
  • Cluster scoped: Installed once in a cluster can be accesses from other namespaces.
  • Namespaces scoped: Can be installed multiple times per cluster, logically isolated per namespace
  1. Will the package reference a Helm chart or Kubernetes manifest?

  2. Will the package require an entrypoint configuration, if so which ports need to be accessible?

  3. Will the package require custom value definitions, if so which ones?

  4. Which URL references will be included?

Let’s integrate Argo Workflows

The best way to learn is by doing so lets integrate a new package. We have already integrated the ArgoCD operator so let’s add the Argo workflows controller too.

Pre-integration checklist for Argo Workflows

  1. Is the package Cluster or Namespace scoped?

    • Cluster scoped
  2. Will the package reference a Helm chart or Kubernetes manifest?

    • In the documentation we can see that both the manifest and a helm chart are available
    • To keep consistent with the ArgoCD operator previously installed, I will use the Kubernetes manifest
  3. Will the package require an entrypoints configuration, if so which ports need to be accessible?

    • Yes:
      • Port: 2746
      • LocalPort: 2746
  4. Will the package require custom value definitions, if so which ones?

    • No
  5. Which URL references will be included?

Step 1: Fork the packages repo

Fork the official packages repo and create a new branch.

git checkout -b add-argo-workflows-support

Step 2: Create a package.yaml file and versions.yaml

Using the repo structure inside the packages folder, add create the argo-workflows folder. Find the version of argo-workflows and create the version folder as well as the versions file. Lastly create the

packages/
└── argo-workflows/
├── versions.yaml
└── v3.5.8+1/
└── package.yaml

package.yaml file

# yaml-language-server: $schema=https://glasskube.dev/schemas/v1/package-manifest.json
name: argo-workflows
shortDescription: Kubernetes-native workflow engine supporting DAG and step-based workflows.
defaultNamespace: argo
iconUrl: https://avatars.githubusercontent.com/u/30269780
manifests:
- url: https://github.com/argoproj/argo-workflows/releases/download/v3.5.8/install.yaml
references:
- label: Github
url: https://github.com/argoproj/argo-workflows
- label: Website
url: https://argoproj.github.io/workflows/

versions.yaml file

latestVersion: "v3.5.8+1"
versions:
- version: "v3.5.8+1"

Step 3: Add the package to the index.yaml file

In the root of the /packages folder you will find an index.yaml file that needs to be updated manually while testing but left unchanged when you open a PR again the public Glasskube repo since this file is automatically updated.

  - iconUrl: https://avatars.githubusercontent.com/u/30269780
latestVersion: v3.5.8+1
name: argo-workflows
shortDescription: Kubernetes-native workflow engine supporting DAG and step-based workflows

Step 4: Commit these new changes to your local branch

git add .
git commit -m "feat(argo-workflow): initial argo-workflow support"
git push origin add-argo-workflows-support

Step 5: Add the repo to your local Glasskube backend

For testing locally, reference the testing guidelines.

To test the package configuration use glasskube repo add to configure your test repository.

glasskube repo add argo-workflows https://raw.githubusercontent.com/jakepage91/packages/add-argo-workflows-support/packages/

Use the raw GitHub url, so Glasskube doesn’t need to translate the html to yaml

View locally configured repositories:

glasskube repo list

Expected output:

NAME            URL                                                                                         DEFAULT  AUTHENTICATION  STATUS  MESSAGE
argo-workflows https://raw.githubusercontent.com/jakepage91/packages/add-argo-workflows-support/packages/ No None Ready repo has 17 packages
glasskube https://packages.dl.glasskube.dev/packages

Step 6: Test the package installation

Please note that any changes made to your package repository will not be picked up immediately. To ensure all caches are cleared, either wait 5 minutes or restart both the operator and the UI. This is a known issue that will be addressed in a future version.

glasskube serve

Opens on https://localhost:8580

argo-workflows-on-glasskube

Once installed check to see if the pods are ready:

kubectl get pods -n argo

Output:

NAME                                   READY   STATUS    RESTARTS   AGE
argo-server-69f4d5846b-s2dj4 1/1 Running 0 2m37s
workflow-controller-66fd69c457-xnr4p 1/1 Running 0 2m37s

Extra step only required if your package includes custom value definitions

The glasskube/packages repo runs a series of CI checks to make sure the code is compliant and that it works. If the package has custom value definitions you will need to include a config-values.txt file inside a .test folder for the test job to pick up and run.

Example config-values.txt file:

--value "firstValue=false" --value "anotherDefinedValueDefinition="

Updated folder structure:

packages/
└── argo-workflows/
├── versions.yaml
└── v3.5.8+1/
├── .test/
│ └── config-values.txt
└── package.yaml

Step 7: Open a PR against the glasskube/pagages repo

Make sure to follow the contributing guidelines and use the following commit message struture

git commit -S -m "feat(<NameOfPackage>: commit-message)"

If you like this sort of content and would like to see more of it, please consider supporting us by giving us a Star on GitHub 🙏 cats-like--github-stars