Skip to content

Commit c055bd1

Browse files
authored
Add tmpdir command flag and refactor CommonOptions (zarf-dev#600)
* Add tmpdir command flag and refactor CommonOptions * Add docs for tmpdir command flag * Add tests for package create, inspect and deploy with --tmpdir * Refactor package deploy test for --tmpdir * Simplify test for --tmpdir in package deploy
1 parent 374e136 commit c055bd1

17 files changed

+97
-28
lines changed

.golangci.yml

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ linters:
1414
- varnamelen
1515
- wrapcheck
1616
- wsl
17+
- paralleltest
18+
- gochecknoglobals
1719
issues:
1820
exclude-use-default: false
1921
new: true

docs/4-user-guide/1-the-zarf-cli/100-cli-commands/2-package/zarf_package_create.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ zarf package create [flags]
1010

1111
```
1212
--confirm Confirm package creation without prompting
13+
--tmpdir Specify the temporary directory to use for intermediate files
1314
-h, --help help for create
1415
--skip-sbom Skip generating SBOM for this package
1516
--zarf-cache string Specify the location of the Zarf image cache (default ".zarf-image-cache")

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

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ zarf package deploy [PACKAGE] [flags]
1111
```
1212
--components string Comma-separated list of components to install. Adding this flag will skip the init prompts for which components to install
1313
--confirm Confirm package deployment without prompting
14+
--tmpdir Specify the temporary directory to use for intermediate files
1415
-h, --help help for deploy
1516
--insecure --shasum Skip shasum validation of remote package. Required if deploying a remote package and --shasum is not provided
1617
--shasum --insecure Shasum of the package to deploy. Required if deploying a remote package and --insecure is not provided

docs/4-user-guide/1-the-zarf-cli/100-cli-commands/2-package/zarf_package_inspect.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ zarf package inspect [PACKAGE] [flags]
99
### Options
1010

1111
```
12-
-h, --help help for inspect
12+
--tmpdir Specify the temporary directory to use for intermediate files
13+
-h, --help help for inspect
1314
```
1415

1516
### Options inherited from parent commands

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

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ zarf init [flags]
1515
```
1616
--components string Comma-separated list of components to install. Adding this flag will skip the init prompts for which components to install
1717
--confirm Confirm the install without prompting
18+
--tmpdir Specify the temporary directory to use for intermediate files
1819
-h, --help help for init
1920
--nodeport string Nodeport to access the Zarf container registry. Between [30000-32767]
2021
--secret string Root secret value that is used to 'seed' other secrets

src/cmd/initialize.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var initCmd = &cobra.Command{
5454
// If the init-package doesn't exist in the executable directory, suggest trying to download
5555
if utils.InvalidPath(config.DeployOptions.PackagePath) {
5656

57-
if config.DeployOptions.Confirm {
57+
if config.CommonOptions.Confirm {
5858
message.Fatalf(nil, "This command requires a zarf-init package, but one was not found on the local system.")
5959
}
6060

@@ -100,7 +100,8 @@ var initCmd = &cobra.Command{
100100

101101
func init() {
102102
rootCmd.AddCommand(initCmd)
103-
initCmd.Flags().BoolVar(&config.DeployOptions.Confirm, "confirm", false, "Confirm the install without prompting")
103+
initCmd.Flags().BoolVar(&config.CommonOptions.Confirm, "confirm", false, "Confirm the install without prompting")
104+
initCmd.Flags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", "", "Specify the temporary directory to use for intermediate files")
104105
initCmd.Flags().StringVar(&config.DeployOptions.Components, "components", "", "Comma-separated list of components to install.")
105106
initCmd.Flags().StringVar(&config.DeployOptions.StorageClass, "storage-class", "", "Describe the StorageClass to be used")
106107
initCmd.Flags().StringVar(&config.DeployOptions.Secret, "secret", "", "Root secret value that is used to 'seed' other secrets")

src/cmd/package.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,19 @@ func init() {
108108
packageCmd.AddCommand(packageDeployCmd)
109109
packageCmd.AddCommand(packageInspectCmd)
110110

111-
packageCreateCmd.Flags().BoolVar(&config.DeployOptions.Confirm, "confirm", false, "Confirm package creation without prompting")
111+
packageCreateCmd.Flags().BoolVar(&config.CommonOptions.Confirm, "confirm", false, "Confirm package creation without prompting")
112+
packageCreateCmd.Flags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", "", "Specify the temporary directory to use for intermediate files")
112113
packageCreateCmd.Flags().StringVar(&zarfImageCache, "zarf-cache", config.ZarfDefaultImageCachePath, "Specify the location of the Zarf image cache")
113114
packageCreateCmd.Flags().StringVarP(&config.CreateOptions.OutputDirectory, "output-directory", "o", "", "Specify the output directory for the created Zarf package")
114115
packageCreateCmd.Flags().BoolVar(&config.CreateOptions.SkipSBOM, "skip-sbom", false, "Skip generating SBOM for this package")
115116
packageCreateCmd.Flags().BoolVar(&config.CreateOptions.Insecure, "insecure", false, "Allow insecure registry connections when pulling OCI images")
116117

117-
packageDeployCmd.Flags().BoolVar(&config.DeployOptions.Confirm, "confirm", false, "Confirm package deployment without prompting")
118+
packageDeployCmd.Flags().BoolVar(&config.CommonOptions.Confirm, "confirm", false, "Confirm package deployment without prompting")
119+
packageDeployCmd.Flags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", "", "Specify the temporary directory to use for intermediate files")
118120
packageDeployCmd.Flags().StringVar(&config.DeployOptions.Components, "components", "", "Comma-separated list of components to install. Adding this flag will skip the init prompts for which components to install")
119121
packageDeployCmd.Flags().BoolVar(&insecureDeploy, "insecure", false, "Skip shasum validation of remote package. Required if deploying a remote package and `--shasum` is not provided")
120122
packageDeployCmd.Flags().StringVar(&shasum, "shasum", "", "Shasum of the package to deploy. Required if deploying a remote package and `--insecure` is not provided")
121-
122123
packageDeployCmd.Flags().StringVar(&config.DeployOptions.SGetKeyPath, "sget", "", "Path to public sget key file for remote packages signed via cosign")
124+
125+
packageInspectCmd.Flags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", "", "Specify the temporary directory to use for intermediate files")
123126
}

src/cmd/prepare.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"io/ioutil"
66

7+
"github.com/defenseunicorns/zarf/src/config"
78
"github.com/defenseunicorns/zarf/src/internal/packager"
89

910
"github.com/AlecAivazis/survey/v2"
@@ -20,11 +21,11 @@ var prepareCmd = &cobra.Command{
2021
}
2122

2223
var prepareTransformGitLinks = &cobra.Command{
23-
Use: "patch-git [HOST] [FILE]",
24+
Use: "patch-git [HOST] [FILE]",
2425
Aliases: []string{"p"},
2526
Short: "Converts all .git URLs to the specified Zarf HOST and with the Zarf URL pattern in a given FILE. NOTE: \n" +
26-
"This should only be used for manifests that are not mutated by the Zarf Agent Mutating Webhook.",
27-
Args: cobra.ExactArgs(2),
27+
"This should only be used for manifests that are not mutated by the Zarf Agent Mutating Webhook.",
28+
Args: cobra.ExactArgs(2),
2829
Run: func(cmd *cobra.Command, args []string) {
2930
host, fileName := args[0], args[1]
3031

@@ -57,10 +58,10 @@ var prepareTransformGitLinks = &cobra.Command{
5758
}
5859

5960
var prepareComputeFileSha256sum = &cobra.Command{
60-
Use: "sha256sum [FILE|URL]",
61+
Use: "sha256sum [FILE|URL]",
6162
Aliases: []string{"s"},
62-
Short: "Generate a SHA256SUM for the given file",
63-
Args: cobra.ExactArgs(1),
63+
Short: "Generate a SHA256SUM for the given file",
64+
Args: cobra.ExactArgs(1),
6465
Run: func(cmd *cobra.Command, args []string) {
6566
fileName := args[0]
6667
hash, err := utils.GetSha256Sum(fileName)
@@ -75,7 +76,7 @@ var prepareComputeFileSha256sum = &cobra.Command{
7576
var prepareFindImages = &cobra.Command{
7677
Use: "find-images",
7778
Aliases: []string{"f"},
78-
Args: cobra.MaximumNArgs(1),
79+
Args: cobra.MaximumNArgs(1),
7980
Short: "Evaluates components in a zarf file to identify images specified in their helm charts and manifests",
8081
Long: "Evaluates components in a zarf file to identify images specified in their helm charts and manifests.\n\n" +
8182
"Components that have repos that host helm charts can be processed by providing the --repo-chart-path.",
@@ -98,5 +99,5 @@ func init() {
9899
prepareCmd.AddCommand(prepareFindImages)
99100

100101
prepareFindImages.Flags().StringVarP(&repoHelmChartPath, "repo-chart-path", "p", "", `If git repos hold helm charts, often found with gitops tools, specify the chart path, e.g. "/" or "/chart"`)
101-
102+
prepareFindImages.Flags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", "", "Specify the temporary directory to use for intermediate files")
102103
}

src/config/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ var (
4949
// CLIVersion track the version of the CLI
5050
CLIVersion = "unset"
5151

52+
// CommonOptions tracks user-defined values that apply across commands.
53+
CommonOptions types.ZarfCommonOptions
54+
5255
// CreeateOptions tracks the user-defined options used to create the package
5356
CreateOptions types.ZarfCreateOptions
5457

src/internal/git/pull.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package git
33
import (
44
"context"
55

6+
"github.com/defenseunicorns/zarf/src/config"
67
"github.com/defenseunicorns/zarf/src/internal/message"
78
"github.com/defenseunicorns/zarf/src/internal/utils"
89
"github.com/go-git/go-git/v5"
@@ -14,7 +15,7 @@ import (
1415
const onlineRemoteName = "online-upstream"
1516

1617
func DownloadRepoToTemp(gitUrl string, spinner *message.Spinner) string {
17-
path, _ := utils.MakeTempDir()
18+
path, _ := utils.MakeTempDir(config.CommonOptions.TempDirectory)
1819
// If downloading to temp, grab all tags since the repo isn't being
1920
// packaged anyway, and it saves us from having to fetch the tags
2021
// later if we need them

src/internal/helm/post-render.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func NewRenderer(options ChartOptions, actionConfig *action.Configuration) *rend
4343
func (r *renderer) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
4444
message.Debugf("helm.Run(renderedManifests *bytes.Buffer)")
4545
// This is very low cost and consistent for how we replace elsewhere, also good for debugging
46-
tempDir, _ := utils.MakeTempDir()
46+
tempDir, _ := utils.MakeTempDir(config.CommonOptions.TempDirectory)
4747
path := tempDir + "/chart.yaml"
4848

4949
// Write the context to a file for processing

src/internal/packager/common.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type tempPaths struct {
4242
}
4343

4444
func createPaths() tempPaths {
45-
basePath, _ := utils.MakeTempDir()
45+
basePath, _ := utils.MakeTempDir(config.CommonOptions.TempDirectory)
4646
return tempPaths{
4747
base: basePath,
4848

@@ -98,9 +98,10 @@ func confirmAction(configPath, userMessage string, sbomViewFiles []string) bool
9898

9999
// Display prompt if not auto-confirmed
100100
var confirmFlag bool
101-
if config.DeployOptions.Confirm {
101+
if config.CommonOptions.Confirm {
102102
message.Infof("%s Zarf package confirmed", userMessage)
103-
return config.DeployOptions.Confirm
103+
104+
return config.CommonOptions.Confirm
104105
} else {
105106
prompt := &survey.Confirm{
106107
Message: userMessage + " this Zarf package?",

src/internal/packager/components.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func isRequiredOrRequested(component types.ZarfComponent, requestedComponentName
123123
return true
124124
} else {
125125
// Otherwise,check if this is one of the components that has been requested
126-
if len(requestedComponentNames) > 0 || config.DeployOptions.Confirm {
126+
if len(requestedComponentNames) > 0 || config.CommonOptions.Confirm {
127127
for _, requestedComponent := range requestedComponentNames {
128128
// If the component name matches one of the requested components, then return true
129129
if strings.ToLower(requestedComponent) == component.Name {
@@ -140,7 +140,7 @@ func isRequiredOrRequested(component types.ZarfComponent, requestedComponentName
140140
// Confirm optional component
141141
func confirmOptionalComponent(component types.ZarfComponent) (confirmComponent bool) {
142142
// Confirm flag passed, just use defaults
143-
if config.DeployOptions.Confirm {
143+
if config.CommonOptions.Confirm {
144144
return component.Default
145145
}
146146

@@ -165,7 +165,7 @@ func confirmOptionalComponent(component types.ZarfComponent) (confirmComponent b
165165

166166
func confirmChoiceGroup(componentGroup []types.ZarfComponent) types.ZarfComponent {
167167
// Confirm flag passed, just use defaults
168-
if config.DeployOptions.Confirm {
168+
if config.CommonOptions.Confirm {
169169
var componentNames []string
170170
for _, component := range componentGroup {
171171
// If the component is default, then return it

src/internal/utils/io.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717

1818
var TempPathPrefix = "zarf-"
1919

20-
func MakeTempDir() (string, error) {
21-
tmp, err := ioutil.TempDir("", TempPathPrefix)
20+
func MakeTempDir(tmpDir string) (string, error) {
21+
tmp, err := ioutil.TempDir(tmpDir, TempPathPrefix)
2222
message.Debugf("Creating temp path %s", tmp)
2323
return tmp, err
2424
}

src/test/e2e/00_use_cli_test.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ func TestUseCLI(t *testing.T) {
2525
// output, err = exec.Command("bash", "-c", "\"echo 'random test data 🦄' > shasum-test-file\"").Output()
2626
shasumTestFilePath := "shasum-test-file"
2727

28-
// run `zarf create` with a specified image cache location
28+
// run `zarf package create` with a specified image cache location
2929
imageCachePath := "/tmp/.image_cache-location"
3030

31-
e2e.cleanFiles(shasumTestFilePath, imageCachePath)
31+
// run `zarf package create` with a specified tmp location
32+
otherTmpPath := "/tmp/othertmp"
33+
34+
e2e.cleanFiles(shasumTestFilePath, imageCachePath, otherTmpPath)
3235

3336
testfile, _ := os.Create(shasumTestFilePath)
3437
cmd := exec.Command("echo", "random test data 🦄")
@@ -69,14 +72,28 @@ func TestUseCLI(t *testing.T) {
6972
// TODO: remove this once #511 is merged
7073
_ = os.Chdir("examples/game")
7174
tmpBin := fmt.Sprintf("../../%s", e2e.zarfBinPath)
75+
pkgName := fmt.Sprintf("zarf-package-dos-games-%s.tar.zst", e2e.arch)
76+
7277
stdOut, stdErr, err = utils.ExecCommandWithContext(context.TODO(), true, tmpBin, "package", "create", "examples/game", "--confirm", "--zarf-cache", imageCachePath)
7378
require.NoError(t, err, stdOut, stdErr)
79+
80+
stdOut, stdErr, err = utils.ExecCommandWithContext(context.TODO(), true, tmpBin, "package", "inspect", pkgName)
81+
require.NoError(t, err, stdOut, stdErr)
82+
83+
_ = os.Mkdir(otherTmpPath, 0750)
84+
stdOut, stdErr, err = utils.ExecCommandWithContext(context.TODO(), true, tmpBin, "package", "create", "examples/game", "--confirm", "--zarf-cache", imageCachePath, "--tmpdir", otherTmpPath, "--log-level=debug")
85+
require.Contains(t, stdErr, otherTmpPath, "The other tmp path should show as being created")
86+
require.NoError(t, err, stdOut, stdErr)
87+
88+
stdOut, stdErr, err = utils.ExecCommandWithContext(context.TODO(), true, tmpBin, "package", "inspect", pkgName, "--tmpdir", otherTmpPath, "--log-level=debug")
89+
require.Contains(t, stdErr, otherTmpPath, "The other tmp path should show as being created")
90+
require.NoError(t, err, stdOut, stdErr)
7491
// Reset temp chdir
7592
_ = os.Chdir("../..")
7693

7794
files, err := ioutil.ReadDir(imageCachePath)
7895
require.NoError(t, err, "Error when reading image cache path")
7996
assert.Greater(t, len(files), 1)
8097

81-
e2e.cleanFiles(shasumTestFilePath, imageCachePath)
98+
e2e.cleanFiles(shasumTestFilePath, imageCachePath, otherTmpPath)
8299
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestTempDirectoryDeploy(t *testing.T) {
12+
t.Log("E2E: Temporary directory deploy")
13+
14+
// run `zarf package deploy` with a specified tmp location
15+
otherTmpPath := "/tmp/othertmp"
16+
17+
e2e.setup(t)
18+
defer e2e.teardown(t)
19+
20+
e2e.cleanFiles(otherTmpPath)
21+
22+
path := fmt.Sprintf("build/zarf-package-component-choice-%s.tar.zst", e2e.arch)
23+
24+
_ = os.Mkdir(otherTmpPath, 0750)
25+
26+
stdOut, stdErr, err := e2e.execZarfCommand("package", "deploy", path, "--confirm", "--tmpdir", otherTmpPath, "--log-level=debug")
27+
require.Contains(t, stdErr, otherTmpPath, "The other tmp path should show as being created")
28+
require.NoError(t, err, stdOut, stdErr)
29+
30+
e2e.cleanFiles(otherTmpPath)
31+
}

src/types/runtime.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package types
22

3+
// ZarfCommonOptions tracks the user-defined preferences used across commands.
4+
type ZarfCommonOptions struct {
5+
Confirm bool
6+
TempDirectory string
7+
}
8+
39
// ZarfDeployOptions tracks the user-defined preferences during a package deployment
410
type ZarfDeployOptions struct {
511
PackagePath string
6-
Confirm bool
712
Components string
813
SGetKeyPath string
914

0 commit comments

Comments
 (0)