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

1773 Publish Zarf init + skeleton as OCI on release #1990

Merged
merged 12 commits into from
Aug 28, 2023
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ jobs:
make release-init-package ARCH=amd64 AGENT_IMAGE_TAG=$GITHUB_REF_NAME
make release-init-package ARCH=arm64 AGENT_IMAGE_TAG=$GITHUB_REF_NAME

- name: Publish Init Package as OCI and Skeleton
run: |
make publish-init-package ARCH=amd64 REPOSITORY_URL=ghcr.io/defenseunicorns/packages
make publish-init-package ARCH=arm64 REPOSITORY_URL=ghcr.io/defenseunicorns/packages

# Create a CVE report based on this build
- name: Create release time CVE report
run: "make cve-report"
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ ib-init-package:
--set REGISTRY_IMAGE="ironbank/opensource/docker/registry-v2" \
--set REGISTRY_IMAGE_TAG="2.8.2"

# INTERNAL: used to publish the init package
publish-init-package:
$(ZARF_BIN) package publish build/zarf-init-$(ARCH)-$(CLI_VERSION).tar.zst oci://$(REPOSITORY_URL)
$(ZARF_BIN) package publish . oci://$(REPOSITORY_URL)

build-examples: ## Build all of the example packages
@test -s $(ZARF_BIN) || $(MAKE) build-cli

Expand Down
13 changes: 7 additions & 6 deletions src/cmd/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/config/lang"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/packager"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
Expand Down Expand Up @@ -114,17 +115,17 @@ func downloadInitPackage(downloadCacheTarget string) error {
}

var confirmDownload bool
url := packager.GetInitPackageRemote("")
url := oci.GetInitPackageURL(config.GetArch(), config.CLIVersion)

// Give the user the choice to download the init-package and note that this does require an internet connection
message.Question(fmt.Sprintf(lang.CmdInitDownloadAsk, url))
message.Question(fmt.Sprintf(lang.CmdInitPullAsk, url))

message.Note(lang.CmdInitDownloadNote)
message.Note(lang.CmdInitPullNote)

// Prompt the user if --confirm not specified
if !confirmDownload {
prompt := &survey.Confirm{
Message: lang.CmdInitDownloadConfirm,
Message: lang.CmdInitPullConfirm,
}
if err := survey.AskOne(prompt, &confirmDownload); err != nil {
return fmt.Errorf(lang.ErrConfirmCancel, err.Error())
Expand All @@ -133,10 +134,10 @@ func downloadInitPackage(downloadCacheTarget string) error {

// If the user wants to download the init-package, download it
if confirmDownload {
return utils.DownloadToFile(url, downloadCacheTarget, "")
return oci.DownloadPackageTarball(url, downloadCacheTarget, config.CommonOptions.OCIConcurrency)
}
// Otherwise, exit and tell the user to manually download the init-package
return errors.New(lang.CmdInitDownloadErrManual)
return errors.New(lang.CmdInitPullErrManual)
}

func validateInitFlags() error {
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/tools/zarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
"github.com/defenseunicorns/zarf/src/internal/packager/git"
"github.com/defenseunicorns/zarf/src/internal/packager/helm"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/packager"
"github.com/defenseunicorns/zarf/src/pkg/pki"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"github.com/defenseunicorns/zarf/src/types"
"github.com/sigstore/cosign/pkg/cosign"
Expand Down Expand Up @@ -174,9 +174,9 @@ var downloadInitCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
initPackageName := packager.GetInitPackageName("")
target := filepath.Join(outputDirectory, initPackageName)
url := packager.GetInitPackageRemote("")
err := utils.DownloadToFile(url, target, "")
if err != nil {
url := oci.GetInitPackageURL(config.GetArch(), config.CLIVersion)

if err := oci.DownloadPackageTarball(url, target, config.CommonOptions.OCIConcurrency); err != nil {
message.Fatalf(err, lang.CmdToolsDownloadInitErr, err.Error())
}
},
Expand Down
8 changes: 4 additions & 4 deletions src/config/lang/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ const (
CmdInitErrValidateArtifact = "the 'artifact-push-username' and 'artifact-push-token' flags must be provided if the 'artifact-url' flag is provided"
CmdInitErrUnableCreateCache = "Unable to create the cache directory: %s"

CmdInitDownloadAsk = "It seems the init package could not be found locally, but can be downloaded from %s"
CmdInitDownloadNote = "Note: This will require an internet connection."
CmdInitDownloadConfirm = "Do you want to download this init package?"
CmdInitDownloadErrManual = "download the init package manually and place it in the current working directory"
CmdInitPullAsk = "It seems the init package could not be found locally, but can be pulled from oci://%s"
CmdInitPullNote = "Note: This will require an internet connection."
CmdInitPullConfirm = "Do you want to pull this init package?"
CmdInitPullErrManual = "pull the init package manually and place it in the current working directory"

CmdInitFlagSet = "Specify deployment variables to set on the command line (KEY=value)"

Expand Down
36 changes: 36 additions & 0 deletions src/pkg/oci/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"github.com/defenseunicorns/zarf/src/types"
"github.com/mholt/archiver/v3"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2/registry"
)
Expand Down Expand Up @@ -91,3 +94,36 @@ func RemoveDuplicateDescriptors(descriptors []ocispec.Descriptor) []ocispec.Desc
}
return list
}

// GetInitPackageURL returns the URL for the init package for the given architecture and version.
func GetInitPackageURL(arch, version string) string {
return fmt.Sprintf("ghcr.io/defenseunicorns/packages/init:%s-%s", version, arch)
}

// DownloadPackageTarball downloads the given OCI package and saves as a tarball.
func DownloadPackageTarball(url, destinationTarball string, concurrency int) error {
remote, err := NewOrasRemote(url)
if err != nil {
return err
}

tmp, err := utils.MakeTempDir()
if err != nil {
return err
}
defer os.RemoveAll(tmp)

_, err = remote.PullPackage(tmp, concurrency)
if err != nil {
return err
}

allTheLayers, err := filepath.Glob(filepath.Join(tmp, "*"))
if err != nil {
return err
}

_ = os.Remove(destinationTarball)

return archiver.Archive(allTheLayers, destinationTarball)
}
5 changes: 0 additions & 5 deletions src/pkg/packager/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@ func (p *Packager) GetPackageName() string {
return fmt.Sprintf("%s.%s", packageFileName, suffix)
}

// GetInitPackageRemote returns the URL for a remote init package for the given architecture
func GetInitPackageRemote(arch string) string {
return fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", config.GithubProject, config.CLIVersion, GetInitPackageName(arch))
}

// ClearTempPaths removes the temp directory and any files within it.
func (p *Packager) ClearTempPaths() {
// Remove the temp directory, but don't throw an error if it fails
Expand Down
4 changes: 4 additions & 0 deletions src/pkg/packager/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func (p *Packager) loadSkeleton() error {
return fmt.Errorf("unable to read the zarf.yaml in %s: %s", base, err.Error())
}

if p.cfg.Pkg.Kind == types.ZarfInitConfig {
p.cfg.Pkg.Metadata.Version = config.CLIVersion
}

err = p.composeComponents()
if err != nil {
return err
Expand Down