RFC-0003: Introduce Flux OCI media type

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
pull/3575/head
Stefan Prodan 2 years ago
parent fa9d42d7bf
commit c093714597
No known key found for this signature in database
GPG Key ID: 3299AEB0E4085BAF

@ -4,7 +4,7 @@
**Creation date:** 2022-03-31 **Creation date:** 2022-03-31
**Last update:** 2022-09-29 **Last update:** 2023-02-10
## Summary ## Summary
@ -35,7 +35,7 @@ they do today for container images.
### Non-Goals ### Non-Goals
- Introduce a new OCI media type for artifacts containing Kubernetes manifests. - Enforce a specific OCI media type for artifacts containing Kubernetes manifests or any other configs.
## Proposal ## Proposal
@ -47,25 +47,26 @@ and push the archive to a container registry as an OCI artifact.
```sh ```sh
flux push artifact oci://docker.io/org/app-config:v1.0.0 \ flux push artifact oci://docker.io/org/app-config:v1.0.0 \
--source="$(git config --get remote.origin.url)" \ --source="$(git config --get remote.origin.url)" \
--revision="$(git branch --show-current)/$(git rev-parse HEAD)" \ --revision="$(git rev-parse HEAD)" \
--path="./deploy" --path="./deploy"
``` ```
The Flux CLI will produce artifacts of type `application/vnd.docker.distribution.manifest.v2+json` The Flux CLI will produce OCI artifacts by setting the config layer
which ensures compatibility with container registries that don't support custom OCI media types. media type to `application/vnd.cncf.flux.config.v1+json`.
The directory pointed to by `--path` is archived and compressed in the `tar+gzip` format The directory pointed to by `--path` is archived and compressed in the `tar+gzip` format
and the layer media type is set to `application/vnd.docker.image.rootfs.diff.tar.gzip`. and the layer media type is set to `application/vnd.cncf.flux.content.v1.tar+gzip`.
The source URL and revision are added to the OCI artifact as annotations in the format: The source and revision are added to the OCI artifact as Open Containers standard annotations:
```json ```json
{ {
"schemaVersion": 2, "schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json", "mediaType": "application/vnd.oci.image.manifest.v1+json",
"annotations": { "annotations": {
"source.toolkit.fluxcd.io/url": "https://github.com/org/app.git", "org.opencontainers.image.created": "2023-02-10T09:06:09Z",
"source.toolkit.fluxcd.io/revision": "main/450796ddb2ab6724ee1cc32a4be56da032d1cca0" "org.opencontainers.image.revision": "6ea3e5b4da159fcb4a1288f072d34c3315644bcc",
"org.opencontainers.image.source": "https://github.com/fluxcd/flux2"
} }
} }
``` ```
@ -136,7 +137,7 @@ which contains the tarball with Kubernetes manifests.
```yaml ```yaml
spec: spec:
layerSelector: layerSelector:
mediaType: "application/deployment.content.v1.tar+gzip" mediaType: "application/vnd.cncf.flux.content.v1.tar+gzip"
``` ```
If the layer selector matches more than one layer, If the layer selector matches more than one layer,
@ -287,7 +288,7 @@ Then push the Kubernetes manifests to GHCR:
```sh ```sh
flux push artifact oci://ghcr.io/org/my-app-config:v1.0.0 \ flux push artifact oci://ghcr.io/org/my-app-config:v1.0.0 \
--source="$(git config --get remote.origin.url)" \ --source="$(git config --get remote.origin.url)" \
--revision="$(git tag --points-at HEAD)/$(git rev-parse HEAD)"\ --revision="$(git rev-parse HEAD)"\
--path="./deploy" --path="./deploy"
``` ```
@ -308,8 +309,8 @@ List the artifacts and their metadata with:
```console ```console
$ flux list artifacts oci://ghcr.io/org/my-app-config $ flux list artifacts oci://ghcr.io/org/my-app-config
ARTIFACT DIGEST SOURCE REVISION ARTIFACT DIGEST SOURCE REVISION
ghcr.io/org/my-app-config:latest sha256:45b95019d30af335137977a369ad56e9ea9e9c75bb01afb081a629ba789b890c https://github.com/org/my-app-config.git v1.0.0/20b3a674391df53f05e59a33554973d1cbd4d549 ghcr.io/org/my-app-config:latest sha256:45b95019d30af335137977a369ad56e9ea9e9c75bb01afb081a629ba789b890c https://github.com/org/my-app-config.git 20b3a674391df53f05e59a33554973d1cbd4d549
ghcr.io/org/my-app-config:v1.0.0 sha256:45b95019d30af335137977a369ad56e9ea9e9c75bb01afb081a629ba789b890c https://github.com/org/my-app-config.git v1.0.0/3f45e72f0d3457e91e3c530c346d86969f9f4034 ghcr.io/org/my-app-config:v1.0.0 sha256:45b95019d30af335137977a369ad56e9ea9e9c75bb01afb081a629ba789b890c https://github.com/org/my-app-config.git 3f45e72f0d3457e91e3c530c346d86969f9f4034
``` ```
#### Story 2 #### Story 2
@ -372,45 +373,37 @@ spec:
timeout: 2m timeout: 2m
``` ```
### Alternatives
An alternative solution is to introduce an OCI artifact type especially made for Kubernetes configuration.
That is considered unpractical, as introducing an OCI type has to go through the
IANA process and Flux is not the owner of those type as Helm is for Helm artifact for example.
## Design Details ## Design Details
Both the Flux CLI and source-controller will use the [go-containerregistry](https://github.com/google/go-containerregistry) The Flux controllers and CLI will use the [fluxcd/pkg/oci](https://github.com/fluxcd/pkg/tree/main/oci)
library for OCI operations such as push, pull, tag, list tags, etc. library for OCI operations such as push, pull, tag, list tags, etc.
For authentication purposes, the `flux <verb> artifact` commands will use the `~/.docker/config.json` For authentication purposes, the `flux <verb> artifact` commands will use the `~/.docker/config.json`
config file and the Docker credential helpers. config file and the Docker credential helpers. On Cloud VMs without Docker installed, the CLI will
use context-based authorization for AWS, Azure and GCP.
The source-controller will reuse the authentication library from
[image-reflector-controller](https://github.com/fluxcd/image-reflector-controller).
The Flux CLI will produce OCI artifacts with the following format: The Flux CLI will produce OCI artifacts with the following format:
```json ```json
{ {
"schemaVersion": 2, "schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json", "mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": { "config": {
"mediaType": "application/vnd.docker.container.image.v1+json", "mediaType": "application/vnd.cncf.flux.config.v1+json",
"size": 233, "size": 233,
"digest": "sha256:3b6cdcc7adcc9a84d3214ee1c029543789d90b5ae69debe9efa3f66e982875de" "digest": "sha256:1b80ecb1c04d4a9718a6094a00ed17b76ea8ff2bb846695fa38e7492d34f505c"
}, },
"layers": [ "layers": [
{ {
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "mediaType": "application/vnd.cncf.flux.content.v1.tar+gzip",
"size": 1091, "size": 19081,
"digest": "sha256:ad804afeae14a8a5c9a45b29f4931104a887844691d040c8737ee3cce6fd6735" "digest": "sha256:46c2b334705cd08db1a6fa46f860cd3364fc1a3636eea37a9b35537549086a1c"
} }
], ],
"annotations": { "annotations": {
"org.opencontainers.image.created": "2022-08-08T12:31:41+03:00", "org.opencontainers.image.created": "2023-02-10T09:06:09Z",
"org.opencontainers.image.revision": "6.1.8/b3b00fe35424a45d373bf4c7214178bc36fd7872", "org.opencontainers.image.revision": "6ea3e5b4da159fcb4a1288f072d34c3315644bcc",
"org.opencontainers.image.source": "https://github.com/stefanprodan/podinfo.git" "org.opencontainers.image.source": "https://github.com/fluxcd/flux2"
} }
} }
``` ```
@ -442,8 +435,8 @@ status:
checksum: d7e924b4882e55b97627355c7b3d2e711e9b54303afa2f50c25377f4df66a83b checksum: d7e924b4882e55b97627355c7b3d2e711e9b54303afa2f50c25377f4df66a83b
lastUpdateTime: "2022-06-22T09:14:21Z" lastUpdateTime: "2022-06-22T09:14:21Z"
metadata: metadata:
org.opencontainers.image.created: "2022-08-08T12:31:41+03:00" org.opencontainers.image.created: "2023-02-10T09:06:09Z"
org.opencontainers.image.revision: 6.1.8/b3b00fe35424a45d373bf4c7214178bc36fd7872 org.opencontainers.image.revision: b3b00fe35424a45d373bf4c7214178bc36fd7872
org.opencontainers.image.source: https://github.com/stefanprodan/podinfo.git org.opencontainers.image.source: https://github.com/stefanprodan/podinfo.git
path: ocirepository/oci/podinfo/3b6cdcc7adcc9a84d3214ee1c029543789d90b5ae69debe9efa3f66e982875de.tar.gz path: ocirepository/oci/podinfo/3b6cdcc7adcc9a84d3214ee1c029543789d90b5ae69debe9efa3f66e982875de.tar.gz
revision: 3b6cdcc7adcc9a84d3214ee1c029543789d90b5ae69debe9efa3f66e982875de revision: 3b6cdcc7adcc9a84d3214ee1c029543789d90b5ae69debe9efa3f66e982875de

Loading…
Cancel
Save