Skip to content

Commit 1c956b4

Browse files
[v1.8.x] fix: build-cmd arg in pkgman-to-bundle (#5036)
* fix: build-cmd arg in pkgman-to-bundle The custom build command in pkgman-to-bundle accepts the input and executes it using `exec.Command()`. However, `exec.Command()` requires the first argument to be the path or name of the binary. This change separates the user input and considers first argument as the path. Signed-off-by: varshaprasad96 <[email protected]> * update docs for pkgman to bundle cmd Signed-off-by: varshaprasad96 <[email protected]> * add example command in doc Signed-off-by: varshaprasad96 <[email protected]> Co-authored-by: varshaprasad96 <[email protected]>
1 parent c88286b commit 1c956b4

File tree

5 files changed

+135
-80
lines changed

5 files changed

+135
-80
lines changed

internal/cmd/operator-sdk/pkgmantobundle/cmd.go

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,36 +74,41 @@ INFO[0000] Creating bundle/bundle-0.0.1/bundle.Dockerfile
7474
INFO[0000] Creating bundle/bundle-0.0.1/metadata/annotations.yaml
7575
...
7676
77-
# After running the above command, the bundles will be generated in 'bundle/' directory.
78-
$ tree bundle/
79-
bundle/
77+
# After running the above command, the bundles will be generated in 'bundles/' directory.
78+
$ tree bundles/
79+
bundles/
8080
├── bundle-0.0.1
81-
│   ├── bundle.Dockerfile
82-
│   ├── manifests
83-
│   │   ├── etcdcluster.crd.yaml
84-
│   │   ├── etcdoperator.clusterserviceversion.yaml
85-
│   ├── metadata
86-
│   │   └── annotations.yaml
87-
│   └── tests
88-
│   └── scorecard
89-
│   └── config.yaml
81+
│   ├── bundle
82+
│   │   ├── manifests
83+
│   │   │   ├── etcdcluster.crd.yaml
84+
│   │   │   ├── etcdoperator.clusterserviceversion.yaml
85+
│   │   ├── metadata
86+
│   │   │   └── annotations.yaml
87+
│   │   └── tests
88+
│   │   └── scorecard
89+
│   │   └── config.yaml
90+
│   └── bundle.Dockerfile
9091
└── bundle-0.0.2
91-
├── bundle.Dockerfile
92-
├── manifests
93-
│   ├── etcdbackup.crd.yaml
94-
│   ├── etcdcluster.crd.yaml
95-
│   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
96-
│   ├── etcdrestore.crd.yaml
97-
├── metadata
98-
│   └── annotations.yaml
99-
└── tests
100-
└── scorecard
101-
└── config.yaml
102-
103-
Also, images for the both the bundles will be built with the following names: quay.io/example/etcd:0.0.1 and quay.io/example/etcd:0.0.2.
92+
├── bundle
93+
│   ├── manifests
94+
│   │   ├── etcdbackup.crd.yaml
95+
│   │   ├── etcdcluster.crd.yaml
96+
│   │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
97+
│   │   ├── etcdrestore.crd.yaml
98+
│   └── metadata
99+
│   └── annotations.yaml
100+
└── bundle.Dockerfile
101+
102+
A custom command to build bundle images can also be specified using the '--build-cmd' flag. For example,
103+
104+
$ operator-sdk pkgman-to-bundle packagemanifests --image-tag-base quay.io/example/etcd --build-cmd "podman build -f bundle.Dockerfile . -t"
105+
106+
Images for the both the bundles will be built with the following names: quay.io/example/etcd:0.0.1 and quay.io/example/etcd:0.0.2.
104107
`
105108
)
106109

110+
var defaultSubBundleDir = "bundle"
111+
107112
type pkgManToBundleCmd struct {
108113
// Input packagemanifest directory.
109114
pkgmanifestDir string
@@ -183,7 +188,7 @@ func (p *pkgManToBundleCmd) run() (err error) {
183188
}
184189

185190
bundleMetaData := bundleutil.BundleMetaData{
186-
BundleDir: filepath.Join(p.outputDir, "bundle-"+dir.Name()),
191+
BundleDir: filepath.Join(p.outputDir, "bundle-"+dir.Name(), defaultSubBundleDir),
187192
PackageName: packageName,
188193
Channels: channels,
189194
DefaultChannel: defaultChannel,

internal/cmd/operator-sdk/pkgmantobundle/pkgmantobundle_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var _ = Describe("Running pkgmanToBundle command", func() {
3434
var (
3535
p pkgManToBundleCmd
3636
pkgManDir string
37-
outputDir string
37+
outputDir string = "bundle-output"
3838
)
3939

4040
BeforeEach(func() {
@@ -65,7 +65,6 @@ var _ = Describe("Running pkgmanToBundle command", func() {
6565
It("should generate multiple bundles for each version of manifests", func() {
6666
// Specify input package manifest directory and output directory
6767
pkgManDir = filepath.Join("testdata", "packagemanifests")
68-
outputDir = "bundles-output"
6968

7069
p.pkgmanifestDir = pkgManDir
7170
p.outputDir = outputDir
@@ -88,19 +87,31 @@ var _ = Describe("Running pkgmanToBundle command", func() {
8887

8988
// Verifying that bundle contains required files
9089
Expect(fileExists(filepath.Join(p.outputDir, bundle.Name(), "bundle.Dockerfile"))).To(BeTrue())
91-
Expect(fileExists(filepath.Join(p.outputDir, bundle.Name(), "metadata", "annotations.yaml"))).To(BeTrue())
90+
Expect(fileExists(filepath.Join(p.outputDir, bundle.Name(), defaultSubBundleDir, "metadata", "annotations.yaml"))).To(BeTrue())
9291
Expect(b.CSV).NotTo(BeNil())
9392
Expect(b.V1CRDs).NotTo(BeNil())
9493

9594
// Verify if scorecard config exiss in the bundle
9695
if bundle.Name() == "bundle-0.0.1" {
97-
Expect(fileExists(filepath.Join(p.outputDir, bundle.Name(), "tests", "scorecard", "config.yaml"))).To(BeTrue())
96+
Expect(fileExists(filepath.Join(p.outputDir, bundle.Name(), defaultSubBundleDir, "tests", "scorecard", "config.yaml"))).To(BeTrue())
9897
}
9998
}
10099
})
101100

101+
It("should build image when build command is provided", func() {
102+
// Specify input package manifest directory and output directory
103+
pkgManDir = filepath.Join("testdata", "packagemanifests")
104+
105+
p.pkgmanifestDir = pkgManDir
106+
p.outputDir = outputDir
107+
p.baseImg = "quay.io/example/memcached-operator"
108+
p.buildCmd = "docker build -f bundle.Dockerfile . -t"
109+
110+
err := p.run()
111+
Expect(err).NotTo(HaveOccurred())
112+
})
113+
102114
It("should error when output directory already exists", func() {
103-
outputDir = "bundles-output"
104115
err := os.Mkdir(outputDir, projutil.DirMode)
105116
Expect(err).NotTo(HaveOccurred())
106117

internal/util/bundleutil/bundleutil.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"os/exec"
2323
"path/filepath"
2424
"sort"
25+
"strings"
2526
"text/template"
2627

2728
log "github.com/sirupsen/logrus"
@@ -87,7 +88,7 @@ func (meta *BundleMetaData) GenerateMetadata() error {
8788
// Create annotation values for both bundle.Dockerfile and annotations.yaml, which should
8889
// hold the same set of values always.
8990
values := annotationsValues{
90-
BundleDir: meta.BundleDir,
91+
BundleDir: filepath.Base(meta.BundleDir),
9192
PackageName: meta.PackageName,
9293
Channels: meta.Channels,
9394
DefaultChannel: meta.DefaultChannel,
@@ -110,7 +111,7 @@ func (meta *BundleMetaData) GenerateMetadata() error {
110111
// inside bundleDir, else its in the project directory.
111112
// Remmove this, when pkgman-to-bundle migrate command is removed.
112113
if len(meta.PkgmanifestPath) != 0 {
113-
dockerfilePath = filepath.Join(meta.BundleDir, "bundle.Dockerfile")
114+
dockerfilePath = filepath.Join(filepath.Dir(meta.BundleDir), "bundle.Dockerfile")
114115
}
115116

116117
templateMap := map[string]*template.Template{
@@ -196,16 +197,40 @@ func (meta *BundleMetaData) BuildBundleImage(tag string) error {
196197

197198
img := fmt.Sprintf("%s:%s", meta.BaseImage, tag)
198199

200+
// switch back to current working directory, so that subsequent
201+
// bundle version images can be built.
202+
cwd, err := os.Getwd()
203+
if err != nil {
204+
return err
205+
}
206+
207+
defer func() {
208+
if err := os.Chdir(cwd); err != nil {
209+
log.Error(cwd)
210+
}
211+
}()
212+
213+
if err := os.Chdir(filepath.Dir(meta.BundleDir)); err != nil {
214+
return err
215+
}
216+
199217
if len(meta.BuildCommand) != 0 {
200218
// TODO(varsha): Make this more user friendly by accepting a template which
201219
// can executed in each bundle subdirectory.
202-
log.Infof("Using the specified command to build image %s", img)
203-
cmd := exec.Command(meta.BuildCommand, img)
204-
if err := cmd.Run(); err != nil {
220+
log.Infof("Using the specified command to build image")
221+
commandArg := strings.Split(meta.BuildCommand, " ")
222+
223+
// append the tag and build context to the command
224+
cmd := exec.Command(commandArg[0], append(commandArg[1:], img)...)
225+
output, err := cmd.CombinedOutput()
226+
if err != nil || viper.GetBool(flags.VerboseOpt) {
227+
fmt.Println(string(output))
228+
}
229+
if err != nil {
205230
return err
206231
}
207232
} else {
208-
output, err := exec.Command("docker", "build", "-f", filepath.Join(meta.BundleDir, "bundle.Dockerfile"), "-t", img, ".").CombinedOutput()
233+
output, err := exec.Command("docker", "build", "-f", "bundle.Dockerfile", "-t", img, ".").CombinedOutput()
209234
if err != nil || viper.GetBool(flags.VerboseOpt) {
210235
fmt.Println(string(output))
211236
}

website/content/en/docs/cli/operator-sdk_pkgman-to-bundle.md

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,36 @@ INFO[0000] Creating bundle/bundle-0.0.1/bundle.Dockerfile
5555
INFO[0000] Creating bundle/bundle-0.0.1/metadata/annotations.yaml
5656
...
5757
58-
# After running the above command, the bundles will be generated in 'bundle/' directory.
59-
$ tree bundle/
60-
bundle/
58+
# After running the above command, the bundles will be generated in 'bundles/' directory.
59+
$ tree bundles/
60+
bundles/
6161
├── bundle-0.0.1
62-
│   ├── bundle.Dockerfile
63-
│   ├── manifests
64-
│   │   ├── etcdcluster.crd.yaml
65-
│   │   ├── etcdoperator.clusterserviceversion.yaml
66-
│   ├── metadata
67-
│   │   └── annotations.yaml
68-
│   └── tests
69-
│   └── scorecard
70-
│   └── config.yaml
62+
│   ├── bundle
63+
│   │   ├── manifests
64+
│   │   │   ├── etcdcluster.crd.yaml
65+
│   │   │   ├── etcdoperator.clusterserviceversion.yaml
66+
│   │   ├── metadata
67+
│   │   │   └── annotations.yaml
68+
│   │   └── tests
69+
│   │   └── scorecard
70+
│   │   └── config.yaml
71+
│   └── bundle.Dockerfile
7172
└── bundle-0.0.2
72-
├── bundle.Dockerfile
73-
├── manifests
74-
│   ├── etcdbackup.crd.yaml
75-
│   ├── etcdcluster.crd.yaml
76-
│   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
77-
│   ├── etcdrestore.crd.yaml
78-
├── metadata
79-
│   └── annotations.yaml
80-
└── tests
81-
└── scorecard
82-
└── config.yaml
83-
84-
Also, images for the both the bundles will be built with the following names: quay.io/example/etcd:0.0.1 and quay.io/example/etcd:0.0.2.
73+
├── bundle
74+
│   ├── manifests
75+
│   │   ├── etcdbackup.crd.yaml
76+
│   │   ├── etcdcluster.crd.yaml
77+
│   │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
78+
│   │   ├── etcdrestore.crd.yaml
79+
│   └── metadata
80+
│   └── annotations.yaml
81+
└── bundle.Dockerfile
82+
83+
A custom command to build bundle images can also be specified using the '--build-cmd' flag. For example,
84+
85+
$ operator-sdk pkgman-to-bundle packagemanifests --image-tag-base quay.io/example/etcd --build-cmd "podman build -f bundle.Dockerfile . -t"
86+
87+
Images for the both the bundles will be built with the following names: quay.io/example/etcd:0.0.1 and quay.io/example/etcd:0.0.2.
8588
8689
```
8790

website/content/en/docs/olm-integration/quickstart-package-manifests.md

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,22 +125,28 @@ INFO[0000] Creating etcd-bundle/bundle-0.0.1/metadata/annotations.yaml
125125
This will create output bundles in the directory `etcd-bundle`. The output directory will look like:
126126

127127
```
128+
etcd-bundle/
128129
├── bundle-0.0.1
129-
│   ├── bundle.Dockerfile
130-
│   ├── manifests
131-
│   │   ├── etcdcluster.crd.yaml
132-
│   │   ├── etcdoperator.clusterserviceversion.yaml
133-
│   ├── metadata
134-
│   │   └── annotations.yaml
130+
│   ├── bundle
131+
│   │   ├── manifests
132+
│   │   │   ├── etcdcluster.crd.yaml
133+
│   │   │   ├── etcdoperator.clusterserviceversion.yaml
134+
│   │   ├── metadata
135+
│   │   │   └── annotations.yaml
136+
│   │   └── tests
137+
│   │   └── scorecard
138+
│   │   └── config.yaml
139+
│   └── bundle.Dockerfile
135140
└── bundle-0.0.2
136-
├── bundle.Dockerfile
137-
├── manifests
138-
│   ├── etcdbackup.crd.yaml
139-
│   ├── etcdcluster.crd.yaml
140-
│   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
141-
│   ├── etcdrestore.crd.yaml
142-
├── metadata
143-
   └── annotations.yaml
141+
├── bundle
142+
│   ├── manifests
143+
│   │   ├── etcdbackup.crd.yaml
144+
│   │   ├── etcdcluster.crd.yaml
145+
│   │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
146+
│   │   ├── etcdrestore.crd.yaml
147+
│   └── metadata
148+
│   └── annotations.yaml
149+
└── bundle.Dockerfile
144150
```
145151

146152
To build images for the bundles, the base container image name can be provided using `--image-tag-base` flag. This name should be provided without the tag (`:` and characters following), as the command will tag each bundle image with its packagemanifests directory name, i.e. `<image-tag-base>:<dir-name>`. For example, the following command for the above `packagemnifests` directory would build the bundles `quay.io/example/etcd-bundle:0.0.1` and `quay.io/example/etcd-bundle:0.0.2`.
@@ -149,14 +155,19 @@ To build images for the bundles, the base container image name can be provided u
149155
operator-sdk pkgman-to-bundle packagemanifests --image-tag-base quay.io/example/etcd-bundle
150156
```
151157

152-
A custom command can also be specified to build images, using the `--build-cmd` flag. The default command is `docker build`. However, if using a custom command, it needs to be made sure that the command is in the `PATH` or a fully qualified path name is provided as input to the flag.
158+
A custom command can also be specified to build images, using the `--build-cmd` flag. The default command is `docker build`. For example:
153159

154-
Once the command has finished building your bundle images and they have been added to a catalog image, delete all bundle directories except for the latest one. This directory will contain manifests for your operator's head bundle, and should be versioned with version control system like git. Rename this directory to `bundle`, and move `bundle.Dockerfile` to your project's root:
160+
```console
161+
$ operator-sdk pkgman-to-bundle packagemanifests --output-dir etcd-bundle/ --image-tag-base quay.io/example/etcd --build-cmd "podman build -f bundle.Dockerfile . -t"
162+
```
163+
164+
However, if using a custom command, it needs to be made sure that the command is in the `PATH` or a fully qualified path name is provided as input to the flag.
165+
166+
Once the command has finished building your bundle images and they have been added to a catalog image, delete all bundle directories except for the latest one. This directory will contain manifests for your operator's head bundle, and should be versioned with version control system like git. Move this directory and its `bundle.Dockerfile` to your project's root:
155167

156168
```console
157-
$ mv ./etcd-bundle/bundle-0.0.2 ./bundle
169+
$ cp -r ./etcd-bundle/bundle-0.0.2/* .
158170
$ rm -rf ./etcd-bundle
159-
$ mv bundle/bundle.Dockerfile .
160171
```
161172

162173
Try building then running your bundle on a live cluster to make sure it works as expected:

0 commit comments

Comments
 (0)