Skip to content

Commit

Permalink
Read uds-bundle.yaml from current working dir (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGedd authored Aug 29, 2023
1 parent 029832e commit 3cae2b1
Show file tree
Hide file tree
Showing 19 changed files with 227 additions and 113 deletions.
80 changes: 67 additions & 13 deletions src/cmd/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ package cmd

import (
"fmt"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"

"github.com/AlecAivazis/survey/v2"
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/config/lang"
"github.com/defenseunicorns/uds-cli/src/pkg/bundler"
"github.com/defenseunicorns/zarf/src/config"
zarfConfig "github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"os"
"path/filepath"

"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/spf13/cobra"
Expand All @@ -27,15 +30,25 @@ var bundleCmd = &cobra.Command{
var bundleCreateCmd = &cobra.Command{
Use: "create [DIRECTORY]",
Aliases: []string{"c"},
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
Short: lang.CmdBundleCreateShort,
PreRun: func(cmd *cobra.Command, args []string) {
if !utils.IsDir(args[0]) {
message.Fatalf(nil, "first argument (%q) must be a valid path to a directory", args[0])
if len(args) > 0 && !utils.IsDir(args[0]) {
message.Fatalf(nil, "(%q) is not a valid path to a directory", args[0])
}
if _, err := os.Stat(config.BundleYAML); len(args) == 0 && err != nil {
message.Fatalf(err, "%s not found in directory", config.BundleYAML)
}
},
Run: func(cmd *cobra.Command, args []string) {
bundleCfg.CreateOpts.SourceDirectory = args[0]
srcDir, err := os.Getwd()
if err != nil {
message.Fatalf(err, "error reading the current working directory")
}
if len(args) > 0 {
srcDir = args[0]
}
bundleCfg.CreateOpts.SourceDirectory = srcDir

bundleCfg.CreateOpts.SetVariables = bundler.MergeVariables(v.GetStringMapString(V_BNDL_CREATE_SET), bundleCfg.CreateOpts.SetVariables)

Expand All @@ -53,10 +66,11 @@ var bundleDeployCmd = &cobra.Command{
Use: "deploy [BUNDLE_TARBALL|OCI_REF]",
Aliases: []string{"d"},
Short: lang.CmdBundleDeployShort,
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
PreRun: firstArgIsEitherOCIorTarball,
Run: func(cmd *cobra.Command, args []string) {
bundleCfg.DeployOpts.Source = args[0]
bundleCfg.DeployOpts.Source = choosePackage(args)
configureZarf()

// read config file and unmarshal
if v.ConfigFileUsed() != "" {
Expand All @@ -71,7 +85,6 @@ var bundleDeployCmd = &cobra.Command{
return
}
}

bndlClient := bundler.NewOrDie(&bundleCfg)
defer bndlClient.ClearPaths()

Expand All @@ -86,10 +99,11 @@ var bundleInspectCmd = &cobra.Command{
Use: "inspect [BUNDLE_TARBALL|OCI_REF]",
Aliases: []string{"i"},
Short: lang.CmdBundleInspectShort,
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
PreRun: firstArgIsEitherOCIorTarball,
Run: func(cmd *cobra.Command, args []string) {
bundleCfg.InspectOpts.Source = args[0]
bundleCfg.InspectOpts.Source = choosePackage(args)
configureZarf()

bndlClient := bundler.NewOrDie(&bundleCfg)
defer bndlClient.ClearPaths()
Expand All @@ -109,6 +123,7 @@ var bundleRemoveCmd = &cobra.Command{
PreRun: firstArgIsEitherOCIorTarball,
Run: func(cmd *cobra.Command, args []string) {
bundleCfg.RemoveOpts.Source = args[0]
configureZarf()

bndlClient := bundler.NewOrDie(&bundleCfg)
defer bndlClient.ClearPaths()
Expand All @@ -132,7 +147,7 @@ var bundlePullCmd = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
bundleCfg.PullOpts.Source = args[0]

configureZarf()
bndlClient := bundler.NewOrDie(&bundleCfg)
defer bndlClient.ClearPaths()

Expand All @@ -144,6 +159,9 @@ var bundlePullCmd = &cobra.Command{
}

func firstArgIsEitherOCIorTarball(_ *cobra.Command, args []string) {
if len(args) == 0 {
return
}
var errString string
var err error
if bundler.IsValidTarballPath(args[0]) {
Expand Down Expand Up @@ -189,3 +207,39 @@ func init() {
bundlePullCmd.Flags().StringVarP(&bundleCfg.PullOpts.OutputDirectory, "output", "o", v.GetString(V_BNDL_PULL_OUTPUT), lang.CmdBundlePullFlagOutput)
bundlePullCmd.Flags().StringVarP(&bundleCfg.PullOpts.PublicKeyPath, "key", "k", v.GetString(V_BNDL_PULL_KEY), lang.CmdBundlePullFlagKey)
}

// configureZarf copies configs from UDS-CLI to Zarf
// todo: make a PR to Zarf to get rid of this: https://github.com/defenseunicorns/uds-cli/pull/26#discussion_r1307945876
func configureZarf() {
zarfConfig.CommonOptions.Insecure = config.CommonOptions.Insecure
zarfConfig.CommonOptions.TempDirectory = config.CommonOptions.TempDirectory
zarfConfig.CommonOptions.OCIConcurrency = config.CommonOptions.OCIConcurrency
zarfConfig.CommonOptions.Confirm = config.CommonOptions.Confirm
zarfConfig.CommonOptions.CachePath = config.CommonOptions.CachePath
}

// choosePackage provides a file picker when users don't specify a file
func choosePackage(args []string) string {
if len(args) > 0 {
return args[0]
}
var path string
prompt := &survey.Input{
Message: lang.CmdPackageChoose,
Suggest: func(toComplete string) []string {
files, _ := filepath.Glob(config.BundlePrefix + toComplete + "*.tar")
gzFiles, _ := filepath.Glob(config.BundlePrefix + toComplete + "*.tar.zst")
partialFiles, _ := filepath.Glob(config.BundlePrefix + toComplete + "*.part000")

files = append(files, gzFiles...)
files = append(files, partialFiles...)
return files
},
}

if err := survey.AskOne(prompt, &path, survey.WithValidator(survey.Required)); err != nil {
message.Fatalf(nil, lang.CmdPackageChooseErr, err.Error())
}

return path
}
5 changes: 3 additions & 2 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ package cmd

import (
"fmt"
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/config/lang"
"github.com/defenseunicorns/uds-cli/src/types"
"github.com/defenseunicorns/zarf/src/cmd/common"
"github.com/defenseunicorns/zarf/src/cmd/tools"
"github.com/defenseunicorns/zarf/src/config"
zarfConfig "github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/utils/exec"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -80,7 +81,7 @@ func init() {
v.SetDefault(V_NO_LOG_FILE, false)
v.SetDefault(V_NO_PROGRESS, false)
v.SetDefault(V_INSECURE, false)
v.SetDefault(V_ZARF_CACHE, config.ZarfDefaultCachePath) // todo: Zarf vs UDS cache
v.SetDefault(V_ZARF_CACHE, zarfConfig.ZarfDefaultCachePath)
v.SetDefault(V_TMP_DIR, "")

rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "l", v.GetString(V_LOG_LEVEL), lang.RootCmdFlagLogLevel)
Expand Down
36 changes: 34 additions & 2 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,43 @@
// Package config contains configuration strings for UDS-CLI
package config

import (
"github.com/defenseunicorns/uds-cli/src/types"
"runtime"
)

const (
ZarfYAML = "zarf.yaml"
BlobsDir = "blobs/sha256"
ZarfYAML = "zarf.yaml"
BlobsDir = "blobs/sha256"
BundleYAML = "uds-bundle.yaml"
BundlePrefix = "uds-bundle-"
)

var (
// CommonOptions tracks user-defined values that apply across commands.
CommonOptions types.BundlerCommonOptions

// CLIVersion track the version of the CLI
CLIVersion = "unset"

// CLIArch is the computer architecture of the device executing the CLI commands
CLIArch string

// SkipLogFile is a flag to skip logging to a file
SkipLogFile bool
)

// GetArch returns the arch based on a priority list with options for overriding.
func GetArch(archs ...string) string {
// List of architecture overrides.
priority := append([]string{CLIArch}, archs...)

// Find the first architecture that is specified.
for _, arch := range priority {
if arch != "" {
return arch
}
}

return runtime.GOARCH
}
4 changes: 4 additions & 0 deletions src/config/lang/lang.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const (
CmdViperErrLoadingConfigFile = "failed to load config file: %s"
CmdViperInfoUsingConfigFile = "Using config file %s"

// bundle picker during deployment
CmdPackageChoose = "Choose or type the bundle file"
CmdPackageChooseErr = "Bundle path selection canceled: %s"

// uds-cli version
CmdVersionShort = "Shows the version of the running UDS-CLI binary"
CmdVersionLong = "Displays the version of the UDS-CLI release that the current binary was built from."
Expand Down
15 changes: 7 additions & 8 deletions src/pkg/bundler/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/pkg/zarf"
"github.com/defenseunicorns/uds-cli/src/types"
zarfConfig "github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/utils"
Expand Down Expand Up @@ -250,14 +249,14 @@ func BundleAndPublish(r *oci.OrasRemote, bundle *types.UDSBundle, signature []by
return false
}

if err := oci.CopyPackage(ctx, remote, r, filterLayers, zarfConfig.CommonOptions.OCIConcurrency); err != nil {
if err := oci.CopyPackage(ctx, remote, r, filterLayers, config.CommonOptions.OCIConcurrency); err != nil {
return err
}
} else {
// blob mount if same registry
message.Debugf("Performing a cross repository blob mount on %s from %s --> %s", ref, ref.Repository, ref.Repository)
spinner := message.NewProgressSpinner("Mounting layers from %s", pkgRef.Repository)
layersToCopy = append(layersToCopy, pkgRootManifest.Config) // why do we need root.Config in this case?
layersToCopy = append(layersToCopy, pkgRootManifest.Config)
for _, layer := range layersToCopy {
spinner.Updatef("Mounting %s", layer.Digest.Encoded())
// layer is the descriptor!! Verbiage "fetch" or "pull" refers to the actual layers
Expand All @@ -282,10 +281,10 @@ func BundleAndPublish(r *oci.OrasRemote, bundle *types.UDSBundle, signature []by
return err
}
bundleYamlDesc.Annotations = map[string]string{
ocispec.AnnotationTitle: BundleYAML,
ocispec.AnnotationTitle: config.BundleYAML,
}

message.Debug("Pushed", BundleYAML+":", message.JSONValue(bundleYamlDesc))
message.Debug("Pushed", config.BundleYAML+":", message.JSONValue(bundleYamlDesc))
rootManifest.Layers = append(rootManifest.Layers, bundleYamlDesc)

// push the bundle's signature
Expand Down Expand Up @@ -330,7 +329,7 @@ func BundleAndPublish(r *oci.OrasRemote, bundle *types.UDSBundle, signature []by

message.HorizontalRule()
flags := ""
if zarfConfig.CommonOptions.Insecure {
if config.CommonOptions.Insecure {
flags = "--insecure"
}
message.Title("To inspect/deploy/pull:", "")
Expand Down Expand Up @@ -392,13 +391,13 @@ func pushBundleYamlToStore(ctx context.Context, store *ocistore.Store, bundle *t
}
bundleYamlDesc := content.NewDescriptorFromBytes(oci.ZarfLayerMediaTypeBlob, bundleYamlBytes)
bundleYamlDesc.Annotations = map[string]string{
ocispec.AnnotationTitle: BundleYAML,
ocispec.AnnotationTitle: config.BundleYAML,
}
err = store.Push(ctx, bundleYamlDesc, bytes.NewReader(bundleYamlBytes))
if err != nil {
return ocispec.Descriptor{}, err
}
message.Debug("Pushed", BundleYAML+":", message.JSONValue(bundleYamlDesc))
message.Debug("Pushed", config.BundleYAML+":", message.JSONValue(bundleYamlDesc))
return bundleYamlDesc, err
}

Expand Down
32 changes: 12 additions & 20 deletions src/pkg/bundler/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import (
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"

"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/pkg/zarf"
"github.com/defenseunicorns/uds-cli/src/types"
"github.com/defenseunicorns/zarf/src/config"
zarfConfig "github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/packager"
Expand Down Expand Up @@ -73,7 +73,7 @@ func NewOrDie(cfg *types.BundlerConfig) *Bundler {
// ClearPaths clears out the paths used by Bundler
func (b *Bundler) ClearPaths() {
_ = os.RemoveAll(b.tmp)
_ = os.RemoveAll(config.ZarfSBOMDir)
_ = os.RemoveAll(zarfConfig.ZarfSBOMDir)
}

// ValidateBundleResources validates the bundle's metadata and package references
Expand All @@ -89,14 +89,14 @@ func (b *Bundler) ValidateBundleResources(bundle *types.UDSBundle) error {
}
}
if bundle.Metadata.Version == "" {
return fmt.Errorf("%s is missing required field: metadata.version", BundleYAML)
return fmt.Errorf("%s is missing required field: metadata.version", config.BundleYAML)
}
if bundle.Metadata.Name == "" {
return fmt.Errorf("%s is missing required field: metadata.name", BundleYAML)
return fmt.Errorf("%s is missing required field: metadata.name", config.BundleYAML)
}

if len(bundle.ZarfPackages) == 0 {
return fmt.Errorf("%s is missing required list: packages", BundleYAML)
return fmt.Errorf("%s is missing required list: packages", config.BundleYAML)
}

if err := validateBundleVars(bundle.ZarfPackages); err != nil {
Expand Down Expand Up @@ -129,7 +129,7 @@ func (b *Bundler) ValidateBundleResources(bundle *types.UDSBundle) error {
}

if pkg.Ref == "" {
return fmt.Errorf("%s .packages[%s] is missing required field: ref", BundleYAML, pkg.Repository)
return fmt.Errorf("%s .packages[%s] is missing required field: ref", config.BundleYAML, pkg.Repository)
}

zarfYAML := zarfTypes.ZarfPackage{}
Expand Down Expand Up @@ -202,7 +202,7 @@ func (b *Bundler) ValidateBundleResources(bundle *types.UDSBundle) error {
// make sure if a wildcard is given, it is the first and only element
for idx, component := range pkg.OptionalComponents {
if (component == "*" && idx != 0) || (component == "*" && len(pkg.OptionalComponents) > 1) {
return fmt.Errorf("%s .packages[%s].optional-components[%d] wildcard '*' must be first and only item", BundleYAML, pkg.Repository, idx)
return fmt.Errorf("%s .packages[%s].optional-components[%d] wildcard '*' must be first and only item", config.BundleYAML, pkg.Repository, idx)
}
}

Expand Down Expand Up @@ -262,11 +262,11 @@ func (b *Bundler) ValidateBundleResources(bundle *types.UDSBundle) error {
})
// make sure the component exists
if c.Name == "" {
return fmt.Errorf("%s .packages[%s].components[%s] does not exist in upstream: %s", BundleYAML, pkg.Repository, component, url)
return fmt.Errorf("%s .packages[%s].components[%s] does not exist in upstream: %s", config.BundleYAML, pkg.Repository, component, url)
}
// make sure the component supports the bundle's target architecture
if c.Only.Cluster.Architecture != "" && c.Only.Cluster.Architecture != bundle.Metadata.Architecture {
return fmt.Errorf("%s .packages[%s].components[%s] does not support architecture: %s", BundleYAML, pkg.Repository, component, bundle.Metadata.Architecture)
return fmt.Errorf("%s .packages[%s].components[%s] does not support architecture: %s", config.BundleYAML, pkg.Repository, component, bundle.Metadata.Architecture)
}
}
}
Expand Down Expand Up @@ -305,15 +305,7 @@ func validateBundleVars(packages []types.BundleZarfPackage) error {
// this is mainly mirrored from packager.writeYaml()
func (b *Bundler) CalculateBuildInfo() error {
now := time.Now()

// Just use $USER env variable to avoid CGO issue.
// https://groups.google.com/g/golang-dev/c/ZFDDX3ZiJ84.
// Record the name of the user creating the package.
if runtime.GOOS == "windows" {
b.bundle.Build.User = os.Getenv("USERNAME")
} else {
b.bundle.Build.User = os.Getenv("USER")
}
b.bundle.Build.User = os.Getenv("USER")

hostname, err := os.Hostname()
if err != nil {
Expand All @@ -335,7 +327,7 @@ func (b *Bundler) CalculateBuildInfo() error {
// ValidateBundleSignature validates the bundle signature
func ValidateBundleSignature(bundleYAMLPath, signaturePath, publicKeyPath string) error {
if utils.InvalidPath(bundleYAMLPath) {
return fmt.Errorf("path for %s at %s does not exist", BundleYAML, bundleYAMLPath)
return fmt.Errorf("path for %s at %s does not exist", config.BundleYAML, bundleYAMLPath)
}
// The package is not signed, and no public key was provided
if signaturePath == "" && publicKeyPath == "" {
Expand Down
Loading

0 comments on commit 3cae2b1

Please sign in to comment.