/
bundle.go
359 lines (319 loc) · 16.5 KB
/
bundle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
package main
import (
"github.com/spf13/cobra"
"get.porter.sh/porter/pkg/porter"
)
func buildBundleCommands(p *porter.Porter) *cobra.Command {
cmd := &cobra.Command{
Use: "bundles",
Aliases: []string{"bundle"},
Short: "Bundle commands",
Long: "Commands for working with bundles. These all have shortcuts so that you can call these commands without the bundle resource prefix. For example, porter bundle install is available as porter install as well.",
}
cmd.Annotations = map[string]string{
"group": "resource",
}
cmd.AddCommand(buildBundleCreateCommand(p))
cmd.AddCommand(buildBundleBuildCommand(p))
cmd.AddCommand(buildBundleLintCommand(p))
cmd.AddCommand(buildBundleInstallCommand(p))
cmd.AddCommand(buildBundleUpgradeCommand(p))
cmd.AddCommand(buildBundleInvokeCommand(p))
cmd.AddCommand(buildBundleUninstallCommand(p))
cmd.AddCommand(buildBundleArchiveCommand(p))
cmd.AddCommand(buildBundleExplainCommand(p))
cmd.AddCommand(buildBundleCopyCommand(p))
cmd.AddCommand(buildBundleInspectCommand(p))
return cmd
}
func buildBundleCreateCommand(p *porter.Porter) *cobra.Command {
return &cobra.Command{
Use: "create",
Short: "Create a bundle",
Long: "Create a bundle. This generates a porter bundle in the current directory.",
RunE: func(cmd *cobra.Command, args []string) error {
return p.Create()
},
}
}
func buildBundleBuildCommand(p *porter.Porter) *cobra.Command {
opts := porter.BuildOptions{}
cmd := &cobra.Command{
Use: "build",
Short: "Build a bundle",
Long: "Builds the bundle in the current directory by generating a Dockerfile and a CNAB bundle.json, and then building the invocation image.",
RunE: func(cmd *cobra.Command, args []string) error {
return p.Build(opts)
},
}
f := cmd.Flags()
f.BoolVar(&opts.NoLint, "no-lint", false, "Do not run the linter")
f.BoolVarP(&opts.Verbose, "verbose", "v", false, "Enable verbose logging")
return cmd
}
func buildBundleLintCommand(p *porter.Porter) *cobra.Command {
var opts porter.LintOptions
cmd := &cobra.Command{
Use: "lint",
Short: "Lint a bundle",
Long: `Check the bundle for problems and adherence to best practices by running linters for porter and the mixins used in the bundle.
The lint command is run automatically when you build a bundle. The command is available separately so that you can just lint your bundle without also building it.`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.PrintLintResults(opts)
},
}
f := cmd.Flags()
f.StringVarP(&opts.File, "file", "f", "",
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
f.StringVarP(&opts.RawFormat, "output", "o", "plaintext",
"Specify an output format. Allowed values: "+porter.AllowedLintFormats.String())
f.BoolVarP(&opts.Verbose, "verbose", "v", false,
"Enable verbose logging")
return cmd
}
func buildBundleInstallCommand(p *porter.Porter) *cobra.Command {
opts := porter.InstallOptions{}
cmd := &cobra.Command{
Use: "install [INSTALLATION]",
Short: "Create a new installation of a bundle",
Long: `Create a new installation of a bundle.
The first argument is the name of the installation to create. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle install
porter bundle install MyAppInDev --file myapp/bundle.json
porter bundle install --parameter-set azure --param test-mode=true --param header-color=blue
porter bundle install --cred azure --cred kubernetes
porter bundle install --driver debug
porter bundle install MyAppFromTag --tag getporter/kubernetes:v0.1.0
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.InstallBundle(opts)
},
}
f := cmd.Flags()
f.BoolVar(&opts.AllowAccessToDockerHost, "allow-docker-host-access", false,
"Controls if the bundle should have access to the host's Docker daemon with elevated privileges. See https://porter.sh/configuration/#allow-docker-host-access for the full implications of this flag.")
f.StringVarP(&opts.File, "file", "f", "",
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
f.StringVar(&opts.CNABFile, "cnab-file", "",
"Path to the CNAB bundle.json file.")
f.StringSliceVarP(&opts.ParameterSets, "parameter-set", "p", nil,
"Name of a parameter set file for the bundle. May be either a named set of parameters or a filepath, and specified multiple times.")
f.StringSliceVar(&opts.Params, "param", nil,
"Define an individual parameter in the form NAME=VALUE. Overrides parameters otherwise set via --parameter-set. May be specified multiple times.")
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
f.StringVarP(&opts.Driver, "driver", "d", porter.DefaultDriver,
"Specify a driver to use. Allowed values: docker, debug")
f.StringVarP(&opts.Tag, "tag", "t", "",
"Use a bundle in an OCI registry specified by the given tag")
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
"Don't require TLS for the registry")
f.BoolVar(&opts.Force, "force", false,
"Force a fresh pull of the bundle and all dependencies")
return cmd
}
func buildBundleUpgradeCommand(p *porter.Porter) *cobra.Command {
opts := porter.UpgradeOptions{}
cmd := &cobra.Command{
Use: "upgrade [INSTALLATION]",
Short: "Upgrade an installation",
Long: `Upgrade an installation.
The first argument is the installation name to upgrade. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle upgrade
porter bundle upgrade MyAppInDev --file myapp/bundle.json
porter bundle upgrade --parameter-set azure --param test-mode=true --param header-color=blue
porter bundle upgrade --cred azure --cred kubernetes
porter bundle upgrade --driver debug
porter bundle upgrade MyAppFromTag --tag getporter/kubernetes:v0.1.0
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.UpgradeBundle(opts)
},
}
f := cmd.Flags()
f.BoolVar(&opts.AllowAccessToDockerHost, "allow-docker-host-access", false,
"Controls if the bundle should have access to the host's Docker daemon with elevated privileges. See https://porter.sh/configuration/#allow-docker-host-access for the full implications of this flag.")
f.StringVarP(&opts.File, "file", "f", "",
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
f.StringVar(&opts.CNABFile, "cnab-file", "",
"Path to the CNAB bundle.json file.")
f.StringSliceVarP(&opts.ParameterSets, "parameter-set", "p", nil,
"Name of a parameter set file for the bundle. May be either a named set of parameters or a filepath, and specified multiple times.")
f.StringSliceVar(&opts.Params, "param", nil,
"Define an individual parameter in the form NAME=VALUE. Overrides parameters otherwise set via --parameter-set. May be specified multiple times.")
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
f.StringVarP(&opts.Driver, "driver", "d", porter.DefaultDriver,
"Specify a driver to use. Allowed values: docker, debug")
f.StringVarP(&opts.Tag, "tag", "t", "",
"Use a bundle in an OCI registry specified by the given tag")
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
"Don't require TLS for the registry")
f.BoolVar(&opts.Force, "force", false,
"Force a fresh pull of the bundle and all dependencies")
return cmd
}
func buildBundleInvokeCommand(p *porter.Porter) *cobra.Command {
opts := porter.InvokeOptions{}
cmd := &cobra.Command{
Use: "invoke [INSTALLATION] --action ACTION",
Short: "Invoke a custom action on an installation",
Long: `Invoke a custom action on an installation.
The first argument is the installation name upon which to invoke the action. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle invoke --action ACTION
porter bundle invoke --action ACTION MyAppInDev --file myapp/bundle.json
porter bundle invoke --action ACTION --parameter-set azure --param test-mode=true --param header-color=blue
porter bundle invoke --action ACTION --cred azure --cred kubernetes
porter bundle invoke --action ACTION --driver debug
porter bundle invoke --action ACTION MyAppFromTag --tag getporter/kubernetes:v0.1.0
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.InvokeBundle(opts)
},
}
f := cmd.Flags()
f.BoolVar(&opts.AllowAccessToDockerHost, "allow-docker-host-access", false,
"Controls if the bundle should have access to the host's Docker daemon with elevated privileges. See https://porter.sh/configuration/#allow-docker-host-access for the full implications of this flag.")
f.StringVar(&opts.Action, "action", "",
"Custom action name to invoke.")
f.StringVarP(&opts.File, "file", "f", "",
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
f.StringVar(&opts.CNABFile, "cnab-file", "",
"Path to the CNAB bundle.json file.")
f.StringSliceVarP(&opts.ParameterSets, "parameter-set", "p", nil,
"Name of a parameter set file for the bundle. May be either a named set of parameters or a filepath, and specified multiple times.")
f.StringSliceVar(&opts.Params, "param", nil,
"Define an individual parameter in the form NAME=VALUE. Overrides parameters otherwise set via --parameter-set. May be specified multiple times.")
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
f.StringVarP(&opts.Driver, "driver", "d", porter.DefaultDriver,
"Specify a driver to use. Allowed values: docker, debug")
f.StringVarP(&opts.Tag, "tag", "t", "",
"Use a bundle in an OCI registry specified by the given tag")
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
"Don't require TLS for the registry")
f.BoolVar(&opts.Force, "force", false,
"Force a fresh pull of the bundle and all dependencies")
return cmd
}
func buildBundleUninstallCommand(p *porter.Porter) *cobra.Command {
opts := porter.UninstallOptions{}
cmd := &cobra.Command{
Use: "uninstall [INSTALLATION]",
Short: "Uninstall an installation",
Long: `Uninstall an installation
The first argument is the installation name to uninstall. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle uninstall
porter bundle uninstall MyAppInDev --file myapp/bundle.json
porter bundle uninstall --parameter-set azure --param test-mode=true --param header-color=blue
porter bundle uninstall --cred azure --cred kubernetes
porter bundle uninstall --driver debug
porter bundle uninstall MyAppFromTag --tag getporter/kubernetes:v0.1.0
porter bundle uninstall --delete
porter bundle uninstall --force-delete
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.UninstallBundle(opts)
},
}
f := cmd.Flags()
f.BoolVar(&opts.AllowAccessToDockerHost, "allow-docker-host-access", false,
"Controls if the bundle should have access to the host's Docker daemon with elevated privileges. See https://porter.sh/configuration/#allow-docker-host-access for the full implications of this flag.")
f.StringVarP(&opts.File, "file", "f", "",
"Path to the porter manifest file. Defaults to the bundle in the current directory. Optional unless a newer version of the bundle should be used to uninstall the bundle.")
f.StringVar(&opts.CNABFile, "cnab-file", "",
"Path to the CNAB bundle.json file.")
f.StringSliceVarP(&opts.ParameterSets, "parameter-set", "p", nil,
"Name of a parameter set file for the bundle. May be either a named set of parameters or a filepath, and specified multiple times.")
f.StringSliceVar(&opts.Params, "param", nil,
"Define an individual parameter in the form NAME=VALUE. Overrides parameters otherwise set via --parameter-set. May be specified multiple times.")
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
"Credential to use when uninstalling the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
f.StringVarP(&opts.Driver, "driver", "d", porter.DefaultDriver,
"Specify a driver to use. Allowed values: docker, debug")
f.StringVarP(&opts.Tag, "tag", "t", "",
"Use a bundle in an OCI registry specified by the given tag")
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
"Don't require TLS for the registry")
f.BoolVar(&opts.Force, "force", false,
"Force a fresh pull of the bundle and all dependencies")
f.BoolVar(&opts.Delete, "delete", false,
"Delete all records associated with the installation, assuming the uninstall action succeeds")
f.BoolVar(&opts.ForceDelete, "force-delete", false,
"UNSAFE. Delete all records associated with the installation, even if uninstall fails. This is intended for cleaning up test data and is not recommended for production environments.")
return cmd
}
func buildBundlePublishCommand(p *porter.Porter) *cobra.Command {
opts := porter.PublishOptions{}
cmd := cobra.Command{
Use: "publish",
Short: "Publish a bundle",
Long: "Publishes a bundle by pushing the invocation image and bundle to a registry.",
Example: ` porter bundle publish
porter bundle publish --file myapp/porter.yaml
porter bundle publish --archive /tmp/mybuns.tgz --tag myrepo/my-buns:0.1.0
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Publish(opts)
},
}
f := cmd.Flags()
f.StringVarP(&opts.File, "file", "f", "", "Path to the Porter manifest. Defaults to `porter.yaml` in the current directory.")
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false, "Don't require TLS for the registry.")
f.StringVarP(&opts.ArchiveFile, "archive", "a", "", "Path to the bundle archive in .tgz format")
f.StringVarP(&opts.Tag, "tag", "t", "", "Bundle tag for newly published bundle; required if --archive is supplied")
return &cmd
}
func buildBundleArchiveCommand(p *porter.Porter) *cobra.Command {
opts := porter.ArchiveOptions{}
cmd := cobra.Command{
Use: "archive FILENAME",
Short: "Archive a bundle",
Long: "Archives a bundle by generating a gzipped tar archive containing the bundle, invocation image and any referenced images.",
Example: ` porter bundle archive mybun.tgz
porter bundle archive mybun.tgz --file another/porter.yaml
porter bundle archive mybun.tgz --cnab-file some/bundle.json
porter bundle archive mybun.tgz --tag repo/bundle:tag
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Archive(opts)
},
}
f := cmd.Flags()
f.StringVarP(&opts.File, "file", "f", "", "Path to the Porter manifest. Defaults to `porter.yaml` in the current directory.")
f.StringVar(&opts.CNABFile, "cnab-file", "", "Path to the CNAB bundle.json file.")
f.StringVarP(&opts.Tag, "tag", "t", "",
"Use a bundle in an OCI registry specified by the given tag")
f.BoolVar(&opts.Force, "force", false,
"Force a fresh pull of the bundle")
return &cmd
}