Skip to content

Commit 831baea

Browse files
authored
CSV versioning (#1016)
* pkg/scaffold/olm-catalog: CSV directory and file versioning * commands/.../olm-catalog: `--from-version` to specify which existing CSV to use as a base for the new CSV with version `--csv-version`; `--update-crds` to direct the SDK to copy CRD's from `deploy/crds` when creating a new CSV or updating an existing CSV
1 parent 21e899c commit 831baea

File tree

12 files changed

+194
-220
lines changed

12 files changed

+194
-220
lines changed

commands/operator-sdk/cmd/olm-catalog/gen-csv.go

+67-10
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ package catalog
1616

1717
import (
1818
"fmt"
19+
"io/ioutil"
1920
"path/filepath"
21+
"strings"
2022

23+
"github.com/operator-framework/operator-sdk/internal/util/fileutil"
2124
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2225
"github.com/operator-framework/operator-sdk/pkg/scaffold"
2326
"github.com/operator-framework/operator-sdk/pkg/scaffold/input"
@@ -30,7 +33,9 @@ import (
3033

3134
var (
3235
csvVersion string
36+
fromVersion string
3337
csvConfigPath string
38+
updateCRDs bool
3439
)
3540

3641
func NewGenCSVCmd() *cobra.Command {
@@ -40,15 +45,19 @@ func NewGenCSVCmd() *cobra.Command {
4045
Long: `The gen-csv command generates a Cluster Service Version (CSV) YAML manifest
4146
for the operator. This file is used to publish the operator to the OLM Catalog.
4247
43-
A CSV semantic version is supplied via the --csv-version flag.
48+
A CSV semantic version is supplied via the --csv-version flag. If your operator
49+
has already generated a CSV manifest you want to use as a base, supply its
50+
version to --from-version. Otherwise the SDK will scaffold a new CSV manifest.
4451
4552
Configure CSV generation by writing a config file 'deploy/olm-catalog/csv-config.yaml`,
4653
RunE: genCSVFunc,
4754
}
4855

4956
genCSVCmd.Flags().StringVar(&csvVersion, "csv-version", "", "Semantic version of the CSV")
5057
genCSVCmd.MarkFlagRequired("csv-version")
58+
genCSVCmd.Flags().StringVar(&fromVersion, "from-version", "", "Semantic version of an existing CSV to use as a base")
5159
genCSVCmd.Flags().StringVar(&csvConfigPath, "csv-config", "", "Path to CSV config file. Defaults to deploy/olm-catalog/csv-config.yaml")
60+
genCSVCmd.Flags().BoolVar(&updateCRDs, "update-crds", false, "Update CRD manifests in deploy/{operator-name}/{csv-version} the using latest API's")
5261

5362
return genCSVCmd
5463
}
@@ -74,25 +83,73 @@ func genCSVFunc(cmd *cobra.Command, args []string) error {
7483
log.Infof("Generating CSV manifest version %s", csvVersion)
7584

7685
s := &scaffold.Scaffold{}
77-
err := s.Execute(cfg,
78-
&catalog.CSV{CSVVersion: csvVersion, ConfigFilePath: csvConfigPath},
79-
&catalog.ConcatCRD{ConfigFilePath: csvConfigPath},
80-
)
81-
if err != nil {
86+
csv := &catalog.CSV{
87+
CSVVersion: csvVersion,
88+
FromVersion: fromVersion,
89+
ConfigFilePath: csvConfigPath,
90+
}
91+
if err := s.Execute(cfg, csv); err != nil {
8292
return fmt.Errorf("catalog scaffold failed: (%v)", err)
8393
}
94+
95+
// Write CRD's to the new or updated CSV package dir.
96+
if updateCRDs {
97+
input, err := csv.GetInput()
98+
if err != nil {
99+
return err
100+
}
101+
cfg, err := catalog.GetCSVConfig(csvConfigPath)
102+
if err != nil {
103+
return err
104+
}
105+
err = writeCRDsToDir(cfg.CRDCRPaths, filepath.Dir(input.Path))
106+
if err != nil {
107+
return err
108+
}
109+
}
110+
84111
return nil
85112
}
86113

87114
func verifyGenCSVFlags() error {
88-
v, err := semver.NewVersion(csvVersion)
115+
if err := verifyCSVVersion(csvVersion); err != nil {
116+
return err
117+
}
118+
if fromVersion != "" {
119+
if err := verifyCSVVersion(fromVersion); err != nil {
120+
return err
121+
}
122+
}
123+
return nil
124+
}
125+
126+
func verifyCSVVersion(version string) error {
127+
v, err := semver.NewVersion(version)
89128
if err != nil {
90-
return fmt.Errorf("%s is not a valid semantic version: (%v)", csvVersion, err)
129+
return fmt.Errorf("%s is not a valid semantic version: (%v)", version, err)
91130
}
92131
// Ensures numerical values composing csvVersion don't contain leading 0's,
93132
// ex. 01.01.01
94-
if v.String() != csvVersion {
95-
return fmt.Errorf("provided CSV version %s contains bad values (parses to %s)", csvVersion, v)
133+
if v.String() != version {
134+
return fmt.Errorf("provided CSV version %s contains bad values (parses to %s)", version, v)
135+
}
136+
return nil
137+
}
138+
139+
func writeCRDsToDir(crdPaths []string, toDir string) error {
140+
for _, p := range crdPaths {
141+
if !strings.HasSuffix(p, "crd.yaml") {
142+
continue
143+
}
144+
b, err := ioutil.ReadFile(p)
145+
if err != nil {
146+
return err
147+
}
148+
path := filepath.Join(toDir, filepath.Base(p))
149+
err = ioutil.WriteFile(path, b, fileutil.DefaultFileMode)
150+
if err != nil {
151+
return err
152+
}
96153
}
97154
return nil
98155
}

doc/sdk-cli-reference.md

+10-9
Original file line numberDiff line numberDiff line change
@@ -178,25 +178,26 @@ Parent command for all OLM Catalog related commands.
178178

179179
### gen-csv
180180

181-
Writes a Cluster Service Version (CSV) manifest and concatenated CRD files to `deploy/olm-catalog`.
181+
Writes a Cluster Service Version (CSV) manifest and optionally CRD files to `deploy/olm-catalog/{operator-name}/{csv-version}`.
182182

183183
#### Flags
184184

185-
* `--csv-version` (required) Semantic version of the CSV manifest.
186-
* `--csv-config` Path to CSV config file. Defaults to deploy/olm-catalog/csv-config.yaml.
185+
* `--csv-version` string - (required) Semantic version of the CSV manifest.
186+
* `--from-version` string - Semantic version of CSV manifest to use as a base for a new version.
187+
* `--csv-config` string - Path to CSV config file. Defaults to deploy/olm-catalog/csv-config.yaml.
188+
* `--update-crds` Update CRD manifests in deploy/{operator-name}/{csv-version} using the latest CRD manifests.
187189

188190
#### Example
189191

190192
```console
191-
$ operator-sdk olm-catalog gen-csv --csv-version 0.1.1
192-
INFO[0000] Generating CSV manifest version 0.1.1
193-
INFO[0000] Fill in the following required fields in file deploy/olm-catalog/operator-name.csv.yaml:
193+
$ operator-sdk olm-catalog gen-csv --csv-version 0.1.0 --update-crds
194+
INFO[0000] Generating CSV manifest version 0.1.0
195+
INFO[0000] Fill in the following required fields in file deploy/olm-catalog/operator-name/0.1.0/operator-name.v0.1.0.clusterserviceversion.yaml:
194196
spec.keywords
195197
spec.maintainers
196198
spec.provider
197199
spec.labels
198-
INFO[0000] Created deploy/olm-catalog/operator-name.csv.yaml
199-
INFO[0000] Created deploy/olm-catalog/_generated.concat_crd.yaml
200+
INFO[0000] Created deploy/olm-catalog/operator-name/0.1.0/operator-name.v0.1.0.clusterserviceversion.yaml
200201
```
201202

202203
## migrate
@@ -385,7 +386,7 @@ Run scorecard tests on an operator
385386
### Example
386387

387388
```console
388-
$ operator-sdk scorecard --cr-manifest deploy/crds/cache_v1alpha1_memcached_cr.yaml --csv-path deploy/memcachedoperator.0.0.2.csv.yaml
389+
$ operator-sdk scorecard --cr-manifest deploy/crds/cache_v1alpha1_memcached_cr.yaml --csv-path deploy/olm-catalog/memcached-operator/0.0.2/memcached-operator.v0.0.2.clusterserviceversion.yaml
389390
Checking for existence of spec and status blocks in CR
390391
Checking that operator actions are reflected in status
391392
Checking that writing into CRs has an effect

doc/test-framework/scorecard.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ $ operator-sdk scorecard --cr-manifest deploy/crds/app_operator_cr.yaml --csv-pa
4141
The scorecard supports the use of a config file instead of or in addition to flags for configuration. By default, the scorecard will look
4242
for a file called `.osdk-scorecard` with either a `.yaml`, `.json`, or `.toml` file extension. You can also
4343
specify a different config file with the `--config` flag. The configuration options in the config file match the flags.
44-
For instance, for the flags `--cr-manifest "deploy/crds/cache_v1alpha1_memcached_cr.yaml" --init-timeout 60 --csv-path "deploy/memcachedoperator.0.0.2.csv.yaml"`, the corresponding yaml config file would contain:
44+
For instance, for the flags `--cr-manifest "deploy/crds/cache_v1alpha1_memcached_cr.yaml" --init-timeout 60 --csv-path "deploy/olm-catalog/memcached-operator/0.0.2/memcached-operator.v0.0.2.clusterserviceversion.yaml"`, the corresponding yaml config file would contain:
4545

4646
```yaml
4747
cr-manifest: "deploy/crds/cache_v1alpha1_memcached_cr.yaml"
4848
init-timeout: 60
49-
csv-path: "deploy/memcachedoperator.0.0.2.csv.yaml"
49+
csv-path: "deploy/olm-catalog/memcached-operator/0.0.2/memcached-operator.v0.0.2.clusterserviceversion.yaml"
5050
```
5151
5252
The hierarchy of config methods from highest priority to least is: flag->file->default.

hack/tests/scorecard-subcommand.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env bash
22

33
DEST_IMAGE="quay.io/example/scorecard-proxy"
4+
CSV_PATH="deploy/olm-catalog/memcached-operator/0.0.2/memcached-operator.v0.0.2.clusterserviceversion.yaml"
45
CONFIG_PATH=".test-osdk-scorecard.yaml"
56

67
set -ex
@@ -13,7 +14,7 @@ pushd test/test-framework
1314
commandoutput="$(operator-sdk scorecard \
1415
--cr-manifest deploy/crds/cache_v1alpha1_memcached_cr.yaml \
1516
--init-timeout 60 \
16-
--csv-path deploy/memcachedoperator.0.0.2.csv.yaml \
17+
--csv-path "$CSV_PATH" \
1718
--verbose \
1819
--proxy-image "$DEST_IMAGE" \
1920
--proxy-pull-policy Never \

pkg/scaffold/olm-catalog/concat_crd.go

-85
This file was deleted.

pkg/scaffold/olm-catalog/concat_crd_test.go

-81
This file was deleted.

pkg/scaffold/olm-catalog/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type CSVConfig struct {
3737
}
3838

3939
// TODO: discuss case of no config file at default path: write new file or not.
40-
func getCSVConfig(cfgFile string) (*CSVConfig, error) {
40+
func GetCSVConfig(cfgFile string) (*CSVConfig, error) {
4141
cfg := &CSVConfig{}
4242
if _, err := os.Stat(cfgFile); err == nil {
4343
cfgData, err := ioutil.ReadFile(cfgFile)

0 commit comments

Comments
 (0)