Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MZOCI - Make Zarf OCI (Take #2) #1423

Merged
merged 77 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
03fd619
1322 component tarballs (#1331)
YrrepNoj Feb 13, 2023
686b7cf
deletes tar.zst of components after unarchive (#1385)
wirewc Feb 27, 2023
2a8a867
Create a `zarf package publish` command (#1336)
Noxsios Mar 1, 2023
247b449
1324 images tar now expanded (#1359)
YrrepNoj Mar 1, 2023
d398f57
properly re-create components layers when publishing packages
YrrepNoj Feb 28, 2023
20ec44e
Update src/pkg/packager/common.go
Noxsios Mar 1, 2023
f752c34
Update src/pkg/packager/common.go
Noxsios Mar 1, 2023
a135776
re-order defaults so that they get picked up properly
Noxsios Mar 1, 2023
d7343a7
refactor oras remote
Noxsios Mar 2, 2023
2e7a434
archive pulled packages without including temp directory
YrrepNoj Mar 2, 2023
f67ff77
start adding e2e tests for oci stuffs
Noxsios Mar 3, 2023
439ab99
use e2e.arch
Noxsios Mar 3, 2023
0388330
some clarity during big memory stores
Noxsios Mar 3, 2023
32ef564
tests
Noxsios Mar 3, 2023
0f6aafc
tests
Noxsios Mar 3, 2023
09a5592
do not compress component layers within a package
YrrepNoj Mar 3, 2023
d518c52
fix tests
Noxsios Mar 3, 2023
fee547c
login does not have --password, use -p
Noxsios Mar 3, 2023
60d6d39
add back the progress bar for pulling images when creating a package
YrrepNoj Mar 3, 2023
9a1d6d8
add back the --decompress-all flag for git tests
YrrepNoj Mar 3, 2023
b872733
log the correct error message when unable to get dir size
YrrepNoj Mar 3, 2023
e439285
http roundtripper progress bar w/ oras
Noxsios Mar 4, 2023
0ddb3bb
some output cleanup
Noxsios Mar 4, 2023
30383da
this probably makes things even more complicated...
Noxsios Mar 5, 2023
daa9dbc
fix tests + cleanup some cli output
Noxsios Mar 6, 2023
aa784aa
add progress bar for pulling a published zarf package
YrrepNoj Mar 6, 2023
839395f
repackage components into a tarball when publishing (instead of tar.zst)
YrrepNoj Mar 7, 2023
36010c9
fix e2e test that validate oci functionality
YrrepNoj Mar 7, 2023
d84d2f3
Apply suggestions from code review by @Racer159
Noxsios Mar 7, 2023
d797925
clean up clean up, everybody clean up
YrrepNoj Mar 7, 2023
ba46179
create utility for creating a progress bar for local file saves
YrrepNoj Mar 7, 2023
908e819
make inspect oci:// like inspect
Noxsios Mar 7, 2023
b4dfd21
use new utils fn
Noxsios Mar 7, 2023
256cb52
update inspect test
Noxsios Mar 7, 2023
9da6588
fix inspect
Noxsios Mar 7, 2023
3eebe46
update docs
Noxsios Mar 8, 2023
6daa3a2
concurrency --> oci-concurrency
Noxsios Mar 8, 2023
56639da
removed uneeded gitignore
Noxsios Mar 8, 2023
a8fdcbc
no more precopy
Noxsios Mar 8, 2023
b6f1126
linting
Noxsios Mar 8, 2023
a8ff4bc
better isManifestUnsupported handling
Noxsios Mar 8, 2023
76d6045
docs
Noxsios Mar 8, 2023
9ff8434
Fix the period on a comment in create.go
Racer159 Mar 8, 2023
f391a9e
Fix decompressLayers
Racer159 Mar 8, 2023
48a04a6
Fix decompressLayers
Racer159 Mar 8, 2023
fad5306
remove gif and tape
Noxsios Mar 8, 2023
a8cb37d
feedback
Noxsios Mar 8, 2023
42254b6
docs
Noxsios Mar 8, 2023
769c8cb
docs
Noxsios Mar 8, 2023
08f8bf5
Merge branch 'main' into features/oci-package
Racer159 Mar 8, 2023
b6732ca
remove referrers for image manifest, we are not doing nested manifests
Noxsios Mar 8, 2023
e718629
docs
Noxsios Mar 8, 2023
ed478fd
refactor inspect
Noxsios Mar 9, 2023
c317275
some pre-commit stuff
Noxsios Mar 9, 2023
a8063e4
fix podinfo test
Noxsios Mar 10, 2023
2dae9cc
linting
Noxsios Mar 10, 2023
e8dfae6
docs and schema
Noxsios Mar 10, 2023
2ccaeec
docs and schema
Noxsios Mar 10, 2023
7ac27c7
decompress sboms when the --decompress-all flag is provided
YrrepNoj Mar 10, 2023
6551d39
add json utility to write files to disk
YrrepNoj Mar 10, 2023
c4433ba
refactor and rename progress bar for local dir writes
YrrepNoj Mar 10, 2023
462766e
init adr
Noxsios Mar 10, 2023
c032897
remove sbom tar after decompressing the layers
YrrepNoj Mar 10, 2023
d11e78e
Merge branch 'main' into features/oci-package
Racer159 Mar 11, 2023
c8670f1
retry removals of directories that have been recently archived b/c of…
YrrepNoj Mar 13, 2023
7904435
unarchive the sboms into an sbom directory when deploying a package
YrrepNoj Mar 13, 2023
c1fce23
start adr for zarf pacakge structure updates
YrrepNoj Mar 13, 2023
ab701b3
update adr
Noxsios Mar 13, 2023
e73f052
actually check the right location for the package SBOM contents..
YrrepNoj Mar 13, 2023
adedb69
double the wait, i hate this
Noxsios Mar 14, 2023
b95f47e
Merge branch 'main' into features/oci-package
Racer159 Mar 14, 2023
bfd9ef2
update go.mod to use forked syft to fix file close bug
YrrepNoj Mar 14, 2023
23f07f8
grab oras default retry client
Noxsios Mar 14, 2023
923919c
no more need to have retry remove since the file handle is getting pr…
Noxsios Mar 14, 2023
0c5aa6c
fix visual glitches on proress bar
Noxsios Mar 14, 2023
552902a
make sbom functionality more backwards compatable with older zarf pac…
YrrepNoj Mar 14, 2023
0e251ac
fix bug with showing/outputting sbom content when creating a package
YrrepNoj Mar 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/scan-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ jobs:
steps:
- uses: yogevbd/[email protected]
with:
BANNED_LABELS: "needs-docs,needs-tests,needs-adr,needs-git-sign-off"
BANNED_LABELS: "needs-docs,needs-tests,needs-adr,needs-git-sign-off,needs-walkthrough"
60 changes: 60 additions & 0 deletions adr/0014-oci-publish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 14. Zarf Packages as OCI Artifacts

Date: 2023-03-10

## Status

Accepted

## Context

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.

We know we are successful when:

1. (Priority) Users can use Zarf to natively publish a Zarf package to an OCI compliant registry
2. (Secondary goal) Package creators can sign Zarf packages to enable package deployers can trust a packages supply chain security

## Decision

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.

## Implementation

A handful of changes were introduced to the structure of Zarf packages.

```text
zarf-package-adr-arm64.tar.zst
├── checksums.txt
├── components
│ └── [...].tar
├── images
│ ├── index.json
│ ├── oci-layout
│ └── blobs
│ └── sha256
│ └── ... # OCI image layers
├── sboms.tar
└── zarf.yaml
```

- Each component folder is now a tarball instead of a directory
- This enables us to treat each component as a layer within the package artifact
- Images are now stored in a flattened state instead of an images.tar file
- This enables us to keep each image layer as a layer within the package artifact (allowing for server side de-duping)
- SBOM files are now stored in a tarball instead of a directory
- This enables us to treat the SBOM artifacts as a single layer within the package artifact

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://...`).

For an example of this in action, please see the [walkthrough](./docs/../../docs/13-walkthroughs/6-publish-and-deploy.md).

## Consequences

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.

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`.

One thing we may want to look at more in the future is how we can get more intricate tests around the backwards compatibility.

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.
219 changes: 219 additions & 0 deletions docs/13-walkthroughs/6-publish-and-deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Using OCI to Store & Deploy Zarf Packages

## Introduction

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.

## Prerequisites

For following along locally, please ensure the following prerequisites are met:

1. Zarf binary installed on your `$PATH`: ([Install Instructions](../3-getting-started.md#installing-zarf))
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

## Setup

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:

```bash
# Setup some variables for the registry we will be using
$ REGISTRY=docker.io
$ set +o history
$ REGISTRY_USERNAME=<username> # <-- replace with your username
$ REPOSITORY_URL=$REGISTRY/$REGISTRY_USERNAME
$ REGISTRY_SECRET=<secret> # <-- replace with your password or auth token
$ set -o history
```

With those set, you can tell Zarf to login to your registry with the following:

```bash
$ echo $REGISTRY_SECRET | zarf tools registry login $REGISTRY --username $REGISTRY_USERNAME --password-stdin

2023/03/07 23:03:16 logged in via /home/zarf/.docker/config.json
```

:::note

If you do not have the Docker CLI installed, you may need to create a Docker compliant auth config file manually:

```bash
$ mkdir -p ~/.docker
$ AUTH=$(echo -n "$REGISTRY_USERNAME:$REGISTRY_SECRET" | base64)
# Note: If using Docker Hub, the registry URL is `https://index.docker.io/v1/` for the auth config
$ cat <<EOF > ~/.docker/config.json
{
"auths": {
"$REGISTRY": {
"auth": "$AUTH"
}
}
}
EOF
```

:::

## Publish Package

First, create a valid Zarf package definition (`zarf.yaml`), with the `metadata.version` key set.

```yaml
# Make a new directory to work in
$ mkdir -p zarf-publish-walkthrough && cd zarf-publish-walkthrough

# For this walkthrough we will use the `helm-oci-chart` example package
# located here: https://github.com/defenseunicorns/zarf/blob/main/examples/helm-oci-chart/zarf.yaml
$ cat <<EOF > zarf.yaml
kind: ZarfPackageConfig
metadata:
name: helm-oci-chart
description: Deploy podinfo using a Helm OCI chart
# Note: In order to publish, the package must have a version
version: 0.0.1

components:
- name: helm-oci-chart
required: true
charts:
- name: podinfo
version: 6.3.3
namespace: helm-oci-demo
url: oci://ghcr.io/stefanprodan/charts/podinfo
images:
- "ghcr.io/stefanprodan/podinfo:6.3.3"
EOF
```

Create the package locally:

[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_create.md)

```bash
# Create the package (interactively)
$ zarf package create .
# Make these choices at the prompts:
# Create this Zarf package? Yes
# Please provide a value for "Maximum Package Size" 0
```

Then publish the package to the registry:

:::note

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`.

:::

[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_publish.md)

```bash
$ zarf package publish zarf-package-helm-oci-chart-arm64-0.0.1.tar.zst oci://$REPOSITORY_URL

...

• Publishing package to $REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
✔ Prepared 14 layers
✔ 515aceaacb8d images/index.json
✔ 4615b4f0c1ed zarf.yaml
✔ 1300d6545c84 sboms.tar
✔ b66dbb27a733 images/oci-layout
✔ 46564f0eff85 images/blobs/sha256/46564f0...06008f762391a7bb7d58f339ee
✔ 4f4fb700ef54 images/blobs/sha256/4f4fb70...b5577484a6d75e68dc38e8acc1
✔ 6ff8f4799d50 images/blobs/sha256/6ff8f47...4bc00ec8b988d28cef78ea9a5b
✔ 74eae207aa23 images/blobs/sha256/74eae20...fcb007d3da7b842313f80d2c33
✔ a9eaa45ef418 images/blobs/sha256/a9eaa45...6789c52a87ba5a9e6483f2b74f
✔ 8c5b695f4724 images/blobs/sha256/8c5b695...014f94c8d4ea62772c477c1e03
✔ ab67ffd6e92e images/blobs/sha256/ab67ffd...f8c9d93c0e719f6350e99d3aea
✔ b95c82728c36 images/blobs/sha256/b95c827...042a9c5d84426c1674044916d4
✔ e2b45cdcd8bf images/blobs/sha256/e2b45cd...000f1bc1695014e38821dc675c
✔ 79be488a834e components/helm-oci-chart.tar
✔ aed84ba183e7 [application/vnd.oci.artifact.manifest.v1+json]
✔ Published $REPOSITORY_URL/helm-oci-chart:0.0.1-arm64 [application/vnd.oci.artifact.manifest.v1+json]

• To inspect/deploy/pull:
• zarf package inspect oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
• zarf package deploy oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
• zarf package pull oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
```

:::note

The name and reference of this OCI artifact is derived from the package metadata, e.g.: `helm-oci-chart:0.0.1-arm64`

To modify, edit `zarf.yaml` and re-run `zarf package create .`

:::

## Inspect Package

[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_inspect.md)

Inspecting a Zarf package stored in an OCI registry is the same as inspecting a local package and has the same flags:

```yaml
$ zarf package inspect oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
---
kind: ZarfPackageConfig
metadata:
name: helm-oci-chart
description: Deploy podinfo using a Helm OCI chart
version: 0.0.1
architecture: arm64
build:
terminal: minimind.local
user: whoami
architecture: arm64
timestamp: Tue, 07 Mar 2023 14:27:25 -0600
version: v0.25.0-rc1-41-g07d61ba7
migrations:
- scripts-to-actions
components:
- name: helm-oci-chart
required: true
charts:
- name: podinfo
url: oci://ghcr.io/stefanprodan/charts/podinfo
version: 6.3.3
namespace: helm-oci-demo
images:
- ghcr.io/stefanprodan/podinfo:6.3.3
```

## Deploy Package

[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_deploy.md)

Deploying a package stored in an OCI registry is nearly the same experience as deploying a local package:

```bash
# Due to the length of the console output from this command,
# it has been omitted from this walkthrough
$ zarf package deploy oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64
# Make these choices at the prompts:
# Deploy this Zarf package? Yes

$ zarf packages list

Package | Components
helm-oci-chart | [helm-oci-chart]
init | [zarf-injector zarf-seed-registry zarf-registry zarf-agent git-server]
```

## Pull Package

[CLI Reference](../4-user-guide/1-the-zarf-cli/100-cli-commands/zarf_package_pull.md)

Packages can be saved to the local disk in order to deploy a package multiple times without needing to fetch it every time.

```bash
# go home so we don't clobber our currently local built package
$ cd ~
$ mkdir -p zarf-packages && cd zarf-packages

$ zarf package pull oci://$REPOSITORY_URL/helm-oci-chart:0.0.1-arm64

# use vim if you want to inspect the tarball's contents without decompressing it
$ vim zarf-package-helm-oci-chart-arm64-0.0.1.tar.zst
# don't forget to escape w/ `:q`
```
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@ Zarf package commands for creating, deploying, and inspecting packages
* [zarf package deploy](zarf_package_deploy.md) - Use to deploy a Zarf package from a local file or URL (runs offline)
* [zarf package inspect](zarf_package_inspect.md) - Lists the payload of a Zarf package (runs offline)
* [zarf package list](zarf_package_list.md) - List out all of the packages that have been deployed to the cluster
* [zarf package publish](zarf_package_publish.md) - Publish a Zarf package to a remote registry
* [zarf package pull](zarf_package_pull.md) - Pull a Zarf package from a remote registry and save to the local file system
* [zarf package remove](zarf_package_remove.md) - Use to remove a Zarf package that has been deployed already

Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ zarf package deploy [PACKAGE] [flags]
## Options

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

## Options inherited from parent commands
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# zarf package publish
<!-- Auto-generated by docs/gen-cli-docs.sh -->

Publish a Zarf package to a remote registry

```
zarf package publish [PACKAGE] [REPOSITORY] [flags]
```

## Examples

```
zarf package publish my-package.tar oci://my-registry.com/my-namespace
```

## Options

```
-h, --help help for publish
--oci-concurrency int Number of concurrent layer operations to perform when interacting with a remote package. (default 3)
```

## Options inherited from parent commands

```
-a, --architecture string Architecture for OCI images
--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.
-l, --log-level string Log level when running Zarf. Valid options are: warn, info, debug, trace (default "info")
--no-log-file Disable log file creation
--no-progress Disable fancy UI progress bars, spinners, logos, etc
--tmpdir string Specify the temporary directory to use for intermediate files
--zarf-cache string Specify the location of the Zarf cache directory (default "~/.zarf-cache")
```

## SEE ALSO

* [zarf package](zarf_package.md) - Zarf package commands for creating, deploying, and inspecting packages

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# zarf package pull
<!-- Auto-generated by docs/gen-cli-docs.sh -->

Pull a Zarf package from a remote registry and save to the local file system

```
zarf package pull [REFERENCE] [flags]
```

## Examples

```
zarf package pull oci://my-registry.com/my-namespace/my-package:0.0.1-arm64
```

## Options

```
-h, --help help for pull
--oci-concurrency int Number of concurrent layer operations to perform when interacting with a remote package. (default 3)
```

## Options inherited from parent commands

```
-a, --architecture string Architecture for OCI images
--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.
-l, --log-level string Log level when running Zarf. Valid options are: warn, info, debug, trace (default "info")
--no-log-file Disable log file creation
--no-progress Disable fancy UI progress bars, spinners, logos, etc
--tmpdir string Specify the temporary directory to use for intermediate files
--zarf-cache string Specify the location of the Zarf cache directory (default "~/.zarf-cache")
```

## SEE ALSO

* [zarf package](zarf_package.md) - Zarf package commands for creating, deploying, and inspecting packages

Loading