Skip to content

Commit 18e2498

Browse files
NoxsiosYrrepNojwirewcRacer159
authored
MZOCI - Make Zarf OCI (Take #2) (#1423)
## Description maybe this time I wont blow up the whole branch... maybe... ## Related Issue Relates to #1298 Fixes #1319 Fixes #1326 Fixes #1324 Fixes #1322 Fixes #1325 ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Other (security config, docs update, etc) ## Checklist before merging - [x] Test, docs, adr added or updated as needed - [x] [Contributor Guide Steps](https://github.com/defenseunicorns/zarf/blob/main/CONTRIBUTING.md#developer-workflow) followed --------- Signed-off-by: Jon Perry <yrrepnoj@gmail.com> Signed-off-by: razzle <harry@razzle.cloud> Co-authored-by: Jonathan Perry <YrrepNoj@gmail.com> Co-authored-by: Will C <wirewc@gmail.com> Co-authored-by: Wayne Starr <Racer159@users.noreply.github.com> Co-authored-by: Wayne Starr <me@racer159.com>
1 parent 696a1c8 commit 18e2498

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3691
-148
lines changed

.github/workflows/scan-labels.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ jobs:
99
steps:
1010
- uses: yogevbd/enforce-label-action@2.2.2
1111
with:
12-
BANNED_LABELS: "needs-docs,needs-tests,needs-adr,needs-git-sign-off"
12+
BANNED_LABELS: "needs-docs,needs-tests,needs-adr,needs-git-sign-off,needs-walkthrough"

adr/0014-oci-publish.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 14. Zarf Packages as OCI Artifacts
2+
3+
Date: 2023-03-10
4+
5+
## Status
6+
7+
Accepted
8+
9+
## Context
10+
11+
Zarf packages are currently only available if built locally or through manual file transfers. This is not a scalable way to distribute packages. We wanted to find a way to distribute and publish packages in a way that is easily consumable for the majority of users. When considering the goal of being able to share packages, security and trust are very important considerations. We wanted our publishing solution and architecture changes to keep in mind signing of packages and the ability to verify the integrity of packages.
12+
13+
We know we are successful when:
14+
15+
1. (Priority) Users can use Zarf to natively publish a Zarf package to an OCI compliant registry
16+
2. (Secondary goal) Package creators can sign Zarf packages to enable package deployers can trust a packages supply chain security
17+
18+
## Decision
19+
20+
We decided that changing the structure of Zarf packages to be an OCI artifact would be the best way to distribute and publish packages as registries are already an integral part of the container ecosystem.
21+
22+
## Implementation
23+
24+
A handful of changes were introduced to the structure of Zarf packages.
25+
26+
```text
27+
zarf-package-adr-arm64.tar.zst
28+
├── checksums.txt
29+
├── components
30+
│ └── [...].tar
31+
├── images
32+
│ ├── index.json
33+
│ ├── oci-layout
34+
│ └── blobs
35+
│ └── sha256
36+
│ └── ... # OCI image layers
37+
├── sboms.tar
38+
└── zarf.yaml
39+
```
40+
41+
- Each component folder is now a tarball instead of a directory
42+
- This enables us to treat each component as a layer within the package artifact
43+
- Images are now stored in a flattened state instead of an images.tar file
44+
- This enables us to keep each image layer as a layer within the package artifact (allowing for server side de-duping)
45+
- SBOM files are now stored in a tarball instead of a directory
46+
- This enables us to treat the SBOM artifacts as a single layer within the package artifact
47+
48+
With this new structure in place, we can now publish Zarf packages as OCI artifacts. Under the hood this implements the `oras` Go library using Docker's authentication system. For interacting with these packages, the `oci://` package path prefix has been added (ex. `zarf package publish oci://...`).
49+
50+
For an example of this in action, please see the [walkthrough](./docs/../../docs/13-walkthroughs/6-publish-and-deploy.md).
51+
52+
## Consequences
53+
54+
Backwards compatibility was an important considering when making these changes. We had to implement logic to make sure a new version of the Zarf binary could still operate with older versions of Zarf packages.
55+
56+
At the moment we are testing the backwards compatibility by virtue of maintaining the `./src/test/e2e/27_cosign_deploy_test.go` where we are deploying an old Zarf package via `sget`.
57+
58+
One thing we may want to look at more in the future is how we can get more intricate tests around the backwards compatibility.
59+
60+
The reason why testing backwards compatibility is difficult is because this isn't a `zarf.yaml` schema change (like we had recently with the 'Scripts to Actions' PR) but an compiled package architecture change. This means that we will either need to maintain an 'old' Zarf package that will follow future `zarf.yaml` schema changes OR we maintain a modified Zarf binary that creates the old package structure.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Using OCI to Store & Deploy Zarf Packages
2+
3+
## Introduction
4+
5+
In this walkthrough, we are going to run through how to publish a Zarf package to an [OCI](https://github.com/opencontainers/image-spec) compliant registry, allowing end users to pull and deploy packages without needing to build locally, or transfer the package to their environment.
6+
7+
## Prerequisites
8+
9+
For following along locally, please ensure the following prerequisites are met:
10+
11+
1. Zarf binary installed on your `$PATH`: ([Install Instructions](../3-getting-started.md#installing-zarf))
12+
2. Access to a [Registry supporting the OCI Distribution Spec](https://oras.land/implementors/#registries-supporting-oci-artifacts), this walkthrough will be using Docker Hub
13+
14+
## Setup
15+
16+
This walkthrough will require a registry to be configured (see [prerequisites](#prerequisites) for more information). The below sets up some variables for us to use when logging into the registry:
17+
18+
```bash
19+
# Setup some variables for the registry we will be using
20+
$ REGISTRY=docker.io
21+
$ set +o history
22+
$ REGISTRY_USERNAME=<username> # <-- replace with your username
23+
$ REPOSITORY_URL=$REGISTRY/$REGISTRY_USERNAME
24+
$ REGISTRY_SECRET=<secret> # <-- replace with your password or auth token
25+
$ set -o history
26+
```
27+
28+
With those set, you can tell Zarf to login to your registry with the following:
29+
30+
```bash
31+
$ echo $REGISTRY_SECRET | zarf tools registry login $REGISTRY --username $REGISTRY_USERNAME --password-stdin
32+
33+
2023/03/07 23:03:16 logged in via /home/zarf/.docker/config.json
34+
```
35+
36+
:::note
37+
38+
If you do not have the Docker CLI installed, you may need to create a Docker compliant auth config file manually:
39+
40+
```bash
41+
$ mkdir -p ~/.docker
42+
$ AUTH=$(echo -n "$REGISTRY_USERNAME:$REGISTRY_SECRET" | base64)
43+
# Note: If using Docker Hub, the registry URL is `https://index.docker.io/v1/` for the auth config
44+
$ cat <<EOF > ~/.docker/config.json
45+
{
46+
"auths": {
47+
"$REGISTRY": {
48+
"auth": "$AUTH"
49+
}
50+
}
51+
}
52+
EOF
53+
```
54+
55+
:::
56+
57+
## Publish Package
58+
59+
First, create a valid Zarf package definition (`zarf.yaml`), with the `metadata.version` key set.
60+
61+
```yaml
62+
# Make a new directory to work in
63+
$ mkdir -p zarf-publish-walkthrough && cd zarf-publish-walkthrough
64+
65+
# For this walkthrough we will use the `helm-oci-chart` example package
66+
# located here: https://github.com/defenseunicorns/zarf/blob/main/examples/helm-oci-chart/zarf.yaml
67+
$ cat <<EOF > zarf.yaml
68+
kind: ZarfPackageConfig
69+
metadata:
70+
name: helm-oci-chart
71+
description: Deploy podinfo using a Helm OCI chart
72+
# Note: In order to publish, the package must have a version
73+
version: 0.0.1
74+
75+
components:
76+
- name: helm-oci-chart
77+
required: true
78+
charts:
79+
- name: podinfo
80+
version: 6.3.3
81+
namespace: helm-oci-demo
82+
url: oci://ghcr.io/stefanprodan/charts/podinfo
83+
images:
84+
- "ghcr.io/stefanprodan/podinfo:6.3.3"
85+
EOF
86+
```
87+
88+
Create the package locally:
89+
90+
[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_create.md)
91+
92+
```bash
93+
# Create the package (interactively)
94+
$ zarf package create .
95+
# Make these choices at the prompts:
96+
# Create this Zarf package? Yes
97+
# Please provide a value for "Maximum Package Size" 0
98+
```
99+
100+
Then publish the package to the registry:
101+
102+
:::note
103+
104+
Your package tarball may be named differently based on your machine's architecture. For example, if you are running on an AMD64 machine, the tarball will be named `zarf-package-helm-oci-chart-amd64-0.0.1.tar.zst`.
105+
106+
:::
107+
108+
[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_publish.md)
109+
110+
```bash
111+
$ zarf package publish zarf-package-helm-oci-chart-arm64-0.0.1.tar.zst oci://$REPOSITORY_URL
112+
113+
...
114+
115+
• Publishing package to $REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
116+
✔ Prepared 14 layers
117+
✔ 515aceaacb8d images/index.json
118+
✔ 4615b4f0c1ed zarf.yaml
119+
✔ 1300d6545c84 sboms.tar
120+
✔ b66dbb27a733 images/oci-layout
121+
✔ 46564f0eff85 images/blobs/sha256/46564f0...06008f762391a7bb7d58f339ee
122+
✔ 4f4fb700ef54 images/blobs/sha256/4f4fb70...b5577484a6d75e68dc38e8acc1
123+
✔ 6ff8f4799d50 images/blobs/sha256/6ff8f47...4bc00ec8b988d28cef78ea9a5b
124+
✔ 74eae207aa23 images/blobs/sha256/74eae20...fcb007d3da7b842313f80d2c33
125+
✔ a9eaa45ef418 images/blobs/sha256/a9eaa45...6789c52a87ba5a9e6483f2b74f
126+
✔ 8c5b695f4724 images/blobs/sha256/8c5b695...014f94c8d4ea62772c477c1e03
127+
✔ ab67ffd6e92e images/blobs/sha256/ab67ffd...f8c9d93c0e719f6350e99d3aea
128+
✔ b95c82728c36 images/blobs/sha256/b95c827...042a9c5d84426c1674044916d4
129+
✔ e2b45cdcd8bf images/blobs/sha256/e2b45cd...000f1bc1695014e38821dc675c
130+
✔ 79be488a834e components/helm-oci-chart.tar
131+
✔ aed84ba183e7 [application/vnd.oci.artifact.manifest.v1+json]
132+
✔ Published $REPOSITORY_URL/helm-oci-chart:0.0.1-arm64 [application/vnd.oci.artifact.manifest.v1+json]
133+
134+
• To inspect/deploy/pull:
135+
• zarf package inspect oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
136+
• zarf package deploy oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
137+
• zarf package pull oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
138+
```
139+
140+
:::note
141+
142+
The name and reference of this OCI artifact is derived from the package metadata, e.g.: `helm-oci-chart:0.0.1-arm64`
143+
144+
To modify, edit `zarf.yaml` and re-run `zarf package create .`
145+
146+
:::
147+
148+
## Inspect Package
149+
150+
[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_inspect.md)
151+
152+
Inspecting a Zarf package stored in an OCI registry is the same as inspecting a local package and has the same flags:
153+
154+
```yaml
155+
$ zarf package inspect oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
156+
---
157+
kind: ZarfPackageConfig
158+
metadata:
159+
name: helm-oci-chart
160+
description: Deploy podinfo using a Helm OCI chart
161+
version: 0.0.1
162+
architecture: arm64
163+
build:
164+
terminal: minimind.local
165+
user: whoami
166+
architecture: arm64
167+
timestamp: Tue, 07 Mar 2023 14:27:25 -0600
168+
version: v0.25.0-rc1-41-g07d61ba7
169+
migrations:
170+
- scripts-to-actions
171+
components:
172+
- name: helm-oci-chart
173+
required: true
174+
charts:
175+
- name: podinfo
176+
url: oci://ghcr.io/stefanprodan/charts/podinfo
177+
version: 6.3.3
178+
namespace: helm-oci-demo
179+
images:
180+
- ghcr.io/stefanprodan/podinfo:6.3.3
181+
```
182+
183+
## Deploy Package
184+
185+
[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_deploy.md)
186+
187+
Deploying a package stored in an OCI registry is nearly the same experience as deploying a local package:
188+
189+
```bash
190+
# Due to the length of the console output from this command,
191+
# it has been omitted from this walkthrough
192+
$ zarf package deploy oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
193+
# Make these choices at the prompts:
194+
# Deploy this Zarf package? Yes
195+
196+
$ zarf packages list
197+
198+
Package | Components
199+
helm-oci-chart | [helm-oci-chart]
200+
init | [zarf-injector zarf-seed-registry zarf-registry zarf-agent git-server]
201+
```
202+
203+
## Pull Package
204+
205+
[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_pull.md)
206+
207+
Packages can be saved to the local disk in order to deploy a package multiple times without needing to fetch it every time.
208+
209+
```bash
210+
# go home so we don't clobber our currently local built package
211+
$ cd ~
212+
$ mkdir -p zarf-packages && cd zarf-packages
213+
214+
$ zarf package pull oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
215+
216+
# use vim if you want to inspect the tarball's contents without decompressing it
217+
$ vim zarf-package-helm-oci-chart-arm64-0.0.1.tar.zst
218+
# don't forget to escape w/ `:q`
219+
```

docs/4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package.md

+2
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ Zarf package commands for creating, deploying, and inspecting packages
2828
* [zarf package deploy](zarf_package_deploy.md) - Use to deploy a Zarf package from a local file or URL (runs offline)
2929
* [zarf package inspect](zarf_package_inspect.md) - Lists the payload of a Zarf package (runs offline)
3030
* [zarf package list](zarf_package_list.md) - List out all of the packages that have been deployed to the cluster
31+
* [zarf package publish](zarf_package_publish.md) - Publish a Zarf package to a remote registry
32+
* [zarf package pull](zarf_package_pull.md) - Pull a Zarf package from a remote registry and save to the local file system
3133
* [zarf package remove](zarf_package_remove.md) - Use to remove a Zarf package that has been deployed already
3234

docs/4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_deploy.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ zarf package deploy [PACKAGE] [flags]
1414
## Options
1515

1616
```
17-
--components string Comma-separated list of components to install. Adding this flag will skip the init prompts for which components to install
18-
--confirm Confirm package deployment without prompting
19-
-h, --help help for deploy
20-
--set stringToString Specify deployment variables to set on the command line (KEY=value) (default [])
21-
--sget string Path to public sget key file for remote packages signed via cosign
22-
--shasum string Shasum of the package to deploy. Required if deploying a remote package and "--insecure" is not provided
17+
--components string Comma-separated list of components to install. Adding this flag will skip the init prompts for which components to install
18+
--confirm Confirm package deployment without prompting
19+
-h, --help help for deploy
20+
--oci-concurrency int Number of concurrent layer operations to perform when interacting with a remote package. (default 3)
21+
--set stringToString Specify deployment variables to set on the command line (KEY=value) (default [])
22+
--sget string Path to public sget key file for remote packages signed via cosign
23+
--shasum string Shasum of the package to deploy. Required if deploying a remote package and "--insecure" is not provided
2324
```
2425

2526
## Options inherited from parent commands
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# zarf package publish
2+
<!-- Auto-generated by docs/gen-cli-docs.sh -->
3+
4+
Publish a Zarf package to a remote registry
5+
6+
```
7+
zarf package publish [PACKAGE] [REPOSITORY] [flags]
8+
```
9+
10+
## Examples
11+
12+
```
13+
zarf package publish my-package.tar oci://my-registry.com/my-namespace
14+
```
15+
16+
## Options
17+
18+
```
19+
-h, --help help for publish
20+
--oci-concurrency int Number of concurrent layer operations to perform when interacting with a remote package. (default 3)
21+
```
22+
23+
## Options inherited from parent commands
24+
25+
```
26+
-a, --architecture string Architecture for OCI images
27+
--insecure Allow access to insecure registries and disable other recommended security enforcements. This flag should only be used if you have a specific reason and accept the reduced security posture.
28+
-l, --log-level string Log level when running Zarf. Valid options are: warn, info, debug, trace (default "info")
29+
--no-log-file Disable log file creation
30+
--no-progress Disable fancy UI progress bars, spinners, logos, etc
31+
--tmpdir string Specify the temporary directory to use for intermediate files
32+
--zarf-cache string Specify the location of the Zarf cache directory (default "~/.zarf-cache")
33+
```
34+
35+
## SEE ALSO
36+
37+
* [zarf package](zarf_package.md) - Zarf package commands for creating, deploying, and inspecting packages
38+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# zarf package pull
2+
<!-- Auto-generated by docs/gen-cli-docs.sh -->
3+
4+
Pull a Zarf package from a remote registry and save to the local file system
5+
6+
```
7+
zarf package pull [REFERENCE] [flags]
8+
```
9+
10+
## Examples
11+
12+
```
13+
zarf package pull oci://my-registry.com/my-namespace/my-package:0.0.1-arm64
14+
```
15+
16+
## Options
17+
18+
```
19+
-h, --help help for pull
20+
--oci-concurrency int Number of concurrent layer operations to perform when interacting with a remote package. (default 3)
21+
```
22+
23+
## Options inherited from parent commands
24+
25+
```
26+
-a, --architecture string Architecture for OCI images
27+
--insecure Allow access to insecure registries and disable other recommended security enforcements. This flag should only be used if you have a specific reason and accept the reduced security posture.
28+
-l, --log-level string Log level when running Zarf. Valid options are: warn, info, debug, trace (default "info")
29+
--no-log-file Disable log file creation
30+
--no-progress Disable fancy UI progress bars, spinners, logos, etc
31+
--tmpdir string Specify the temporary directory to use for intermediate files
32+
--zarf-cache string Specify the location of the Zarf cache directory (default "~/.zarf-cache")
33+
```
34+
35+
## SEE ALSO
36+
37+
* [zarf package](zarf_package.md) - Zarf package commands for creating, deploying, and inspecting packages
38+

0 commit comments

Comments
 (0)