From 6e76ef246fe83d7e28b26cc8963c09ddc86d1592 Mon Sep 17 00:00:00 2001 From: Michael Hrivnak Date: Thu, 10 Jan 2019 16:37:49 -0500 Subject: [PATCH 1/4] pkg/ansible,pkg/scaffold/ansible; enables leader election for ansible operators --- CHANGELOG.md | 2 ++ pkg/ansible/run.go | 31 ++++++++++++++++++++++++- pkg/scaffold/ansible/deploy_operator.go | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a2b9840eb0..7b366116cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - 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)) - Ansible operator proxy added the cache handler which allows the get requests to use the operators cache. [#760](https://github.com/operator-framework/operator-sdk/pull/760) - Ansible operator proxy added ability to dynamically watch dependent resource that were created by ansible operator. [#857](https://github.com/operator-framework/operator-sdk/pull/857) +- Ansible-based operators have leader election turned on by default. When upgrading, add environment variable `POD_NAME` to your operator's Deployment using the Kubernetes downward API. To see an example, run `operator-sdk new --type=ansible ...` and see file `deploy/operator.yaml`. + ### Changed - The official images for the Ansible and Helm operators have moved! Travis now builds, tags, and pushes operator base images during CI ([#832](https://github.com/operator-framework/operator-sdk/pull/832)). diff --git a/pkg/ansible/run.go b/pkg/ansible/run.go index 30db88ca17d..4832182147f 100644 --- a/pkg/ansible/run.go +++ b/pkg/ansible/run.go @@ -15,6 +15,7 @@ package ansible import ( + "context" "os" "runtime" @@ -22,6 +23,8 @@ import ( "github.com/operator-framework/operator-sdk/pkg/ansible/operator" proxy "github.com/operator-framework/operator-sdk/pkg/ansible/proxy" "github.com/operator-framework/operator-sdk/pkg/k8sutil" + "github.com/operator-framework/operator-sdk/pkg/leader" + "github.com/operator-framework/operator-sdk/pkg/ready" sdkVersion "github.com/operator-framework/operator-sdk/version" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,6 +45,8 @@ func printVersion() { func Run(flags *aoflags.AnsibleOperatorFlags) { logf.SetLogger(logf.ZapLogger(false)) + printVersion() + namespace, found := os.LookupEnv(k8sutil.WatchNamespaceEnvVar) if found { log.Infof("Watching %v namespace.", namespace) @@ -58,7 +63,31 @@ func Run(flags *aoflags.AnsibleOperatorFlags) { log.Fatal(err) } - printVersion() + name, found := os.LookupEnv(k8sutil.OperatorNameEnvVar) + if !found { + log.Fatal("OPERATOR_NAME environment variable not set") + } + // Become the leader before proceeding + err = leader.Become(context.TODO(), name+"-lock") + if err != nil { + log.Error(err, "") + os.Exit(1) + } + + // Set ready + r := ready.NewFileReady() + err = r.Set() + if err != nil { + log.Error(err, "") + os.Exit(1) + } + defer func() { + if err = r.Unset(); err != nil { + log.Error(err, "") + os.Exit(1) + } + }() + done := make(chan error) cMap := proxy.NewControllerMap() diff --git a/pkg/scaffold/ansible/deploy_operator.go b/pkg/scaffold/ansible/deploy_operator.go index 9d17cc079e3..19fa58a80f4 100644 --- a/pkg/scaffold/ansible/deploy_operator.go +++ b/pkg/scaffold/ansible/deploy_operator.go @@ -70,6 +70,10 @@ spec: fieldRef: fieldPath: metadata.namespace {{- end}} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name - name: OPERATOR_NAME value: "{{.ProjectName}}" ` From d43cc4f4a2e630b3415cee6215971efcd3a57101 Mon Sep 17 00:00:00 2001 From: Michael Hrivnak Date: Wed, 16 Jan 2019 07:49:13 -0500 Subject: [PATCH 2/4] removes readiness probe --- pkg/ansible/run.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pkg/ansible/run.go b/pkg/ansible/run.go index 4832182147f..fa5cf8ccd17 100644 --- a/pkg/ansible/run.go +++ b/pkg/ansible/run.go @@ -24,7 +24,6 @@ import ( proxy "github.com/operator-framework/operator-sdk/pkg/ansible/proxy" "github.com/operator-framework/operator-sdk/pkg/k8sutil" "github.com/operator-framework/operator-sdk/pkg/leader" - "github.com/operator-framework/operator-sdk/pkg/ready" sdkVersion "github.com/operator-framework/operator-sdk/version" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -74,20 +73,6 @@ func Run(flags *aoflags.AnsibleOperatorFlags) { os.Exit(1) } - // Set ready - r := ready.NewFileReady() - err = r.Set() - if err != nil { - log.Error(err, "") - os.Exit(1) - } - defer func() { - if err = r.Unset(); err != nil { - log.Error(err, "") - os.Exit(1) - } - }() - done := make(chan error) cMap := proxy.NewControllerMap() From 808774a2ff6bf121b1e1f0f1eb6f8c525397df3b Mon Sep 17 00:00:00 2001 From: Fabian von Feilitzsch Date: Wed, 16 Jan 2019 20:23:09 -0500 Subject: [PATCH 3/4] Fix test-cluster and add some debug statements --- commands/operator-sdk/cmd/test/cluster.go | 4 ++++ .../ansible/build_test_framework_ansible_test_script.go | 2 +- test/ansible-memcached/asserts.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/commands/operator-sdk/cmd/test/cluster.go b/commands/operator-sdk/cmd/test/cluster.go index be9b4ad02af..2c78b3c1580 100755 --- a/commands/operator-sdk/cmd/test/cluster.go +++ b/commands/operator-sdk/cmd/test/cluster.go @@ -22,6 +22,7 @@ import ( k8sInternal "github.com/operator-framework/operator-sdk/internal/util/k8sutil" "github.com/operator-framework/operator-sdk/internal/util/projutil" + "github.com/operator-framework/operator-sdk/pkg/k8sutil" "github.com/operator-framework/operator-sdk/pkg/scaffold" "github.com/operator-framework/operator-sdk/pkg/scaffold/ansible" "github.com/operator-framework/operator-sdk/pkg/test" @@ -108,6 +109,9 @@ func testClusterFunc(cmd *cobra.Command, args []string) error { Env: []v1.EnvVar{{ Name: test.TestNamespaceEnv, ValueFrom: &v1.EnvVarSource{FieldRef: &v1.ObjectFieldSelector{FieldPath: "metadata.namespace"}}, + }, { + Name: k8sutil.OperatorNameEnvVar, + Value: "test-operator", }}, }}, }, diff --git a/pkg/scaffold/ansible/build_test_framework_ansible_test_script.go b/pkg/scaffold/ansible/build_test_framework_ansible_test_script.go index 337dc99d9a0..58de541c3a2 100644 --- a/pkg/scaffold/ansible/build_test_framework_ansible_test_script.go +++ b/pkg/scaffold/ansible/build_test_framework_ansible_test_script.go @@ -39,7 +39,7 @@ func (b *BuildTestFrameworkAnsibleTestScript) GetInput() (input.Input, error) { const buildTestFrameworkAnsibleTestScriptAnsibleTmpl = `#!/bin/sh export WATCH_NAMESPACE=${TEST_NAMESPACE} -(/usr/local/bin/entrypoint > /tmp/operator.log 2>&1)& +(/usr/local/bin/entrypoint)& trap "kill $!" SIGINT SIGTERM EXIT cd ${HOME}/project diff --git a/test/ansible-memcached/asserts.yml b/test/ansible-memcached/asserts.yml index 12edf1bd019..ab7cd34a315 100644 --- a/test/ansible-memcached/asserts.yml +++ b/test/ansible-memcached/asserts.yml @@ -22,7 +22,7 @@ - name: Wait 2 minutes for memcached deployment debug: - msg: Waiting for memcached deployment... + var: deploy until: deploy and deploy.status and deploy.status.replicas == deploy.status.get("availableReplicas", 0) retries: 12 delay: 10 From d53b8ee1540eb2774b81132c64f8a645bc80fbb0 Mon Sep 17 00:00:00 2001 From: Fabian von Feilitzsch Date: Wed, 16 Jan 2019 20:51:17 -0500 Subject: [PATCH 4/4] Add podname as well --- commands/operator-sdk/cmd/test/cluster.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/commands/operator-sdk/cmd/test/cluster.go b/commands/operator-sdk/cmd/test/cluster.go index 2c78b3c1580..c88306d392f 100755 --- a/commands/operator-sdk/cmd/test/cluster.go +++ b/commands/operator-sdk/cmd/test/cluster.go @@ -23,6 +23,7 @@ import ( k8sInternal "github.com/operator-framework/operator-sdk/internal/util/k8sutil" "github.com/operator-framework/operator-sdk/internal/util/projutil" "github.com/operator-framework/operator-sdk/pkg/k8sutil" + "github.com/operator-framework/operator-sdk/pkg/leader" "github.com/operator-framework/operator-sdk/pkg/scaffold" "github.com/operator-framework/operator-sdk/pkg/scaffold/ansible" "github.com/operator-framework/operator-sdk/pkg/test" @@ -112,6 +113,9 @@ func testClusterFunc(cmd *cobra.Command, args []string) error { }, { Name: k8sutil.OperatorNameEnvVar, Value: "test-operator", + }, { + Name: leader.PodNameEnv, + ValueFrom: &v1.EnvVarSource{FieldRef: &v1.ObjectFieldSelector{FieldPath: "metadata.name"}}, }}, }}, },