Skip to content

Commit adb253d

Browse files
author
Eric Stroczynski
authored
go mod support for new operators (#1001)
* commands/.../print_deps.go: print deps based on dep manager type * release.sh: update after go mod changes * pkg/scaffold/project/tools.go: k8s, openapi, CRD code generator runtime dependencies * *.md: update docs dep -> go mod, Gopkg.* -> go.* * internal/pkg/scaffold/*go_mod.go: go, ansible, helm `go.mod` scaffolds * test/e2e/memcached_test.go: go mod gets local changes instead of copying * internal/util/projutil/project_util.go: functions for detecting operator type * CHANGELOG.md: added go module support * set GO111MODULE=on in ansible and helm e2e * bump to go 1.12 * Gopkg.lock: revendor
1 parent c447c45 commit adb253d

File tree

33 files changed

+999
-132
lines changed

33 files changed

+999
-132
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cache:
77
- $HOME/.cache/go-build
88

99
go:
10-
- 1.10.3
10+
- 1.12.x
1111

1212
# The `x_base_steps` top-level key is unknown to travis,
1313
# so we can use it to create a bunch of common build step

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- New option for [`operator-sdk build --image-builder`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#build), which can be used to specify which image builder to use. Adds support for [buildah](https://github.com/containers/buildah/). ([#1311](https://github.com/operator-framework/operator-sdk/pull/1311))
66
- Manager is now configured with a new `DynamicRESTMapper`, which accounts for the fact that the default `RESTMapper`, which only checks resource types at startup, can't handle the case of first creating a CRD and then an instance of that CRD. ([#1329](https://github.com/operator-framework/operator-sdk/pull/1329))
77
- Unify CLI debug logging under a global `--verbose` flag ([#1361](https://github.com/operator-framework/operator-sdk/pull/1361))
8+
- [Go module](https://github.com/golang/go/wiki/Modules) support by default for new Go operators and during Ansible and Helm operator migration. The dependency manager used for a new operator can be explicitly specified for new operators through the `--dep-manager` flag, available in [`operator-sdk new`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#new) and [`operator-sdk migrate`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#migrate). `dep` is still available through `--dep-manager=dep`. ([#1001](https://github.com/operator-framework/operator-sdk/pull/1001))
89

910
### Changed
1011

Gopkg.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The following workflow is for a new **Helm** operator:
4040

4141
- [dep][dep_tool] version v0.5.0+.
4242
- [git][git_tool]
43-
- [go][go_tool] version v1.10+.
43+
- [go][go_tool] version v1.12+.
4444
- [docker][docker_tool] version 17.03+.
4545
- [kubectl][kubectl_tool] version v1.11.3+.
4646
- Access to a Kubernetes v1.11.3+ cluster.
@@ -72,6 +72,7 @@ Create and deploy an app-operator using the SDK CLI:
7272
$ mkdir -p $GOPATH/src/github.com/example-inc/
7373
# Create a new app-operator project
7474
$ cd $GOPATH/src/github.com/example-inc/
75+
$ export GO111MODULE=on
7576
$ operator-sdk new app-operator
7677
$ cd app-operator
7778

cmd/operator-sdk/build/cmd.go

+2
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ func buildFunc(cmd *cobra.Command, args []string) error {
184184
PackagePath: filepath.Join(projutil.CheckAndGetProjectGoPkg(), scaffold.ManagerDir),
185185
Args: goTrimFlags,
186186
Env: goBuildEnv,
187+
GoMod: projutil.IsDepManagerGoMod(),
187188
}
188189
if err := projutil.GoBuild(opts); err != nil {
189190
return fmt.Errorf("failed to build operator binary: (%v)", err)
@@ -218,6 +219,7 @@ func buildFunc(cmd *cobra.Command, args []string) error {
218219
PackagePath: testLocationBuild + "/...",
219220
Args: append(goTrimFlags, "-c"),
220221
Env: goBuildEnv,
222+
GoMod: projutil.IsDepManagerGoMod(),
221223
},
222224
}
223225
if err := projutil.GoTest(opts); err != nil {

cmd/operator-sdk/migrate/cmd.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func NewCmd() *cobra.Command {
4444
RunE: migrateRun,
4545
}
4646

47-
newCmd.Flags().StringVar(&depManager, "dep-manager", "dep", `Dependency manager the new project will use (choices: "dep")`)
47+
newCmd.Flags().StringVar(&depManager, "dep-manager", "modules", `Dependency manager the new project will use (choices: "dep", "modules")`)
4848
newCmd.Flags().StringVar(&headerFile, "header-file", "", "Path to file containing headers for generated Go files. Copied to hack/boilerplate.go.txt")
4949

5050
return newCmd
@@ -179,8 +179,13 @@ func scaffoldHelmDepManager(s *scaffold.Scaffold, cfg *input.Config) error {
179179
switch m := projutil.DepManagerType(depManager); m {
180180
case projutil.DepManagerDep:
181181
files = append(files, &helm.GopkgToml{})
182+
case projutil.DepManagerGoMod:
183+
if err := goModCheck(); err != nil {
184+
return err
185+
}
186+
files = append(files, &helm.GoMod{}, &scaffold.Tools{})
182187
default:
183-
return projutil.ErrInvalidDepManager
188+
return projutil.ErrInvalidDepManager(depManager)
184189
}
185190
return s.Execute(cfg, files...)
186191
}
@@ -190,8 +195,22 @@ func scaffoldAnsibleDepManager(s *scaffold.Scaffold, cfg *input.Config) error {
190195
switch m := projutil.DepManagerType(depManager); m {
191196
case projutil.DepManagerDep:
192197
files = append(files, &ansible.GopkgToml{})
198+
case projutil.DepManagerGoMod:
199+
if err := goModCheck(); err != nil {
200+
return err
201+
}
202+
files = append(files, &ansible.GoMod{}, &scaffold.Tools{})
193203
default:
194-
return projutil.ErrInvalidDepManager
204+
return projutil.ErrInvalidDepManager(depManager)
195205
}
196206
return s.Execute(cfg, files...)
197207
}
208+
209+
func goModCheck() error {
210+
goModOn, err := projutil.GoModOn()
211+
if err == nil && !goModOn {
212+
log.Fatal(`Dependency manager "modules" has been selected but go modules are not active. ` +
213+
`Activate modules then run "operator-sdk migrate".`)
214+
}
215+
return err
216+
}

cmd/operator-sdk/new/cmd.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ generates a skeletal app-operator application in $GOPATH/src/github.com/example.
5454
newCmd.Flags().StringVar(&apiVersion, "api-version", "", "Kubernetes apiVersion and has a format of $GROUP_NAME/$VERSION (e.g app.example.com/v1alpha1) - used with \"ansible\" or \"helm\" types")
5555
newCmd.Flags().StringVar(&kind, "kind", "", "Kubernetes CustomResourceDefintion kind. (e.g AppService) - used with \"ansible\" or \"helm\" types")
5656
newCmd.Flags().StringVar(&operatorType, "type", "go", "Type of operator to initialize (choices: \"go\", \"ansible\" or \"helm\")")
57-
newCmd.Flags().StringVar(&depManager, "dep-manager", "dep", `Dependency manager the new project will use (choices: "dep")`)
57+
newCmd.Flags().StringVar(&depManager, "dep-manager", "modules", `Dependency manager the new project will use (choices: "dep", "modules")`)
5858
newCmd.Flags().BoolVar(&skipGit, "skip-git-init", false, "Do not init the directory as a git repository")
5959
newCmd.Flags().StringVar(&headerFile, "header-file", "", "Path to file containing headers for generated Go files. Copied to hack/boilerplate.go.txt")
6060
newCmd.Flags().BoolVar(&generatePlaybook, "generate-playbook", false, "Generate a playbook skeleton. (Only used for --type ansible)")
@@ -166,8 +166,16 @@ func doGoScaffold() error {
166166
switch m := projutil.DepManagerType(depManager); m {
167167
case projutil.DepManagerDep:
168168
err = s.Execute(cfg, &scaffold.GopkgToml{})
169+
case projutil.DepManagerGoMod:
170+
if goModOn, merr := projutil.GoModOn(); merr != nil {
171+
return merr
172+
} else if !goModOn {
173+
log.Fatalf(`Dependency manager "%s" has been selected but go modules are not active. `+
174+
`Activate modules then run "operator-sdk new %s".`, m, projectName)
175+
}
176+
err = s.Execute(cfg, &scaffold.GoMod{}, &scaffold.Tools{})
169177
default:
170-
err = projutil.ErrInvalidDepManager
178+
err = projutil.ErrNoDepManager
171179
}
172180
if err != nil {
173181
return fmt.Errorf("dependency manager file scaffold failed: (%v)", err)
@@ -392,8 +400,13 @@ func getDeps() error {
392400
if err := execProjCmd("dep", "ensure", "-v"); err != nil {
393401
return err
394402
}
403+
case projutil.DepManagerGoMod:
404+
log.Info("Running go mod ...")
405+
if err := execProjCmd("go", "mod", "vendor", "-v"); err != nil {
406+
return err
407+
}
395408
default:
396-
return projutil.ErrInvalidDepManager
409+
return projutil.ErrInvalidDepManager(depManager)
397410
}
398411
log.Info("Done getting dependencies")
399412
return nil

cmd/operator-sdk/printdeps/cmd.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@ func NewCmd() *cobra.Command {
3333
Short: "Print Golang packages and versions required to run the operator",
3434
Long: `The operator-sdk print-deps command prints all Golang packages and versions expected
3535
by this version of the Operator SDK. Versions for these packages should match
36-
those in an operators' Gopkg.toml file.
36+
those in an operators' go.mod or Gopkg.toml file, depending on the dependency
37+
manager chosen when initializing or migrating a project.
3738
3839
print-deps prints in columnar format by default. Use the --as-file flag to
39-
print in Gopkg.toml file format.
40+
print in go.mod or Gopkg.toml file format.
4041
`,
4142
RunE: printDepsFunc,
4243
}
4344

44-
printDepsCmd.Flags().BoolVar(&asFile, "as-file", false, "Print dependencies in Gopkg.toml file format.")
45+
printDepsCmd.Flags().BoolVar(&asFile, "as-file", false, "Print dependencies in go.mod or Gopkg.toml file format, depending on the dependency manager chosen when initializing or migrating a project")
4546

4647
return printDepsCmd
4748
}
@@ -72,14 +73,17 @@ func printDeps(asFile bool) error {
7273
if isDep {
7374
return ansible.PrintDepGopkgTOML(asFile)
7475
}
76+
return ansible.PrintGoMod(asFile)
7577
case projutil.IsOperatorHelm():
7678
if isDep {
7779
return helm.PrintDepGopkgTOML(asFile)
7880
}
81+
return helm.PrintGoMod(asFile)
7982
case projutil.IsOperatorGo():
8083
if isDep {
8184
return scaffold.PrintDepGopkgTOML(asFile)
8285
}
86+
return scaffold.PrintGoMod(asFile)
8387
}
8488

8589
return projutil.ErrUnknownOperatorType{}

cmd/operator-sdk/test/local.go

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ func testLocalGoFunc(cmd *cobra.Command, args []string) error {
213213
PackagePath: args[0] + "/...",
214214
Env: append(os.Environ(), fmt.Sprintf("%v=%v", test.TestNamespaceEnv, tlConfig.namespace)),
215215
Dir: projutil.MustGetwd(),
216+
GoMod: projutil.IsDepManagerGoMod(),
216217
},
217218
TestBinaryArgs: testArgs,
218219
}

cmd/operator-sdk/up/local.go

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ func buildLocal(outputBinName string) error {
185185
BinName: outputBinName,
186186
PackagePath: filepath.Join(projutil.CheckAndGetProjectGoPkg(), scaffold.ManagerDir),
187187
Args: args,
188+
GoMod: projutil.IsDepManagerGoMod(),
188189
}
189190
return projutil.GoBuild(opts)
190191
}

doc/ansible/user-guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ powered by Ansible using tools and libraries provided by the Operator SDK.
1212
- [ansible-runner][ansible_runner_tool] version v1.1.0+
1313
- [ansible-runner-http][ansible_runner_http_plugin] version v1.0.0+
1414
- [dep][dep_tool] version v0.5.0+. (Optional if you aren't installing from source)
15-
- [go][go_tool] version v1.10+. (Optional if you aren't installing from source)
15+
- [go][go_tool] version v1.12+. (Optional if you aren't installing from source)
1616
- Access to a Kubernetes v.1.9.0+ cluster.
1717

1818
**Note**: This guide uses [minikube][minikube_tool] version v0.25.0+ as the

doc/dev/developer_guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This document explains how to setup your dev environment.
55
## Prerequisites
66
- [dep][dep_tool] version v0.5.0+
77
- [git][git_tool]
8-
- [go][go_tool] version v1.10+
8+
- [go][go_tool] version v1.12+
99

1010
## Download Operator SDK
1111

doc/dev/release.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ Create a new branch to push release commits:
171171
$ git checkout -b release-v1.3.0
172172
```
173173

174-
Commit changes to the following six files:
174+
Commit changes to the following files:
175175

176176
- `version/version.go`: update `Version` to `v1.3.0`.
177177
- `internal/pkg/scaffold/gopkgtoml.go`, under the `[[constraint]]` for `github.com/operator-framework/operator-sdk`:
@@ -181,6 +181,12 @@ Commit changes to the following six files:
181181
- `internal/pkg/scaffold/gopkgtoml_test.go`: same as for `internal/pkg/scaffold/gopkgtoml.go`.
182182
- `internal/pkg/scaffold/ansible/gopkgtoml.go`: same as for `internal/pkg/scaffold/gopkgtoml.go`.
183183
- `internal/pkg/scaffold/helm/gopkgtoml.go`: same as for `internal/pkg/scaffold/gopkgtoml.go`.
184+
- `internal/pkg/scaffold/go_mod.go`, in the `replace` block for `github.com/operator-framework/operator-sdk`:
185+
- Add the following `replace` entry: `github.com/operator-framework/operator-sdk => github.com/operator-framework/operator-sdk v1.3.0`.
186+
- If an entry already exists, change the version to `v1.3.0`.
187+
- `internal/pkg/scaffold/go_mod_test.go`: same as for `internal/pkg/scaffold/go_mod.go`.
188+
- `internal/pkg/scaffold/helm/go_mod.go`: same as for `internal/pkg/scaffold/go_mod.go`.
189+
- `internal/pkg/scaffold/ansible/go_mod.go`: same as for `internal/pkg/scaffold/go_mod.go`.
184190
- `CHANGELOG.md`: update the `## Unreleased` header to `## v1.3.0`.
185191

186192
Create a new PR for `release-v1.3.0`.

doc/dev/testing/travis-build.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ The Go, Ansible, and Helm tests then differ in what tests they run.
7979
6. Create a memcached CR and wait for it to be ready.
8080
7. Create a configmap that the memcached-operator is configured to delete using a finalizer.
8181
8. Delete memcached CR and verify that the finalizer deleted the configmap.
82-
9. Run `operator-sdk migrate` to add go source to the operator.
82+
9. Run `operator-sdk migrate` to add go source to the operator (see this [note][deps_mgmt] on dependency management first).
8383
10. Run `operator-sdk build` to compile the new binary and build a new image.
8484
11. Re-run steps 4-8 to test the migrated operator.
8585

@@ -97,7 +97,7 @@ The Go, Ansible, and Helm tests then differ in what tests they run.
9797
7. Scale up the dependent deployment and verify the operator reconciles it back down.
9898
8. Scale up the CR and verify the dependent deployment scales up accordingly.
9999
9. Delete nginx CR and verify that finalizer (which writes a message in the operator logs) ran.
100-
10. Run `operator-sdk migrate` to add go source to the operator.
100+
10. Run `operator-sdk migrate` to add go source to the operator (see this [note][deps_mgmt] on dependency management first).
101101
11. Run `operator-sdk build` to compile the new binary and build a new image.
102102
12. Re-run steps 4-9 to test the migrated operator.
103103

@@ -122,3 +122,4 @@ The markdown test does not create a new cluster and runs in a barebones Travis V
122122
[helm-base]: ../../../hack/image/helm/scaffold-helm-image.go
123123
[marker-github]: https://github.com/crawford/marker
124124
[marker-local]: ../../../hack/ci/marker
125+
[deps_mgmt]: ../../user-guide.md#a-note-on-dependency-management

doc/helm/user-guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ powered by Helm using tools and libraries provided by the Operator SDK.
99
- [docker][docker_tool] version 17.03+.
1010
- [kubectl][kubectl_tool] version v1.11.3+.
1111
- [dep][dep_tool] version v0.5.0+. (Optional if you aren't installing from source)
12-
- [go][go_tool] version v1.10+. (Optional if you aren't installing from source)
12+
- [go][go_tool] version v1.12+. (Optional if you aren't installing from source)
1313
- Access to a Kubernetes v1.11.3+ cluster.
1414

1515
**Note**: This guide uses [minikube][minikube_tool] version v0.25.0+ as the

doc/project_layout.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ The `operator-sdk` CLI generates a number of packages for each project. The foll
1010
| pkg/controller | This pkg contains the controller implementations. Users are expected to edit the `pkg/controller/<kind>/<kind>_controller.go` to define the controller's reconcile logic for handling a resource type of the specified `kind`. |
1111
| build | Contains the `Dockerfile` and build scripts used to build the operator. |
1212
| deploy | Contains various YAML manifests for registering CRDs, setting up [RBAC][RBAC], and deploying the operator as a Deployment.
13-
| Gopkg.toml Gopkg.lock | The [Go Dep][dep] manifests that describe the external dependencies of this operator. |
14-
| vendor | The golang [vendor][Vendor] folder that contains the local copies of the external dependencies that satisfy the imports of this project. [Go Dep][dep] manages the vendor directly. |
13+
| (Gopkg.toml Gopkg.lock) or (go.mod go.sum) | The [Go mod][go_mod] or [Go Dep][dep] manifests that describe the external dependencies of this operator, depending on the dependency manager chosen when initializing or migrating a project. |
14+
| vendor | The golang [vendor][Vendor] folder that contains the local copies of the external dependencies that satisfy the imports of this project. [Go Dep][dep]/[Go modules][go_mod] manages the vendor directly. |
1515

1616
[RBAC]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
1717
[Vendor]: https://golang.org/cmd/go/#hdr-Vendor_Directories
18+
[go_mod]: https://github.com/golang/go/wiki/Modules
1819
[dep]: https://github.com/golang/dep

doc/sdk-cli-reference.md

+23-7
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ Prints the most recent Golang packages and versions required by operators. Print
9696

9797
### Flags
9898

99-
* `--as-file` - Print packages and versions in Gopkg.toml format.
99+
* `--as-file` - Print packages and versions in go.mod or Gopkg.toml format, depending on the dependency manager chosen when initializing or migrating a project.
100100

101101
### Example
102102

103+
With dependency manager `dep`:
104+
103105
```console
104106
$ operator-sdk print-deps --as-file
105107
required = [
@@ -118,6 +120,19 @@ required = [
118120
...
119121
```
120122

123+
With dependency manager `modules`, i.e. go mod:
124+
125+
```console
126+
$ operator-sdk print-deps --as-file
127+
module github.com/example-inc/memcached-operator
128+
129+
require (
130+
contrib.go.opencensus.io/exporter/ocagent v0.4.9 // indirect
131+
github.com/Azure/go-autorest v11.5.2+incompatible // indirect
132+
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 // indirect
133+
github.com/coreos/prometheus-operator v0.26.0 // indirect
134+
```
135+
121136
## generate
122137

123138
### k8s
@@ -218,20 +233,21 @@ you will need to rename it before running migrate or manually add it to your Doc
218233

219234
#### Flags
220235

221-
* `--dep-manager` string - Dependency manager the migrated project will use (choices: "dep")
236+
* `--dep-manager` string - Dependency manager the migrated project will use (choices: "dep", "modules") (default "modules")
222237

223238
### Example
224239

225240
```console
226241
$ operator-sdk migrate
227-
2019/01/10 15:02:45 No playbook was found, so not including it in the new Dockerfile
228-
2019/01/10 15:02:45 renamed Dockerfile to build/Dockerfile.sdkold and replaced with newer version
229-
2019/01/10 15:02:45 Compare the new Dockerfile to your old one and manually migrate any customizations
242+
INFO[0000] No playbook was found, so not including it in the new Dockerfile
243+
INFO[0000] Renamed Dockerfile to build/Dockerfile.sdkold and replaced with newer version. Compare the new Dockerfile to your old one and manually migrate any customizations
244+
INFO[0000] Created go.mod
230245
INFO[0000] Created cmd/manager/main.go
231-
INFO[0000] Created Gopkg.toml
232246
INFO[0000] Created build/Dockerfile
233247
INFO[0000] Created bin/entrypoint
234248
INFO[0000] Created bin/user_setup
249+
INFO[0000] Created library/k8s_status.py
250+
INFO[0000] Created bin/ao-logs
235251
```
236252

237253
## new
@@ -253,7 +269,7 @@ Scaffolds a new operator project.
253269
* `--helm-chart` string - Initialize helm operator with existing helm chart (`<URL>`, `<repo>/<name>`, or local path)
254270
* `--helm-chart-repo` string - Chart repository URL for the requested helm chart
255271
* `--helm-chart-version` string - Specific version of the helm chart (default is latest version)
256-
* `--dep-manager` string - Dependency manager the new project will use (choices: "dep")
272+
* `--dep-manager` string - Dependency manager the new project will use (choices: "dep", "modules") (default "modules")
257273
* `-h, --help` - help for new
258274

259275
### Example

0 commit comments

Comments
 (0)