---
# System prepended metadata

title: kctrl -  Package Helm Chart from Git Repository
tags: [kctrl]

---

# kctrl -  Package Helm Chart from Git Repository

###### tags: `kctrl`

## Packaging Helm Chart from Git Repository

In this tutorial, we will see how to package an helm chart from a helm repo. We will use [MongoDb enterprise operator](https://github.com/mongodb/helm-charts/tree/main/charts/enterprise-operator) as an example here.

### Prerequisites

1. Install Carvel tools - [imgpkg](https://carvel.dev/imgpkg/docs/latest/install/), [kapp](https://carvel.dev/kapp/docs/latest/install/), [kbld](https://carvel.dev/kbld/docs/latest/install/), [vendir](https://carvel.dev/vendir/docs/latest/install/), [ytt](https://carvel.dev/ytt/docs/latest/install/).
2. Identify helm chart and helm repo. [`MongoDb enterprise operator`](https://github.com/mongodb/mongodb-enterprise-kubernetes) is available in this [`repo`](https://mongodb.github.io/helm-charts/) with chart name as [`enterprise-operator`](https://github.com/mongodb/helm-charts/tree/main/charts/enterprise-operator) and is managed by `mongodb` itself. We will package this helm chart and make it available for distribution.
3. Kubernetes cluster (I will be using [minikube](https://minikube.sigs.k8s.io/docs/)).
4. OCI registry where the package bundle and repository bundles will be pushed (I will be using my [Docker Hub](https://hub.docker.com/) account).

### Initialize Package

```bash
$ mkdir tutorial-3
$ cd tutorial-3
$ kctrl pkg init
```
To initialize, we will use `kctrl pkg init`.

This command asks a few basic questions regarding how we want to initialize our package. Lets go through them together:

`> Enter the package reference name (samplepackage.corp.com):`
  * In this question, we need to enter the package name which will be a valid DNS subdomain name. We will use `mongodb.carvel.dev` as our package name.

`> Enter source (1):`
  * Here, we need to enter from where to get the Kubernetes manifest or helm chart which needs to be packaged. As mentioned earlier, we will use [`enterprise-operator`](https://github.com/mongodb/helm-charts/tree/main/charts/enterprise-operator) from this [`repo`](https://mongodb.github.io/helm-charts/). Hence, we will select Option `3`.

`> Enter helm chart repository URL ():`
  * In this, we have to enter the helm repository URL. We will enter `https://mongodb.github.io/helm-charts`.

`> Enter helm chart name ():`
  * We will use `enterprise-operator` as the chart name.

`> Enter helm chart version ():`
  * We will use `1.17.0` version.

After entering all the above details, [`vendir`](https://carvel.dev/vendir/) will download the helm chart locally into `upstream` folder. `kctrl` will generate two files - package-build.yml and pacakge-resources.yml as output. `Package-resources.yml` file contain Package, PackageInstall and PackageMetadata while `package-build.yml` contains PackageBuild. All the values entered above have been recorded in these files. These files will be used by the `dev` and `pkg release` command subsequently. 

### Release the package

`kctrl pkg release` will be used to release the package.

```bash
$ kctrl pkg release -v 1.0.0
```

This command will create an imgpkg bundle, upload it to the OCI registry, create `package.yml` and `metadata.yml` which can be released for consumption eventually. Also, we are versioning our package with `-v` flag.

`> Enter the registry URL ():`
  * Here we need to enter the registry URL where we need to push our imgpkg bundle. While entering the registry URL, ensure to change the value from `docker.io/rohitagg2020/mongodb-bundle` to `docker.io/<YOUR_DOCKERHUB_ACCOUNT>/mongodb-bundle`. Alternatively, you can enter other valid OCI registry URL.

Now, we have created our Package and PackageMetadata. 

Let's see how the Package and PackageMetadata files look like:

```bash
$ cat carvel-artifacts/packages/mongodb.carvel.dev/package.yml
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: Package
metadata:
  creationTimestamp: null
  name: mongodb.carvel.dev.1.0.0
spec:
  refName: mongodb.carvel.dev
  releasedAt: "2022-11-10T08:34:33Z"
  template:
    spec:
      deploy:
      - kapp: {}
      fetch:
      - imgpkgBundle:
          image: index.docker.io/rohitagg2020/mongodb-bundle@sha256:194e7f573a31a61653533742730143aedf62bf640d4145bf2220a6375380a36c
      template:
      - helmTemplate:
          path: upstream
      - ytt:
          paths:
          - '-'
      - kbld:
          paths:
          - '-'
          - .imgpkg/images.yml
  valuesSchema:
    openAPIv3:
      properties:
        agent:
          properties:
            name:
              default: mongodb-agent
              type: string
            version:
              default: 11.12.0.7388-1
              type: string
          type: object
        ...
      type: object
  version: 1.0.0
$ cat carvel-artifacts/packages/mongodb.carvel.dev/metadata.yml
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: PackageMetadata
metadata:
  creationTimestamp: null
  name: mongodb.carvel.dev
spec:
  displayName: mongodb
  longDescription: mongodb.carvel.dev
  shortDescription: mongodb.carvel.dev
```

Next step is to add it to package repository.

These files can be submitted to the version control tools like github, etc. so that next time while running `pkg init` or `pkg release`, these values can be picked up as default values.

### Add package to the package repository

`kctrl` can be used to release packages grouped together into a `PackageRepository`. Let’s bundle the `dynatrace` package created above into the PackageRepository.

We will reuse the package repository which was created in `tutorial-2`

`kctrl` will create a repo bundle from all the packages and metadata present in the `packages` folder. 
We will copy the `package.yml` and `metadata.yml` created above into the `packages` folder. We will follow the bundle format as mentioned [here](https://carvel.dev/kapp-controller/docs/v0.32.0/packaging-artifact-formats/#package-repository-bundle). Alternatively, while running `pkg release`, `--repo-output` flag can be used to copy the `package.yml` and `metadata.yml` in the prescribed PackageRepository bundle format at a specified location.

```bash
$ mkdir -p packages/mongodb.carvel.dev
$ cp ../tutorial-3/carvel-artifacts/packages/mongodb.carvel.dev/package.yml packages/mongodb.carvel.dev/1.0.0.yml
$ cp ../tutorial-3/carvel-artifacts/packages/mongodb.carvel.dev/metadata.yml packages/mongodb.carvel.dev/
$ tree
.
└── packages
    └── mongodb.carvel.dev
        ├── 1.0.0.yml
        └── metadata.yml
```

Now, we will run `kctrl pkg repo release` to create and release the repository bundle. This repository bundle can be distributed to the the package consumer.

```bash
$ kctrl pkg repo release -v 2.0.0
```

In this command, it will ask for package repository name and where to push our repository bundle. Also, we are versioning our package repository with `-v` flag.

`> Enter the package repository name (sample-repo.carvel.dev):`
  * We will use `demo-repo.carvel.dev` as our package repository name.

`> Enter the registry url ():`
  * All the `packages` and `metadata` yaml files present in the `packages` folder will be bundled into `imgpkg bundle` and then pushed to the above registry url. While entering the registry URL, ensure to change the value from `docker.io/rohitagg2020/demo-repo-bundle` to `docker.io/<YOUR_DOCKERHUB_ACCOUNT>/demo-repo-bundle`. Alternatively, you can enter other valid OCI registry URL.


### Test the package (Optional)

To test the package, we will again use kctrl.

First step is to add the packageRepository to the Kubernetes cluster by using `kctrl pkg repo add` command. Once the package repository is added, all the packages in that repository becomes available to install. 

Then we can install a package by using `kctrl pkg install` command.

Since package repository and package install are custom resources(CRs), we have to deploy the `kapp-controller` onto the cluster so that all these CRs become available on the cluster.

#### Install kapp controller

**_NOTE_**: In case you have already installed `kapp-controller`, skip this section.

To install, `kapp-controller`, run

```bash
$ kapp deploy -a kc -f https://github.com/vmware-tanzu/carvel-kapp-controller/releases/latest/download/release.yml
```

#### Add package repository
To add the package repo, we will run

```bash
$ kubectl create ns kctrl-test
$ kctrl pkg repo add -r demo-repo --url docker.io/rohitagg2020/demo-repo-bundle:2.0.0 -n kctrl-test
```

To list the available packages, run

```bash
$ kctrl pkg available --list -n kctrl-test
```

#### Install package 
To install the package, we will run

```bash
$ kctrl pkg install -i pkg-install-demo -p mongodb.carvel.dev -v 1.0.0 -n kctrl-test
```

#### Confirm package installed successfully
To confirm that package has been installed successfully, list down the pods and ensure that `mongodb-operator` has been deployed successfully.

`$ kubectl get pods -n kctrl-test`