Skip to content

Commit

Permalink
Start Trunk OCI post
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Jun 20, 2024
1 parent 17d5175 commit 10a9620
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions content/post/postgres/trunk-oci-poc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: "POC: Distributing Trunk Binaries via OCI"
slug: trunk-oci-poc
date: 2024-06-20T20:41:47Z
lastMod: 2024-06-20T20:41:47Z
description: |
Would it be possible to distribute Postgres extension binaries via Open
Container Registries? Tune in to find out!
tags: [Postgres, PGXN, Trunk, POC, OCI]
type: post
---

A couple months ago, Álvaro Hernández [suggested] that Postgres extensions
should be distributed as OCI (née Docker) images:

> It’s all about not reinventing the wheel, and leveraging the ecosystem
> around OCI. Many of the problems (solutions) in building, packaging and
> distributing extensions are already solved by OCI: there’s a whole ecosystem
> of tools around OCI that provide additional benefits in terms of tooling,
> infrastructure and common knowledge.
As a relatively experienced Docker image builder and distributor, I found this
idea intriguing. I hadn't been familiar with the [OCI Image Manifest
Specification], which defines how to build OCI images containing arbitrary
files. But if we could adopt an existing protocol and federated registry
system like OCI/Docker it seems like it'd save pretty significant development
time building our own, plus be adopting and potentially contributing to a
standard.

After PGConf.dev, I decided to see if I could work out how to distribute
[trunk packages][trunk] in such a way that an OCI/Docker-style image URL could be
used to install a version of an extension compiled for the appropriate
architecture.

Thanks to the denizens of the `#oras` and `#zot` channels on the [CNCF Slack],
I extended the [trunk format POC][trunk] in [pg-semver PR 69] to build the
necessary JSON manifest files, push them to a registry, and then pull and
install the` architecturally-appropriate package. Here's how it works.

## Metadata generation

First, I extended [`trunk.mk`], which [builds a trunk package][trunk], with a
few more targets that create JSON files with metadata necessary to build OCI
manifests. The files that `make trunk` now also generates are:

`semver_annotations.json`
: OCI standard annotations describing a package, including license, vendor,
and URLs. Example:

``` json
{
"org.opencontainers.image.created": "2024-06-20T18:07:24Z",
"org.opencontainers.image.licenses": "PostgreSQL",
"org.opencontainers.image.title": "semver",
"org.opencontainers.image.description": "A Postgres data type for the Semantic Version format with support for btree and hash indexing.",
"org.opencontainers.image.source": "https://github.com/theory/pg-semver",
"org.opencontainers.image.vendor": "PGXN",
"org.opencontainers.image.ref.name": "0.32.1",
"org.opencontainers.image.version": "0.32.1",
"org.opencontainers.image.url": "https://github.com/theory/pg-semver"
}
```

`semver-0.32.1+pg16-darwin-23.5.0-arm64_config.json`
: An object with fields appropriate for OCI platform specification, plus
the creation date. An example:

```json
{
"os": "darwin",
"os.version": "23.5.0",
"architecture": "arm64",
"created": "2024-06-20T18:07:24Z"
}
```

`semver-0.32.1+pg16-darwin-23.5.0-arm64_annotations.json`
: An object defining annotations to use in an image, built for a specific
platform, all under a key to be used later by the [ORAS] CLI to put them
in the right place. Example:

```json
{
"$manifest": {
"org.opencontainers.image.created": "2024-06-20T18:07:24Z",
"org.opencontainers.image.title": "semver-0.32.1+pg16-darwin-23.5.0-arm64.trunk",
"org.opencontainers.image.licenses": "PostgreSQL",
"org.opencontainers.image.description": "A Postgres data type for the Semantic Version format with support for btree and hash indexing.",
"org.opencontainers.image.source": "https://github.com/theory/pg-semver",
"org.opencontainers.image.vendor": "PGXN",
"org.opencontainers.image.ref.name": "0.32.1",
"org.opencontainers.image.version": "0.32.1",
"org.opencontainers.image.url": "https://github.com/theory/pg-semver",
"org.pgxn.trunk.pg.version": "16.3",
"org.pgxn.trunk.pg.major": "16",
"org.pgxn.trunk.pg.version_num": "160003",
"org.pgxn.trunk.version": "0.1.0"
}
}
```

The `org.opencontainers.image` keys are the same as in
`semver_annotations.json`, the new `org.pgxn.trunk` annotations are
intended to be used to grab the image appropriate for the version of
Postgres, although that functionality isn't part of this POC.


[suggested]: https://www.ongres.com/blog/why-postgres-extensions-should-be-distributed-and-packaged-as-oci-images/
"Álvaro Hernández: Why Postgres Extensions should be packaged and distributed as OCI images"
[OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md
[trunk]: {{% ref "/post/postgres/trunk-poc" %}} "POC: PGXN Binary Distribution Format"
[CNCF Slack]: https://communityinviter.com/apps/cloud-native/cncf
[pg-semver PR 69]: https://github.com/theory/pg-semver/pull/69
"theory/pg-semver#69: POC pushing & pulling trunk from an OSI registry"
[ORAS]: https://oras.land "Distribute Artifacts Across OCI Registries With Ease"

0 comments on commit 10a9620

Please sign in to comment.