Skip to content

Commit

Permalink
commands,pkg/scaffold,hack,pkg/helm: run and migrate command support …
Browse files Browse the repository at this point in the history
…for helm (#897)

* [travis deploy] commands,pkg/scaffold,hack,pkg/helm: run and migrate command support for helm

* CHANGELOG.md,doc,commands/.../run/helm.go: document helm support for run and migrate commands

* doc/dev/testing/travis-build.md: ansible/helm e2e doc update

* doc/dev/release.md: documenting new release steps for ansible/helm gopkgtoml.go
  • Loading branch information
joelanford committed Jan 15, 2019
1 parent 3c2fee5 commit 419cfd3
Show file tree
Hide file tree
Showing 26 changed files with 569 additions and 208 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

### Added

- A new command [`operator-sdk migrate`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#migrate) which adds a main.go source file and any associated source files for an operator that is not of the "go" type. ([#887](https://github.com/operator-framework/operator-sdk/pull/887))
- A new command [`operator-sdk run ansible`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#ansible) which runs as an ansible operator process. This is intended to be used when running in a Pod inside a cluster. Developers wanting to run their operator locally should continue to use `up local`. ([#887](https://github.com/operator-framework/operator-sdk/pull/887))
- A new command [`operator-sdk migrate`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#migrate) which adds a main.go source file and any associated source files for an operator that is not of the "go" type. ([#887](https://github.com/operator-framework/operator-sdk/pull/887) and [#897](https://github.com/operator-framework/operator-sdk/pull/897))
- New commands [`operator-sdk run ansible`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#ansible) and [`operator-sdk run helm`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#helm) which run the SDK as ansible and helm operator processes, respectively. These are intended to be used when running in a Pod inside a cluster. Developers wanting to run their operator locally should continue to use `up local`. ([#887](https://github.com/operator-framework/operator-sdk/pull/887) and [#897](https://github.com/operator-framework/operator-sdk/pull/897))

### Changed

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ image/build: image/build/ansible image/build/helm
image/build/ansible: build/operator-sdk-dev-x86_64-linux-gnu
./hack/image/build-ansible-image.sh $(ANSIBLE_BASE_IMAGE):dev

image/build/helm:
image/build/helm: build/operator-sdk-dev-x86_64-linux-gnu
./hack/image/build-helm-image.sh $(HELM_BASE_IMAGE):dev

image/push: image/push/ansible image/push/helm
Expand Down
48 changes: 41 additions & 7 deletions commands/operator-sdk/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/operator-framework/operator-sdk/internal/util/projutil"
"github.com/operator-framework/operator-sdk/pkg/scaffold"
"github.com/operator-framework/operator-sdk/pkg/scaffold/ansible"
"github.com/operator-framework/operator-sdk/pkg/scaffold/helm"
"github.com/operator-framework/operator-sdk/pkg/scaffold/input"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -48,6 +49,8 @@ func migrateRun(cmd *cobra.Command, args []string) {
switch opType {
case projutil.OperatorTypeAnsible:
migrateAnsible()
case projutil.OperatorTypeHelm:
migrateHelm()
default:
log.Fatalf("Operator of type %s cannot be migrated.", opType)
}
Expand Down Expand Up @@ -76,13 +79,7 @@ func migrateAnsible() {
log.Fatalf("Error trying to stat playbook.yaml: (%v)", err)
}

dockerfilePath := filepath.Join(scaffold.BuildDir, scaffold.DockerfileFile)
newDockerfilePath := dockerfilePath + ".sdkold"
err = os.Rename(dockerfilePath, newDockerfilePath)
if err != nil {
log.Fatalf("Failed to rename Dockerfile: (%v)", err)
}
log.Infof("Renamed Dockerfile to %s and replaced with newer version. Compare the new Dockerfile to your old one and manually migrate any customizations", newDockerfilePath)
renameDockerfile()

s := &scaffold.Scaffold{}
err = s.Execute(cfg,
Expand All @@ -96,3 +93,40 @@ func migrateAnsible() {
log.Fatalf("Migrate scaffold failed: (%v)", err)
}
}

// migrateHelm runs the migration process for a helm-based operator
func migrateHelm() {
wd := projutil.MustGetwd()

cfg := &input.Config{
AbsProjectPath: wd,
ProjectName: filepath.Base(wd),
}

renameDockerfile()

s := &scaffold.Scaffold{}
err := s.Execute(cfg,
&helm.Main{},
&helm.GopkgToml{},
&helm.DockerfileHybrid{
Watches: true,
HelmCharts: true,
},
&helm.Entrypoint{},
&helm.UserSetup{},
)
if err != nil {
log.Fatalf("Migrate scaffold failed: (%v)", err)
}
}

func renameDockerfile() {
dockerfilePath := filepath.Join(scaffold.BuildDir, scaffold.DockerfileFile)
newDockerfilePath := dockerfilePath + ".sdkold"
err := os.Rename(dockerfilePath, newDockerfilePath)
if err != nil {
log.Fatalf("Failed to rename Dockerfile: (%v)", err)
}
log.Infof("Renamed Dockerfile to %s and replaced with newer version. Compare the new Dockerfile to your old one and manually migrate any customizations", newDockerfilePath)
}
1 change: 1 addition & 0 deletions commands/operator-sdk/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ should use "up local" instead.`,
}

runCmd.AddCommand(run.NewAnsibleCmd())
runCmd.AddCommand(run.NewHelmCmd())
return runCmd
}
3 changes: 1 addition & 2 deletions commands/operator-sdk/cmd/run/ansible.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ import (
"github.com/spf13/cobra"
)

var flags *aoflags.AnsibleOperatorFlags

// NewAnsibleCmd returns a command that will run an ansible operator
func NewAnsibleCmd() *cobra.Command {
var flags *aoflags.AnsibleOperatorFlags
newCmd := &cobra.Command{
Use: "ansible",
Short: "Runs as an ansible operator",
Expand Down
40 changes: 40 additions & 0 deletions commands/operator-sdk/cmd/run/helm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2019 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package run

import (
"github.com/operator-framework/operator-sdk/pkg/helm"
hoflags "github.com/operator-framework/operator-sdk/pkg/helm/flags"

"github.com/spf13/cobra"
)

// NewHelmCmd returns a command that will run a helm operator
func NewHelmCmd() *cobra.Command {
var flags *hoflags.HelmOperatorFlags
newCmd := &cobra.Command{
Use: "helm",
Short: "Runs as a helm operator",
Long: `Runs as a helm operator. This is intended to be used when running
in a Pod inside a cluster. Developers wanting to run their operator locally
should use "up local" instead.`,
Run: func(cmd *cobra.Command, args []string) {
helm.Run(flags)
},
}
flags = hoflags.AddTo(newCmd.Flags())

return newCmd
}
57 changes: 6 additions & 51 deletions commands/operator-sdk/cmd/up/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,17 @@ import (
"strings"
"syscall"

"sigs.k8s.io/controller-runtime/pkg/runtime/signals"

"github.com/operator-framework/operator-sdk/internal/util/projutil"
"github.com/operator-framework/operator-sdk/pkg/ansible"
aoflags "github.com/operator-framework/operator-sdk/pkg/ansible/flags"
"github.com/operator-framework/operator-sdk/pkg/helm/client"
"github.com/operator-framework/operator-sdk/pkg/helm/controller"
"github.com/operator-framework/operator-sdk/pkg/helm"
hoflags "github.com/operator-framework/operator-sdk/pkg/helm/flags"
"github.com/operator-framework/operator-sdk/pkg/helm/release"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/scaffold"
sdkVersion "github.com/operator-framework/operator-sdk/version"
"k8s.io/helm/pkg/storage"
"k8s.io/helm/pkg/storage/driver"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/manager"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
)

// NewLocalCmd - up local command to run an operator loccally
Expand Down Expand Up @@ -172,50 +163,14 @@ func upLocalHelm() {
log.Fatalf("Failed to set %s environment variable: (%v)", k8sutil.KubeConfigEnvVar, err)
}

logf.SetLogger(logf.ZapLogger(false))

printVersion()

cfg, err := config.GetConfig()
if err != nil {
log.Fatal(err)
}

mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
if err != nil {
log.Fatal(err)
}

// Create Tiller's storage backend and kubernetes client
storageBackend := storage.Init(driver.NewMemory())
tillerKubeClient, err := client.NewFromManager(mgr)
if err != nil {
log.Fatal(err)
}

factories, err := release.NewManagerFactoriesFromFile(storageBackend, tillerKubeClient, helmOperatorFlags.WatchesFile)
if err != nil {
log.Fatal(err)
}

for gvk, factory := range factories {
// Register the controller with the factory.
err := controller.Add(mgr, controller.WatchOptions{
Namespace: namespace,
GVK: gvk,
ManagerFactory: factory,
ReconcilePeriod: helmOperatorFlags.ReconcilePeriod,
WatchDependentResources: true,
})
if err != nil {
log.Fatal(err)
// Set the kubeconfig that the manager will be able to grab
if namespace != "" {
if err := os.Setenv(k8sutil.WatchNamespaceEnvVar, namespace); err != nil {
log.Fatalf("Failed to set %s environment variable: (%v)", k8sutil.WatchNamespaceEnvVar, err)
}
}

// Start the Cmd
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
log.Fatal(err)
}
helm.Run(helmOperatorFlags)
}

func printVersion() {
Expand Down
6 changes: 5 additions & 1 deletion doc/dev/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,15 @@ Create a new branch to push release commits:
$ git checkout -b release-v1.3.0
```

Commit changes to the following four files:
Commit changes to the following six files:
* `version/version.go`: update `Version` to `v1.3.0`.
* `pkg/scaffold/gopkgtoml.go`, under the `[[constraint]]` for `github.com/operator-framework/operator-sdk`:
* Comment out `branch = "master"`
* Un-comment `version = "v1.2.0"`
* Change `v1.2.0` to `v1.3.0`
* `pkg/scaffold/gopkgtoml_test.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `pkg/scaffold/ansible/gopkgtoml.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `pkg/scaffold/helm/gopkgtoml.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `CHANGELOG.md`: update the `## Unreleased` header to `## v1.3.0`.

Create a new PR for `release-v1.3.0`.
Expand Down Expand Up @@ -216,6 +218,8 @@ Check out a new branch from master (or use your `release-v1.3.0`) and commit the
* Comment out `version = "v1.3.0"`
* Un-comment `branch = "master"`
* `pkg/scaffold/gopkgtoml_test.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `pkg/scaffold/ansible/gopkgtoml.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `pkg/scaffold/helm/gopkgtoml.go`: same as for `pkg/scaffold/gopkgtoml.go`.
* `CHANGELOG.md`: add the following as a new set of headers above `## v1.3.0`:
```
## Unreleased
Expand Down
24 changes: 15 additions & 9 deletions doc/dev/testing/travis-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ The Go, Ansible, and Helm tests then differ in what tests they run.
### Ansible tests

1. Run [ansible e2e tests][ansible-e2e].
1. Create base ansible operator image by running [`hack/image/scaffold-ansible-image.go`][ansible-base].
1. Create base ansible operator project by running [`hack/image/ansible/scaffold-ansible-image.go`][ansible-base].
2. Build base ansible operator image.
3. Create and configure a new ansible type memcached-operator.
4. Create cluster resources.
Expand All @@ -86,12 +86,18 @@ The Go, Ansible, and Helm tests then differ in what tests they run.
### Helm Tests

1. Run [helm e2e tests][helm-e2e].
1. Build base helm operator image from [`test/helm-operator`][helm-base].
2. Create and configure a new helm type nginx-operator.
3. Create cluster resources.
4. Wait for operator to be ready.
5. Create nginx CR and wait for it to be ready.
6. Delete nginx CR and verify that finalizer (which writes a message in the operator logs) ran.
1. Create base helm operator project by running [`hack/image/helm/scaffold-helm-image.go`][helm-base].
2. Build base helm operator image.
3. Create and configure a new helm type nginx-operator.
4. Create cluster resources.
5. Wait for operator to be ready.
6. Create nginx CR and wait for it to be ready.
7. Scale up the dependent deployment and verify the operator reconciles it back down.
8. Scale up the CR and verify the dependent deployment scales up accordingly.
9. Delete nginx CR and verify that finalizer (which writes a message in the operator logs) ran.
10. Run `operator-sdk migrate` to add go source to the operator.
11. Run `operator-sdk build` to compile the new binary and build a new image.
12. Re-run steps 4-9 to test the migrated operator.

**NOTE**: All created resources, including the namespace, are deleted using a bash trap when the test finishes

Expand All @@ -110,8 +116,8 @@ The markdown test does not create a new cluster and runs in a barebones travis V
[go-e2e]: ../../../hack/tests/e2e-go.sh
[tls-tests]: ../../../test/e2e/tls_util_test.go
[ansible-e2e]: ../../../hack/tests/e2e-ansible.sh
[ansible-base]: ../../../hack/image/scaffold-ansible-image.go
[ansible-base]: ../../../hack/image/ansible/scaffold-ansible-image.go
[helm-e2e]: ../../../hack/tests/e2e-helm.sh
[helm-base]: ../../../test/helm-operator
[helm-base]: ../../../hack/image/helm/scaffold-helm-image.go
[marker-github]: https://github.com/crawford/marker
[marker-local]: ../../../hack/ci/marker
17 changes: 17 additions & 0 deletions doc/sdk-cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,23 @@ should use `up local` instead.
$ operator-sdk run ansible --watches-file=/opt/ansible/watches.yaml --reconcile-period=30s
```

### helm

Runs as a helm operator process. This is intended to be used when running
in a Pod inside a cluster. Developers wanting to run their operator locally
should use `up local` instead.

#### Flags

* `--reconcile-period` string - Default reconcile period for controllers (default 1m0s)
* `--watches-file` string - Path to the watches file to use (default "./watches.yaml")

#### Example

```bash
$ operator-sdk run helm --watches-file=/opt/helm/watches.yaml --reconcile-period=30s
```

## test

### Available Commands
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion hack/image/build-ansible-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mkdir -p "$BASEIMAGEDIR"

# build operator binary and base image
pushd "$BASEIMAGEDIR"
go run "$ROOTDIR/hack/image/scaffold-ansible-image.go"
go run "$ROOTDIR/hack/image/ansible/scaffold-ansible-image.go"

mkdir -p build/_output/bin/
cp $ROOTDIR/build/operator-sdk-dev-x86_64-linux-gnu build/_output/bin/ansible-operator
Expand Down
17 changes: 14 additions & 3 deletions hack/image/build-helm-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@

set -eux

source hack/lib/test_lib.sh

ROOTDIR="$(pwd)"
GOTMP="$(mktemp -d -p $GOPATH/src)"
trap_add 'rm -rf $GOTMP' EXIT
BASEIMAGEDIR="$GOTMP/helm-operator"
mkdir -p "$BASEIMAGEDIR"

# build operator binary and base image
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o test/helm-operator/helm-operator test/helm-operator/cmd/helm-operator/main.go
pushd test/helm-operator
docker build -t "$1" .
pushd "$BASEIMAGEDIR"
go run "$ROOTDIR/hack/image/helm/scaffold-helm-image.go"

mkdir -p build/_output/bin/
cp $ROOTDIR/build/operator-sdk-dev-x86_64-linux-gnu build/_output/bin/helm-operator
operator-sdk build $1
popd
Loading

0 comments on commit 419cfd3

Please sign in to comment.