@@ -32,45 +32,69 @@ import (
32
32
"github.com/zarf-dev/zarf/src/pkg/zoci"
33
33
)
34
34
35
- // TODO: Add options struct
36
- // Pull fetches the Zarf package from the given sources.
37
- func Pull (ctx context.Context , src , dir , shasum , architecture string , filter filters.ComponentFilterStrategy , publicKeyPath string , skipSignatureValidation bool ) error {
38
- if filter == nil {
39
- filter = filters .Empty ()
40
- }
35
+ // PullOptions declares optional configuration for a Pull operation.
36
+ type PullOptions struct {
37
+ // SHASum uniquely identifies a package based on its contents.
38
+ SHASum string
39
+ // SkipSignatureValidation flags whether Pull should skip validating the signature.
40
+ SkipSignatureValidation bool
41
+ // Architecture is the package architecture.
42
+ Architecture string
43
+ // Filters describes a Filter strategy to include or exclude certain components from the package.
44
+ Filters filters.ComponentFilterStrategy
45
+ // PublicKeyPath validates the create-time signage of a package.
46
+ PublicKeyPath string
47
+ }
48
+
49
+ // Pull takes a source URL and destination directory and fetches the Zarf package from the given sources.
50
+ func Pull (ctx context.Context , source , destination string , opts PullOptions ) error {
41
51
l := logger .From (ctx )
42
52
start := time .Now ()
43
- u , err := url .Parse (src )
53
+
54
+ // ensure filters are set
55
+ f := opts .Filters
56
+ if f == nil {
57
+ f = filters .Empty ()
58
+ }
59
+ // ensure architecture is set
60
+ arch := config .GetArch (opts .Architecture )
61
+
62
+ u , err := url .Parse (source )
44
63
if err != nil {
45
64
return err
46
65
}
66
+ if destination == "" {
67
+ return fmt .Errorf ("no output directory specified" )
68
+ }
47
69
if u .Scheme == "" {
48
70
return errors .New ("scheme must be either oci:// or http(s)://" )
49
71
}
50
72
if u .Host == "" {
51
73
return errors .New ("host cannot be empty" )
52
74
}
53
- // ensure architecture is set
54
- architecture = config .GetArch (architecture )
55
75
56
76
tmpDir , err := utils .MakeTempDir (config .CommonOptions .TempDirectory )
57
77
if err != nil {
58
78
return err
59
79
}
60
- defer os .Remove (tmpDir )
80
+ defer func () {
81
+ if rErr := os .Remove (tmpDir ); rErr != nil {
82
+ err = fmt .Errorf ("cleanup failed: %w" , rErr )
83
+ }
84
+ }()
61
85
tmpPath := ""
62
86
63
87
isPartial := false
64
88
switch u .Scheme {
65
89
case "oci" :
66
- l .Info ("starting pull from oci source" , "src " , src )
67
- isPartial , tmpPath , err = pullOCI (ctx , src , tmpDir , shasum , architecture , filter )
90
+ l .Info ("starting pull from oci source" , "source " , source )
91
+ isPartial , tmpPath , err = pullOCI (ctx , source , tmpDir , opts . SHASum , arch , f )
68
92
if err != nil {
69
93
return err
70
94
}
71
95
case "http" , "https" :
72
- l .Info ("starting pull from http(s) source" , "src" , src , "digest" , shasum )
73
- tmpPath , err = pullHTTP (ctx , src , tmpDir , shasum )
96
+ l .Info ("starting pull from http(s) source" , "src" , source , "digest" , opts . SHASum )
97
+ tmpPath , err = pullHTTP (ctx , source , tmpDir , opts . SHASum )
74
98
if err != nil {
75
99
return err
76
100
}
@@ -80,10 +104,10 @@ func Pull(ctx context.Context, src, dir, shasum, architecture string, filter fil
80
104
81
105
// This loadFromTar is done so that validatePackageIntegrtiy and validatePackageSignature are called
82
106
layoutOpt := layout.PackageLayoutOptions {
83
- PublicKeyPath : publicKeyPath ,
84
- SkipSignatureValidation : skipSignatureValidation ,
107
+ PublicKeyPath : opts . PublicKeyPath ,
108
+ SkipSignatureValidation : opts . SkipSignatureValidation ,
85
109
IsPartial : isPartial ,
86
- Filter : filter ,
110
+ Filter : f ,
87
111
}
88
112
_ , err = layout .LoadFromTar (ctx , tmpPath , layoutOpt )
89
113
if err != nil {
@@ -94,7 +118,7 @@ func Pull(ctx context.Context, src, dir, shasum, architecture string, filter fil
94
118
if err != nil {
95
119
return err
96
120
}
97
- tarPath := filepath .Join (dir , name )
121
+ tarPath := filepath .Join (destination , name )
98
122
err = os .Remove (tarPath )
99
123
if err != nil && ! errors .Is (err , os .ErrNotExist ) {
100
124
return err
@@ -103,18 +127,23 @@ func Pull(ctx context.Context, src, dir, shasum, architecture string, filter fil
103
127
if err != nil {
104
128
return err
105
129
}
106
- defer dstFile .Close ()
130
+ defer func () {
131
+ if dstErr := dstFile .Close (); dstErr != nil {
132
+ err = fmt .Errorf ("unable to cleanup: %w" , dstErr )
133
+ }
134
+ }()
107
135
srcFile , err := os .Open (tmpPath )
108
136
if err != nil {
109
137
return err
110
138
}
139
+ // TODO(mkcp): add to error chain
111
140
defer srcFile .Close ()
112
141
_ , err = io .Copy (dstFile , srcFile )
113
142
if err != nil {
114
143
return err
115
144
}
116
145
117
- l .Debug ("done packager2.Pull" , "src " , src , "dir " , dir , "duration" , time .Since (start ))
146
+ l .Debug ("done packager2.Pull" , "source " , source , "destination " , destination , "duration" , time .Since (start ))
118
147
return nil
119
148
}
120
149
0 commit comments