Skip to content

Commit

Permalink
feat: dev deploy remote bundles (#629)
Browse files Browse the repository at this point in the history
  • Loading branch information
decleaver committed May 28, 2024
1 parent a0ab70c commit 828da75
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 45 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,18 +278,19 @@ UDS CLI includes a vendored version of Zarf inside of its binary. To use Zarf, s
## Dev Mode

> [!NOTE]
> Dev mode is a BETA feature and currently only works with local bundles
> Dev mode is a BETA feature
Dev mode facilitates faster dev cycles when developing and testing bundles

```
uds dev deploy <path-to-bundle-yaml-dir>
uds dev deploy <path-to-bundle-yaml-dir> | <oci-ref>
```

The `dev deploy` command performs the following operations
- Creates Zarf packages for all local packages in a bundle

- If local bundle: Creates Zarf packages for all local packages in a bundle
- Creates the Zarf tarball in the same directory as the `zarf.yaml`
- Will only create the Zarf tarball if one does not already exist
- Ignores any `kind: ZarfInitConfig` packages in the bundle
- Creates a bundle from the newly created Zarf packages
- Creates a bundle from the newly created Zarf packages
- Deploys the bundle in [YOLO](https://docs.zarf.dev/faq/#what-is-yolo-mode-and-why-would-i-use-it) mode, eliminating the need to do a `zarf init`
56 changes: 31 additions & 25 deletions src/cmd/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
package cmd

import (
"os"

"github.com/defenseunicorns/pkg/helpers"
"github.com/defenseunicorns/uds-cli/src/config"
"github.com/defenseunicorns/uds-cli/src/config/lang"
"github.com/defenseunicorns/zarf/src/pkg/message"
Expand All @@ -25,26 +24,25 @@ var devDeployCmd = &cobra.Command{
Args: cobra.MaximumNArgs(1),
Short: lang.CmdDevDeployShort,
Long: lang.CmdDevDeployLong,
PreRun: func(_ *cobra.Command, args []string) {
setBundleFile(args)
},
Run: func(_ *cobra.Command, args []string) {
config.Dev = true

// Create Bundle
srcDir, err := os.Getwd()
if err != nil {
message.Fatalf(err, "error reading the current working directory")
}
// Get bundle source
src := ""
if len(args) > 0 {
srcDir = args[0]
src = args[0]
}

if len(srcDir) != 0 && srcDir[len(srcDir)-1] != '/' {
srcDir = srcDir + "/"
}
// Check if source is a local bundle
localBundle := helpers.IsDir(src)

if localBundle {
// Create Bundle
setBundleFile(args)

config.CommonOptions.Confirm = true
bundleCfg.CreateOpts.SourceDirectory = srcDir
config.CommonOptions.Confirm = true
bundleCfg.CreateOpts.SourceDirectory = src
}

configureZarf()

Expand All @@ -59,18 +57,24 @@ var devDeployCmd = &cobra.Command{
bndlClient := bundle.NewOrDie(&bundleCfg)
defer bndlClient.ClearPaths()

// Check if local zarf packages need to be created
bndlClient.CreateZarfPkgs()

// Create dev bundle
config.Dev = true
if err := bndlClient.Create(); err != nil {
bndlClient.ClearPaths()
message.Fatalf(err, "Failed to create bundle: %s", err.Error())
if localBundle {
// Check if local zarf packages need to be created
bndlClient.CreateZarfPkgs()

if err := bndlClient.Create(); err != nil {
message.Fatalf(err, "Failed to create bundle: %s", err.Error())
}
}

// Set dev source
if localBundle {
bndlClient.SetDeploySource(src)
} else {
bundleCfg.DeployOpts.Source = src
}

// Deploy dev bundle
bndlClient.SetDevSource(srcDir)
// Deploy bundle
deploy(bndlClient)
},
}
Expand All @@ -80,4 +84,6 @@ func init() {
rootCmd.AddCommand(devCmd)
devCmd.AddCommand(devDeployCmd)
devDeployCmd.Flags().StringArrayVarP(&bundleCfg.DeployOpts.Packages, "packages", "p", []string{}, lang.CmdBundleDeployFlagPackages)
devDeployCmd.Flags().BoolVarP(&config.CommonOptions.Confirm, "confirm", "c", false, lang.CmdBundleDeployFlagConfirm)
devDeployCmd.Flags().StringToStringVar(&bundleCfg.DeployOpts.SetVariables, "set", nil, lang.CmdBundleDeployFlagSet)
}
9 changes: 2 additions & 7 deletions src/pkg/bundle/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ func (b *Bundle) CreateZarfPkgs() {
}
}

// SetDevSource sets the source for the bundle when in dev mode
func (b *Bundle) SetDevSource(srcDir string) {
srcDir = filepath.Dir(srcDir)
// Add a trailing slash if it's missing
if len(srcDir) != 0 && srcDir[len(srcDir)-1] != '/' {
srcDir = srcDir + "/"
}
// SetDeploySource sets the source for the bundle when in dev mode
func (b *Bundle) SetDeploySource(srcDir string) {
filename := fmt.Sprintf("%s%s-%s-%s.tar.zst", config.BundlePrefix, b.bundle.Metadata.Name, b.bundle.Metadata.Architecture, b.bundle.Metadata.Version)
b.cfg.DeployOpts.Source = filepath.Join(srcDir, filename)
}
14 changes: 13 additions & 1 deletion src/pkg/sources/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
// Package sources contains Zarf packager sources
package sources

import zarfTypes "github.com/defenseunicorns/zarf/src/types"
import (
zarfTypes "github.com/defenseunicorns/zarf/src/types"
)

// addNamespaceOverrides checks if pkg components have charts with namespace overrides and adds them
func addNamespaceOverrides(pkg *zarfTypes.ZarfPackage, nsOverrides NamespaceOverrideMap) {
Expand All @@ -21,3 +23,13 @@ func addNamespaceOverrides(pkg *zarfTypes.ZarfPackage, nsOverrides NamespaceOver
}
}
}

// setAsYOLO sets the YOLO flag on a package and strips out all images and repos
func setAsYOLO(pkg *zarfTypes.ZarfPackage) {
pkg.Metadata.YOLO = true
// strip out all images and repos
for idx := range pkg.Components {
pkg.Components[idx].Images = []string{}
pkg.Components[idx].Repos = []string{}
}
}
10 changes: 10 additions & 0 deletions src/pkg/sources/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ func (r *RemoteBundle) LoadPackage(dst *layout.PackagePaths, filter filters.Comp
return zarfTypes.ZarfPackage{}, nil, err
}

// if in dev mode and package is a zarf init config, return an empty package
if config.Dev && pkg.Kind == zarfTypes.ZarfInitConfig {
return zarfTypes.ZarfPackage{}, nil, nil
}

pkg.Components, err = filter.Apply(pkg)
if err != nil {
return pkg, nil, err
Expand Down Expand Up @@ -85,6 +90,11 @@ func (r *RemoteBundle) LoadPackage(dst *layout.PackagePaths, filter filters.Comp
}
}
addNamespaceOverrides(&pkg, r.nsOverrides)

if config.Dev {
setAsYOLO(&pkg)
}

// ensure we're using the correct package name as specified by the bundle
pkg.Metadata.Name = r.PkgName
return pkg, nil, err
Expand Down
7 changes: 1 addition & 6 deletions src/pkg/sources/tarball.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,7 @@ func (t *TarballBundle) LoadPackage(dst *layout.PackagePaths, filter filters.Com
addNamespaceOverrides(&pkg, t.nsOverrides)

if config.Dev {
pkg.Metadata.YOLO = true
// strip out all images and repos
for idx := range pkg.Components {
pkg.Components[idx].Images = []string{}
pkg.Components[idx].Repos = []string{}
}
setAsYOLO(&pkg)
}

packageSpinner.Successf("Loaded bundled Zarf package: %s", t.PkgName)
Expand Down
4 changes: 2 additions & 2 deletions src/test/e2e/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ func deploy(t *testing.T, tarballPath string) (stdout string, stderr string) {
return stdout, stderr
}

func devDeploy(t *testing.T, tarballPath string) (stdout string, stderr string) {
cmd := strings.Split(fmt.Sprintf("dev deploy %s", tarballPath), " ")
func devDeploy(t *testing.T, bundlePath string) (stdout string, stderr string) {
cmd := strings.Split(fmt.Sprintf("dev deploy %s --confirm", bundlePath), " ")
stdout, stderr, err := e2e.UDS(cmd...)
require.NoError(t, err)
return stdout, stderr
Expand Down
22 changes: 22 additions & 0 deletions src/test/e2e/dev_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,26 @@ func TestDevDeploy(t *testing.T) {

remove(t, bundlePath)
})

t.Run("Test dev deploy with remote bundle", func(t *testing.T) {

bundle := "oci://ghcr.io/defenseunicorns/packages/uds-cli/test/publish/ghcr-test:0.0.1"

devDeploy(t, bundle)

deployments, _, _ := e2e.UDS(cmd...)
require.Contains(t, deployments, "podinfo")
require.Contains(t, deployments, "nginx")

remove(t, bundle)
})

t.Run("Test dev deploy with --set flag", func(t *testing.T) {
bundleDir := "src/test/bundles/02-variables"
bundleTarballPath := filepath.Join(bundleDir, fmt.Sprintf("uds-bundle-variables-%s-0.0.1.tar.zst", e2e.Arch))
_, stderr := runCmd(t, "dev deploy "+bundleDir+" --set ANIMAL=Longhorns --set COUNTRY=Texas --confirm -l=debug")
require.Contains(t, stderr, "This fun-fact was imported: Longhorns are the national animal of Texas")
require.NotContains(t, stderr, "This fun-fact was imported: Unicorns are the national animal of Scotland")
remove(t, bundleTarballPath)
})
}

0 comments on commit 828da75

Please sign in to comment.