Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/cbodonnell/airgap-oci


https://github.com/cbodonnell/airgap-oci

Last synced: 22 days ago
JSON representation

Awesome Lists containing this project

README

        

# Airgap Bundles as OCI Artifacts

This repo contains resources from initial investigations into how airgap bundles can be stored as OCI artifacts.

## Dependencies

[docker](https://docs.docker.com/get-docker/) - used to run a local registries in this example.

[oras](https://github.com/oras-project/oras) - an OCI client for managing content like artifacts, images, packages. It can be used to create an OCI artifact from a directory of files.

[crane](https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md) - a tool for interacting with remote images and registries. It can be used to copy images from one registry to another.

[go](https://golang.org/doc/install) (optional) - used to generate the `scripts/artifact.sh` script.

## Creating an Airgap Bundle OCI artifact

Today, an airgap bundle consists of three main components:
* `airgap.yaml` - airgap metadata
* `app.tar.gz` - application bundle (kubernetes manifests, helm charts, etc.)
* `images` - directory containing a registry of images

In this example, we will assume we already have the `airgap.yaml` and `app.tar.gz` files and we will use `crane` to copy the images from a remote registry to a temporary local registry to use for the bundle.

### Create a local registry

Start a local registry on port 5000 and store the registry data in the `bundle/images` directory.

```bash
docker run -d -p 5000:5000 -v $(PWD)/bundle/images:/var/lib/registry --name bundle-registry registry:2
```

### Copy images to the local registry

We're copying two images in this example to demonstrate deduplication of layers.

```bash
crane cp docker.io/library/postgres:15.5-alpine localhost:5000/postgres:15.5-alpine
crane cp docker.io/library/postgres:16.1-alpine localhost:5000/postgres:16.1-alpine
```

Once the above commands complete successfully, we can stop the local registry:

```bash
docker rm -f bundle-registry
```

At this point the `bundle/images` directory contains the image data for the airgap bundle.

### Create an OCI artifact

In this step we'll start up another registry on port 5001. In practice, this could be any registry where airgap bundles will be stored.

```bash
docker run -d -p 5001:5000 -v $(PWD)/bundle/images:/var/lib/registry --name storage-registry registry:2
```

It's not necessary to login to the registry in this example, but if it was required, it could be done with the following command:

```bash
oras login localhost:5001 -u $USERNAME -p $PASSWORD
```

The `scripts/artifact.sh` script uses `oras push` to create an OCI artifact that has a custom artifact type of `application/vnd.airgap.bundle` (take a look at the script and the [oras docs](https://oras.land/docs/commands/oras_push) for more details). This artifact will have layers for the metadata, application bundle, and images. Each image blob will be stored as separate layer in the artifact to leverage the deduplication of the OCI format. This script can be regenerated by running `go run ./cmd/script/main.go`, if necessary.

```bash
./scripts/artifact.sh
```

To fetch the manifest for the uploaded artifact, run:

```bash
oras manifest fetch localhost:5001/my-company/airgap-bundle:v1
```

## Downloading an Airgap Bundle OCI artifact

This section provides an example of how an end-user could download an airgap bundle OCI artifact.

### Pulling an artifact

For this example, let's go to a clean working directory:

```bash
cd $(mktemp -d)
```

As before, it's not necessary to login to the registry in this example, but if it was required, it could be done with the following command:

```bash
oras login localhost:5001 -u $USERNAME -p $PASSWORD
```

We can set the location of the oras cache if desired. This is useful if we need to download the same or similar artifacts multiple times.

```bash
export ORAS_CACHE=~/.oras/cache
```

To download an artifact, run:

```bash
oras pull localhost:5001/my-company/airgap-bundle:v1
```

This will download the artifact to the current directory. The `bundle` directory will contain all of the files that make up the airgap bundle, including the `airgap.yaml` and `app.tar.gz` files, as well as the `images` directory containing the image registry data.

For easier transport, the `bundle` directory can be tarred and gzipped:

```bash
tar -czvf airgap-bundle.tar.gz bundle
```

### Checksums

An OCI image has a manifest that contains a list of layers. Each layer has a digest that is a checksum of the layer's contents. The manifest also has a digest that is a checksum of the manifest's contents. The manifest digest is used to reference the image. OCI clients use these digests to verify the integrity of the image.

*The following manual steps are not necessary in practice, but are included here for demonstration purposes.*

To compute digest of the manifest, run:

```bash
oras manifest fetch localhost:5001/my-company/airgap-bundle:v1 | shasum -a 256
```

To pull an artifact using the manifest digest, run:

```bash
oras pull localhost:5001/my-company/airgap-bundle@sha256:${SHA256SUM}
```

If desired, checksums of the files returned can be validated against the checksums of the layers in the manifest:

```bash
shasum -a 256 bundle/airgap.yaml
shasum -a 256 bundle/app.tar.gz
shasum -a 256 bundle/images/docker/registry/v2/blobs/sha256/*/*/data
```

## Additional Resources

* https://github.com/opencontainers/image-spec/blob/main/manifest.md#guidelines-for-artifact-usage
* https://oras.land/docs/
* https://www.youtube.com/watch?v=XbUAPlZi0x0
* https://dlorenc.medium.com/oci-artifacts-explained-8f4a77945c13
* https://explore.ggcr.dev/