├── .github └── workflows │ ├── bug-reproduction.yml │ ├── example-controller-image-build.yml │ ├── kind-image-build.yml │ ├── oracle-generation.yml │ ├── regression-testing.yml │ └── run-sieve.yml ├── .gitignore ├── LICENSE ├── README.md ├── bug_reproduction_test_plans ├── cass-operator-intermediate-state-1.yaml ├── cass-operator-intermediate-state-2.yaml ├── cass-operator-stale-state-1.yaml ├── cassandra-operator-indirect-1.yaml ├── cassandra-operator-indirect-2.yaml ├── cassandra-operator-stale-state-1.yaml ├── cassandra-operator-stale-state-2.yaml ├── cassandra-operator-unobserved-state-1.yaml ├── casskop-intermediate-state-1.yaml ├── casskop-stale-state-1.yaml ├── casskop-stale-state-2.yaml ├── casskop-unobserved-state-1.yaml ├── elastic-operator-stale-state-1.yaml ├── elastic-operator-stale-state-2.yaml ├── mongodb-operator-indirect-1.yaml ├── mongodb-operator-indirect-2.yaml ├── mongodb-operator-indirect-3.yaml ├── mongodb-operator-intermediate-state-1.yaml ├── mongodb-operator-intermediate-state-2.yaml ├── mongodb-operator-stale-state-1.yaml ├── mongodb-operator-stale-state-2.yaml ├── mongodb-operator-stale-state-3.yaml ├── mongodb-operator-unobserved-state-1.yaml ├── nifikop-indirect-1.yaml ├── nifikop-intermediate-state-1.yaml ├── nifikop-intermediate-state-2.yaml ├── rabbitmq-operator-intermediate-state-1.yaml ├── rabbitmq-operator-stale-state-1.yaml ├── rabbitmq-operator-stale-state-2.yaml ├── rabbitmq-operator-unobserved-state-1.yaml ├── xtradb-operator-intermediate-state-1.yaml ├── xtradb-operator-intermediate-state-2.yaml ├── xtradb-operator-intermediate-state-3.yaml ├── xtradb-operator-stale-state-1.yaml ├── xtradb-operator-stale-state-2.yaml ├── xtradb-operator-stale-state-3.yaml ├── xtradb-operator-unobserved-state-1.yaml ├── yugabyte-operator-indirect-1.yaml ├── yugabyte-operator-indirect-2.yaml ├── yugabyte-operator-stale-state-1.yaml ├── yugabyte-operator-stale-state-2.yaml ├── yugabyte-operator-unobserved-state-1.yaml ├── zookeeper-operator-indirect-1.yaml ├── zookeeper-operator-stale-state-1.yaml ├── zookeeper-operator-stale-state-2.yaml └── zookeeper-operator-unobserved-state-1.yaml ├── build.py ├── check_env.py ├── check_test_plan_gen.py ├── config.json ├── deploy_script ├── configure.sh ├── docker.yaml ├── go.yaml ├── helm.yaml ├── kind.yaml ├── kubectl.yaml ├── python.yaml └── vars │ └── default.yaml ├── docs ├── bugs.md ├── demo.md ├── paper-hotos.pdf ├── paper-osdi.pdf ├── port.md ├── poster.pdf ├── reprod.md ├── rfe │ └── decouple_perturbation_policy_and_mechanism │ │ └── doc.md ├── sieve-action.md ├── sieve-arch.png └── stale-state.png ├── examples ├── cass-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── controller-manifest.yaml │ │ ├── deploy.sh │ │ └── storageClass.yaml │ ├── oracle │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaledown-scaleup │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── cdc-1.yaml │ │ ├── cdc-2.yaml │ │ └── test.py ├── cassandra-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── bundle.yaml │ │ ├── crds.yaml │ │ └── deploy.sh │ ├── oracle │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── scaledown-scaleup-brittle │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaledown-scaleup │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── cdc-1.yaml │ │ ├── cdc-2.yaml │ │ └── test.py ├── casskop-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── Chart.yaml │ │ ├── crds │ │ │ ├── db.orange.com_cassandrabackups_crd.yaml │ │ │ ├── db.orange.com_cassandraclusters_crd.yaml │ │ │ └── db.orange.com_cassandrarestores_crd.yaml │ │ ├── deploy.sh │ │ ├── readme.md │ │ ├── templates │ │ │ ├── _functions.tpl │ │ │ ├── deployment.yaml │ │ │ ├── role.yaml │ │ │ ├── rolebinding.yaml │ │ │ ├── service.yaml │ │ │ └── service_account.yaml │ │ └── values.yaml │ ├── oracle │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── reducepdb │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaledown-to-zero │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── cassandra-configmap-v1.yaml │ │ ├── cc-1.yaml │ │ ├── cc-2.yaml │ │ ├── dc-1.yaml │ │ ├── dc-2.yaml │ │ ├── dc-3.yaml │ │ ├── nodes-0.yaml │ │ ├── nodes-1.yaml │ │ ├── nodes-2.yaml │ │ └── test.py ├── elastic-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── crds.yaml │ │ ├── deploy.sh │ │ └── operator.yaml │ ├── oracle │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaledown-scaleup │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── es-1.yaml │ │ ├── es-2.yaml │ │ └── test.py ├── kapp-controller │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── default-ns.yml │ │ ├── deploy.sh │ │ └── release.yml │ └── test │ │ ├── app.yml │ │ └── test.py ├── mongodb-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── bundle.yaml │ │ └── deploy.sh │ ├── oracle │ │ ├── disable-enable-arbiter │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── disable-enable-shard-brittle │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── disable-enable-shard │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── run-cert-manager │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaleup-scaledown │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── cr-1.yaml │ │ ├── cr-arbiter.yaml │ │ ├── cr-shard.yaml │ │ ├── cr.yaml │ │ └── test.py ├── nifikop-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── Chart.yaml │ │ ├── crds │ │ │ ├── nifi.orange.com_nificlusters.yaml │ │ │ ├── nifi.orange.com_nifidataflows.yaml │ │ │ ├── nifi.orange.com_nifiparametercontexts.yaml │ │ │ ├── nifi.orange.com_nifiregistryclients.yaml │ │ │ ├── nifi.orange.com_nifiusergroups.yaml │ │ │ └── nifi.orange.com_nifiusers.yaml │ │ ├── deploy.sh │ │ ├── role.yaml │ │ ├── templates │ │ │ ├── NOTES.txt │ │ │ ├── _functions.tpl │ │ │ ├── deployment.yaml │ │ │ ├── role.yaml │ │ │ ├── role_binding.yaml │ │ │ ├── service.yaml │ │ │ └── service_account.yaml │ │ ├── values.yaml │ │ └── zk.sh │ ├── oracle │ │ ├── change-config │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaledown-scaleup │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── nc-1.yaml │ │ ├── nc-2.yaml │ │ ├── nc-config.yaml │ │ └── test.py ├── rabbitmq-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── cluster-operator.yaml │ │ └── deploy.sh │ ├── oracle │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── resize-pvc │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaleup-scaledown │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── rmqc-1-15Gi.yaml │ │ ├── rmqc-1.yaml │ │ └── test.py ├── xtradb-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── bundle.yaml │ │ └── deploy.sh │ ├── oracle │ │ ├── disable-enable-haproxy │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── disable-enable-proxysql │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── run-cert-manager │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaleup-scaledown │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── cr-4.yaml │ │ ├── cr-haproxy-disabled.yaml │ │ ├── cr-haproxy-enabled.yaml │ │ ├── cr-proxysql-disabled.yaml │ │ ├── cr-proxysql-enabled.yaml │ │ ├── cr.yaml │ │ └── test.py ├── yugabyte-operator │ ├── build │ │ ├── Dockerfile │ │ └── build.sh │ ├── config.json │ ├── deploy │ │ ├── crds │ │ │ ├── yugabyte.com_v1alpha1_ybcluster_cr.yaml │ │ │ ├── yugabyte.com_v1alpha1_ybcluster_full_cr.yaml │ │ │ └── yugabyte.com_ybclusters_crd.yaml │ │ ├── deploy.sh │ │ └── operator.yaml │ ├── oracle │ │ ├── disable-enable-tls │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── disable-enable-tuiport │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ ├── recreate │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ │ └── scaleup-scaledown-tserver │ │ │ ├── controller_family.json │ │ │ ├── event.json │ │ │ ├── mask.json │ │ │ └── state.json │ └── test │ │ ├── test.py │ │ ├── yb-1.yaml │ │ ├── yb-tls-enabled.yaml │ │ └── yb-tserverUIPort-enabled.yaml └── zookeeper-operator │ ├── build │ ├── Dockerfile │ └── build.sh │ ├── config.json │ ├── deploy │ ├── crds │ │ └── zookeeper.pravega.io_zookeeperclusters_crd.yaml │ ├── default_ns │ │ ├── operator.yaml │ │ └── rbac.yaml │ └── deploy.sh │ ├── oracle │ ├── recreate │ │ ├── controller_family.json │ │ ├── event.json │ │ ├── mask.json │ │ └── state.json │ └── scaledown-scaleup │ │ ├── controller_family.json │ │ ├── event.json │ │ ├── mask.json │ │ └── state.json │ └── test │ ├── test.py │ ├── zkc-1.yaml │ └── zkc-2.yaml ├── format.sh ├── gen_github_action.py ├── go.work ├── go.work.sum ├── parallel_testing ├── README.md ├── combine_json.py ├── gen_commands.py ├── runlearn.py └── runtest.sh ├── pyproject.toml ├── report_bugs.py ├── reproduce_bugs.py ├── requirements.txt ├── sieve.py ├── sieve_analyzer ├── __init__.py ├── analyze.py └── event_graph.py ├── sieve_aux └── csi-driver │ ├── csi-storageclass.yaml │ ├── deploy │ ├── kubernetes-1.21-test │ │ ├── README.md │ │ ├── deploy.sh │ │ ├── destroy.sh │ │ ├── hostpath │ │ │ ├── csi-hostpath-attacher.yaml │ │ │ ├── csi-hostpath-driverinfo.yaml │ │ │ ├── csi-hostpath-plugin.yaml │ │ │ ├── csi-hostpath-provisioner.yaml │ │ │ ├── csi-hostpath-resizer.yaml │ │ │ ├── csi-hostpath-snapshotclass.yaml │ │ │ ├── csi-hostpath-snapshotter.yaml │ │ │ └── csi-hostpath-testing.yaml │ │ └── test-driver.yaml │ ├── kubernetes-1.21 │ │ ├── README.md │ │ ├── deploy.sh │ │ ├── destroy.sh │ │ ├── hostpath │ │ │ ├── csi-hostpath-driverinfo.yaml │ │ │ ├── csi-hostpath-plugin.yaml │ │ │ ├── csi-hostpath-snapshotclass.yaml │ │ │ └── csi-hostpath-testing.yaml │ │ └── test-driver.yaml │ ├── kubernetes-latest │ ├── kubernetes-latest-test │ └── util │ │ ├── deploy-hostpath.sh │ │ └── destroy-hostpath.sh │ └── install.sh ├── sieve_client ├── common.go ├── go.mod ├── go.sum ├── learn_client.go ├── test_client.go └── types.go ├── sieve_common ├── __init__.py ├── common.py ├── config.py ├── event_delta.py └── k8s_event.py ├── sieve_instrumentation ├── go.mod ├── go.sum ├── instrumentation.go └── main.go ├── sieve_oracle ├── __init__.py ├── checker_common.py ├── customized_safety_checker.py ├── liveness_checker.py ├── oracle.py └── safety_checker.py ├── sieve_perturbation_policies ├── __init__.py ├── common.py ├── intermediate_state.py ├── stale_state.py └── unobserved_state.py ├── sieve_server ├── common.go ├── config.go ├── event.go ├── expression.go ├── go.mod ├── go.sum ├── learn_server.go ├── notification.go ├── server.go ├── stack.go ├── state_machine.go ├── test_coordinator.go ├── test_plan.go └── trigger_graph.go ├── sieve_test_driver ├── __init__.py └── test_framework.py └── start_porting.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | __pycache__/ 3 | *.pyc 4 | sieve_instrumentation/instrumentation 5 | sieve_instrumentation/config.json 6 | sieve_server/sieve-server 7 | sieve_server/server.yaml 8 | sieve_server/configured_field_key_mask.json 9 | sieve_server/configured_field_path_mask.json 10 | sieve_server/learned_field_path_mask.json 11 | fakegopath/ 12 | app/ 13 | kind_configs/ 14 | deploy_script/ansible_hosts 15 | sieve_test_results/ 16 | sieve_learn_results/ 17 | parallel_testing/commands.txt 18 | parallel_testing/pull-commands.txt 19 | parallel_testing/hosts 20 | parallel_testing/remotehosts 21 | parallel_testing/test-summary-*.json 22 | parallel_testing/massive-testing-* 23 | sieve_config.json 24 | test_plan_stats.tsv 25 | bug_reproduction_stats.tsv 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, sieve 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cass-operator-intermediate-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: cass-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectCreate 10 | resourceKey: secret/default/cassandra-datacenter-ca-keystore 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/datastax/cass-operator/operator/pkg/reconciliation.(*ReconcileCassandraDatacenter).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cass-operator-intermediate-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: cass-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectUpdate 10 | resourceKey: pod/default/cluster1-cassandra-datacenter-default-sts-0 11 | prevStateDiff: '{"metadata": {"labels": {"cassandra.datastax.com/node-state": 12 | "Ready-to-Start"}}}' 13 | curStateDiff: '{"metadata": {"labels": {"cassandra.datastax.com/node-state": 14 | "Starting", "cassandra.datastax.com/seed-node": "true"}}}' 15 | occurrence: 2 16 | observationPoint: 17 | when: afterControllerWrite 18 | by: github.com/datastax/cass-operator/operator/pkg/reconciliation.(*ReconcileCassandraDatacenter).Reconcile 19 | expression: trigger1 20 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cass-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: cassandradatacenter/default/cassandra-datacenter 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: cassandradatacenter/default/cassandra-datacenter 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: cass-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/server-data-cluster1-cassandra-datacenter-default-sts-0 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: cassandradatacenter/default/cassandra-datacenter 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cassandra-operator-indirect-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cassandra-operator-indirect-2.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup-brittle 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cassandra-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: cassandradatacenter/default/cassandra-datacenter 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: cassandradatacenter/default/cassandra-datacenter 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: cassandra-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/data-volume-cassandra-test-cluster-dc1-rack1-0 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: cassandradatacenter/default/cassandra-datacenter 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cassandra-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: pod/default/cassandra-test-cluster-dc1-rack1-1 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: pod/default/cassandra-test-cluster-dc1-rack1-1 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | convertStateToAPIForm: true 16 | occurrence: 1 17 | observationPoint: 18 | when: afterAPIServerRecv 19 | by: kind-control-plane3 20 | expression: trigger1 21 | - actionType: reconnectController 22 | controllerLabel: cassandra-operator 23 | reconnectAPIServer: kind-control-plane3 24 | async: true 25 | waitBefore: 10 26 | trigger: 27 | definitions: 28 | - triggerName: trigger2 29 | condition: 30 | conditionType: onObjectCreate 31 | resourceKey: persistentvolumeclaim/default/data-volume-cassandra-test-cluster-dc1-rack1-1 32 | occurrence: 1 33 | observationPoint: 34 | when: afterAPIServerRecv 35 | by: kind-control-plane 36 | expression: trigger2 37 | - actionType: resumeAPIServer 38 | apiServerName: kind-control-plane3 39 | pauseScope: pod/default/cassandra-test-cluster-dc1-rack1-1 40 | trigger: 41 | definitions: 42 | - triggerName: trigger3 43 | condition: 44 | conditionType: onTimeout 45 | timeoutValue: 20 46 | expression: trigger3 47 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/cassandra-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: pod/default/cassandra-test-cluster-dc1-rack1-1 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: pod/default/cassandra-test-cluster-dc1-rack1-1 13 | prevStateDiff: '{"metadata": {}}' 14 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 15 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 16 | occurrence: 1 17 | observationPoint: 18 | when: beforeControllerRecv 19 | by: informer 20 | expression: trigger1 21 | - actionType: resumeController 22 | pauseAt: beforeControllerRead 23 | pauseScope: pod/default/cassandra-test-cluster-dc1-rack1-1 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onAnyFieldModification 29 | resourceKey: pod/default/cassandra-test-cluster-dc1-rack1-1 30 | prevStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 31 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 32 | occurrence: 1 33 | observationPoint: 34 | when: afterControllerRecv 35 | by: informer 36 | - triggerName: trigger3 37 | condition: 38 | conditionType: onObjectDelete 39 | resourceKey: pod/default/cassandra-test-cluster-dc1-rack1-1 40 | occurrence: 1 41 | observationPoint: 42 | when: afterControllerRecv 43 | by: informer 44 | expression: trigger2|trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/casskop-intermediate-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-to-zero 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: casskop-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectUpdate 10 | resourceKey: statefulset/default/cassandra-cluster-dc1-rack1 11 | prevStateDiff: '{"spec": {"replicas": 2}}' 12 | curStateDiff: '{"spec": {"replicas": 1}}' 13 | occurrence: 1 14 | observationPoint: 15 | when: afterControllerWrite 16 | by: github.com/Orange-OpenSource/casskop/pkg/controller/cassandracluster.(*ReconcileCassandraCluster).Reconcile 17 | expression: trigger1 18 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/casskop-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: cassandracluster/default/cassandra-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: cassandracluster/default/cassandra-cluster 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: casskop-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/data-cassandra-cluster-dc1-rack1-0 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: cassandracluster/default/cassandra-cluster 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/casskop-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: reducepdb 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: cassandracluster/default/cassandra-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: cassandracluster/default/cassandra-cluster 12 | prevStateDiff: '{"spec": {"maxPodUnavailable": 4}}' 13 | curStateDiff: '{"spec": {"maxPodUnavailable": 1}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: beforeAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: casskop-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: poddisruptionbudget/default/cassandra-cluster 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: cassandracluster/default/cassandra-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/casskop-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-to-zero 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: cassandracluster/default/cassandra-cluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: cassandracluster/default/cassandra-cluster 13 | prevStateDiff: '{"spec": {"topology": {"dc": [{"nodesPerRacks": 2}]}}}' 14 | curStateDiff: '{"spec": {"topology": {"dc": [{"nodesPerRacks": 1}]}}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: beforeControllerRecv 18 | by: informer 19 | expression: trigger1 20 | - actionType: resumeController 21 | pauseAt: beforeControllerRead 22 | pauseScope: cassandracluster/default/cassandra-cluster 23 | trigger: 24 | definitions: 25 | - triggerName: trigger2 26 | condition: 27 | conditionType: onAnyFieldModification 28 | resourceKey: cassandracluster/default/cassandra-cluster 29 | prevStateDiff: '{"spec": {"topology": {"dc": [{"nodesPerRacks": 1}]}}}' 30 | occurrence: 1 31 | observationPoint: 32 | when: afterControllerRecv 33 | by: informer 34 | - triggerName: trigger3 35 | condition: 36 | conditionType: onObjectDelete 37 | resourceKey: cassandracluster/default/cassandra-cluster 38 | occurrence: 1 39 | observationPoint: 40 | when: afterControllerRecv 41 | by: informer 42 | expression: trigger2|trigger3 43 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/elastic-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: elasticsearch/default/elasticsearch-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectDelete 11 | resourceKey: elasticsearch/default/elasticsearch-cluster 12 | occurrence: 1 13 | observationPoint: 14 | when: afterAPIServerRecv 15 | by: kind-control-plane3 16 | expression: trigger1 17 | - actionType: reconnectController 18 | controllerLabel: elastic-operator 19 | reconnectAPIServer: kind-control-plane3 20 | async: true 21 | waitBefore: 10 22 | trigger: 23 | definitions: 24 | - triggerName: trigger2 25 | condition: 26 | conditionType: onObjectCreate 27 | resourceKey: secret/default/elasticsearch-cluster-es-transport-certs-public 28 | occurrence: 1 29 | observationPoint: 30 | when: afterAPIServerRecv 31 | by: kind-control-plane 32 | expression: trigger2 33 | - actionType: resumeAPIServer 34 | apiServerName: kind-control-plane3 35 | pauseScope: elasticsearch/default/elasticsearch-cluster 36 | trigger: 37 | definitions: 38 | - triggerName: trigger3 39 | condition: 40 | conditionType: onTimeout 41 | timeoutValue: 20 42 | expression: trigger3 43 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/elastic-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: elasticsearch/default/elasticsearch-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: elasticsearch/default/elasticsearch-cluster 12 | prevStateDiff: '{"spec": {"nodeSets": [{"count": 1}]}}' 13 | curStateDiff: '{"spec": {"nodeSets": [{"count": 2}]}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: beforeAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: elastic-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: poddisruptionbudget/default/elasticsearch-cluster-es-default 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: elasticsearch/default/elasticsearch-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-indirect-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-shard 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-indirect-3.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-shard-brittle 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-intermediate-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-shard 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: mongodb-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectCreate 10 | resourceKey: secret/default/mongodb-cluster-ssl 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-intermediate-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: run-cert-manager 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: mongodb-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectCreate 10 | resourceKey: certificate/default/mongodb-cluster-ssl 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaservermongodb/default/mongodb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaservermongodb/default/mongodb-cluster 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: mongodb-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/mongod-data-mongodb-cluster-rs0-2 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: perconaservermongodb/default/mongodb-cluster 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-shard 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaservermongodb/default/mongodb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaservermongodb/default/mongodb-cluster 12 | prevStateDiff: '{"spec": {"sharding": {"enabled": true}}}' 13 | curStateDiff: '{"spec": {"sharding": {"enabled": false}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: mongodb-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: statefulset/default/mongodb-cluster-cfg 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: perconaservermongodb/default/mongodb-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-stale-state-3.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-arbiter 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaservermongodb/default/mongodb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaservermongodb/default/mongodb-cluster 12 | prevStateDiff: '{"spec": {"replsets": [{"arbiter": {"enabled": true}}]}}' 13 | curStateDiff: '{"spec": {"replsets": [{"arbiter": {"enabled": false}}]}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: mongodb-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: statefulset/default/mongodb-cluster-rs0-arbiter 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: perconaservermongodb/default/mongodb-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/mongodb-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-arbiter 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: perconaservermongodb/default/mongodb-cluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: perconaservermongodb/default/mongodb-cluster 13 | prevStateDiff: '{"spec": {"replsets": [{"arbiter": {"enabled": true}}]}}' 14 | curStateDiff: '{"spec": {"replsets": [{"arbiter": {"enabled": false}}]}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: beforeControllerRecv 18 | by: informer 19 | expression: trigger1 20 | - actionType: resumeController 21 | pauseAt: beforeControllerRead 22 | pauseScope: perconaservermongodb/default/mongodb-cluster 23 | trigger: 24 | definitions: 25 | - triggerName: trigger2 26 | condition: 27 | conditionType: onAnyFieldModification 28 | resourceKey: perconaservermongodb/default/mongodb-cluster 29 | prevStateDiff: '{"spec": {"replsets": [{"arbiter": {"enabled": false}}]}}' 30 | occurrence: 1 31 | observationPoint: 32 | when: afterControllerRecv 33 | by: informer 34 | - triggerName: trigger3 35 | condition: 36 | conditionType: onObjectDelete 37 | resourceKey: perconaservermongodb/default/mongodb-cluster 38 | occurrence: 1 39 | observationPoint: 40 | when: afterControllerRecv 41 | by: informer 42 | expression: trigger2|trigger3 43 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/nifikop-indirect-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: nifikop-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectUpdate 10 | resourceKey: nificluster/default/simplenifi 11 | prevStateDiff: '{"metadata": {}, "status": {"prometheusReportingTask": {"version": 12 | 0}}}' 13 | curStateDiff: '{"metadata": {"finalizers": ["nificlusters.nifi.orange.com/finalizer"]}, 14 | "status": {"prometheusReportingTask": {"version": 2}, "rootProcessGroupId": 15 | "SIEVE-NON-NIL"}}' 16 | occurrence: 1 17 | observationPoint: 18 | when: afterControllerWrite 19 | by: github.com/Orange-OpenSource/nifikop/controllers.(*NifiClusterReconciler) 20 | expression: trigger1 21 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/nifikop-intermediate-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: nifikop-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectUpdate 10 | resourceKey: nificluster/default/simplenifi 11 | prevStateDiff: '{"metadata": {"selfLink": "/apis/nifi.orange.com/v1alpha1/namespaces/default/nificlusters/simplenifi"}, 12 | "status": {"state": ""}}' 13 | curStateDiff: '{"metadata": {"selfLink": "/apis/nifi.orange.com/v1alpha1/namespaces/default/nificlusters/simplenifi/status"}, 14 | "status": {"nodesState": {"1": {"configurationState": "ConfigInSync", "gracefulActionState": 15 | {"actionState": "", "errorMessage": ""}, "initClusterNode": true}}, "state": 16 | "ClusterReconciling"}}' 17 | occurrence: 2 18 | observationPoint: 19 | when: afterControllerWrite 20 | by: github.com/Orange-OpenSource/nifikop/controllers.(*NifiClusterReconciler).Reconcile 21 | expression: trigger1 22 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/rabbitmq-operator-intermediate-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: resize-pvc 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: rabbitmq-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectDelete 10 | resourceKey: statefulset/default/rabbitmq-cluster-server 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/rabbitmq/cluster-operator/controllers.(*RabbitmqClusterReconciler).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/rabbitmq-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: rabbitmqcluster/default/rabbitmq-cluster 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: rabbitmq-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: statefulset/default/rabbitmq-cluster-server 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/rabbitmq-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: resize-pvc 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: rabbitmqcluster/default/rabbitmq-cluster 12 | prevStateDiff: '{"spec": {"persistence": {"storage": "10Gi"}}}' 13 | curStateDiff: '{"spec": {"persistence": {"storage": "15Gi"}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: beforeAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: rabbitmq-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: statefulset/default/rabbitmq-cluster-server 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/rabbitmq-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaleup-scaledown 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: rabbitmqcluster/default/rabbitmq-cluster 13 | prevStateDiff: '{"spec": {"replicas": 1}}' 14 | curStateDiff: '{"spec": {"replicas": 3}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: beforeControllerRecv 18 | by: informer 19 | expression: trigger1 20 | - actionType: resumeController 21 | pauseAt: beforeControllerRead 22 | pauseScope: rabbitmqcluster/default/rabbitmq-cluster 23 | trigger: 24 | definitions: 25 | - triggerName: trigger2 26 | condition: 27 | conditionType: onAnyFieldModification 28 | resourceKey: rabbitmqcluster/default/rabbitmq-cluster 29 | prevStateDiff: '{"spec": {"replicas": 3}}' 30 | occurrence: 1 31 | observationPoint: 32 | when: afterControllerRecv 33 | by: informer 34 | - triggerName: trigger3 35 | condition: 36 | conditionType: onObjectDelete 37 | resourceKey: rabbitmqcluster/default/rabbitmq-cluster 38 | occurrence: 1 39 | observationPoint: 40 | when: afterControllerRecv 41 | by: informer 42 | expression: trigger2|trigger3 43 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-intermediate-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-proxysql 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: xtradb-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectCreate 10 | resourceKey: secret/default/xtradb-cluster-ssl 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/percona/percona-xtradb-cluster-operator/pkg/controller/pxc.(*ReconcilePerconaXtraDBCluster).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-intermediate-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: run-cert-manager 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: xtradb-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectCreate 10 | resourceKey: certificate/default/xtradb-cluster-ssl 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/percona/percona-xtradb-cluster-operator/pkg/controller/pxc.(*ReconcilePerconaXtraDBCluster).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-intermediate-state-3.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: restartController 4 | controllerLabel: xtradb-operator 5 | trigger: 6 | definitions: 7 | - triggerName: trigger1 8 | condition: 9 | conditionType: onObjectDelete 10 | resourceKey: statefulset/default/xtradb-cluster-pxc 11 | occurrence: 1 12 | observationPoint: 13 | when: afterControllerWrite 14 | by: github.com/percona/percona-xtradb-cluster-operator/pkg/controller/pxc.(*ReconcilePerconaXtraDBCluster).Reconcile 15 | expression: trigger1 16 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: xtradb-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/datadir-xtradb-cluster-pxc-2 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-haproxy 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 12 | prevStateDiff: '{"spec": {"haproxy": {"enabled": true}}}' 13 | curStateDiff: '{"spec": {"haproxy": {}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: xtradb-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: statefulset/default/xtradb-cluster-haproxy 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-stale-state-3.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-proxysql 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 12 | prevStateDiff: '{"spec": {"proxysql": {"enabled": true}}}' 13 | curStateDiff: '{"spec": {"proxysql": {}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: xtradb-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: statefulset/default/xtradb-cluster-proxysql 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/xtradb-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaleup-scaledown 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 13 | prevStateDiff: '{"spec": {"pxc": {"size": 3}}}' 14 | curStateDiff: '{"spec": {"pxc": {"size": 5}}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: beforeControllerRecv 18 | by: informer 19 | expression: trigger1 20 | - actionType: resumeController 21 | pauseAt: beforeControllerRead 22 | pauseScope: perconaxtradbcluster/default/xtradb-cluster 23 | trigger: 24 | definitions: 25 | - triggerName: trigger2 26 | condition: 27 | conditionType: onAnyFieldModification 28 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 29 | prevStateDiff: '{"spec": {"pxc": {"size": 5}}}' 30 | occurrence: 1 31 | observationPoint: 32 | when: afterControllerRecv 33 | by: informer 34 | - triggerName: trigger3 35 | condition: 36 | conditionType: onObjectDelete 37 | resourceKey: perconaxtradbcluster/default/xtradb-cluster 38 | occurrence: 1 39 | observationPoint: 40 | when: afterControllerRecv 41 | by: informer 42 | expression: trigger2|trigger3 43 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/yugabyte-operator-indirect-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-tuiport 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/yugabyte-operator-indirect-2.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-tls 2 | actions: null 3 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/yugabyte-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-tls 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: ybcluster/default/example-ybcluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: ybcluster/default/example-ybcluster 12 | prevStateDiff: '{"spec": {"tls": {"enabled": true}}}' 13 | curStateDiff: '{"spec": {"tls": {}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: yugabyte-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: secret/default/yb-tserver-yugabyte-tls-cert 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: ybcluster/default/example-ybcluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/yugabyte-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: disable-enable-tuiport 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: ybcluster/default/example-ybcluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: ybcluster/default/example-ybcluster 12 | prevStateDiff: '{"spec": {"tserver": {"tserverUIPort": 9000}}}' 13 | curStateDiff: '{"spec": {"tserver": {}}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: yugabyte-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: service/default/yb-tserver-ui 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: ybcluster/default/example-ybcluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/yugabyte-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaleup-scaledown-tserver 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: ybcluster/default/example-ybcluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectUpdate 12 | resourceKey: ybcluster/default/example-ybcluster 13 | prevStateDiff: '{"spec": {"replicationFactor": 3, "tserver": {"replicas": 14 | 3}}}' 15 | curStateDiff: '{"spec": {"replicationFactor": 4, "tserver": {"replicas": 4}}}' 16 | occurrence: 1 17 | observationPoint: 18 | when: beforeControllerRecv 19 | by: informer 20 | expression: trigger1 21 | - actionType: resumeController 22 | pauseAt: beforeControllerRead 23 | pauseScope: ybcluster/default/example-ybcluster 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onAnyFieldModification 29 | resourceKey: ybcluster/default/example-ybcluster 30 | prevStateDiff: '{"spec": {"replicationFactor": 4, "tserver": {"replicas": 31 | 4}}}' 32 | occurrence: 1 33 | observationPoint: 34 | when: afterControllerRecv 35 | by: informer 36 | - triggerName: trigger3 37 | condition: 38 | conditionType: onObjectDelete 39 | resourceKey: ybcluster/default/example-ybcluster 40 | occurrence: 1 41 | observationPoint: 42 | when: afterControllerRecv 43 | by: informer 44 | expression: trigger2|trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/zookeeper-operator-indirect-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: afterControllerWrite 5 | pauseScope: zookeepercluster/default/zookeeper-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: zookeepercluster/default/zookeeper-cluster 12 | prevStateDiff: '{"metadata": {"finalizers": ["cleanUpZookeeperPVC"]}}' 13 | curStateDiff: '{"metadata": {}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterControllerWrite 17 | by: github.com/pravega/zookeeper-operator/pkg/controller/zookeepercluster.(*ReconcileZookeeperCluster).Reconcile 18 | expression: trigger1 19 | - actionType: resumeController 20 | pauseAt: afterControllerWrite 21 | pauseScope: zookeepercluster/default/zookeeper-cluster 22 | trigger: 23 | definitions: 24 | - triggerName: trigger2 25 | condition: 26 | conditionType: onObjectDelete 27 | resourceKey: statefulset/default/zookeeper-cluster 28 | occurrence: 1 29 | observationPoint: 30 | when: afterControllerRecv 31 | by: informer 32 | - triggerName: trigger3 33 | condition: 34 | conditionType: onObjectDelete 35 | resourceKey: configmap/default/zookeeper-cluster-configmap 36 | occurrence: 1 37 | observationPoint: 38 | when: afterControllerRecv 39 | by: informer 40 | - triggerName: trigger4 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 3 44 | expression: trigger2&trigger3|trigger4 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/zookeeper-operator-stale-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: recreate 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: zookeepercluster/default/zookeeper-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: zookeepercluster/default/zookeeper-cluster 12 | prevStateDiff: '{"metadata": {}}' 13 | curStateDiff: '{"metadata": {"deletionGracePeriodSeconds": "SIEVE-NON-NIL", 14 | "deletionTimestamp": "SIEVE-NON-NIL"}}' 15 | occurrence: 1 16 | observationPoint: 17 | when: afterAPIServerRecv 18 | by: kind-control-plane3 19 | expression: trigger1 20 | - actionType: reconnectController 21 | controllerLabel: zookeeper-operator 22 | reconnectAPIServer: kind-control-plane3 23 | async: true 24 | waitBefore: 10 25 | trigger: 26 | definitions: 27 | - triggerName: trigger2 28 | condition: 29 | conditionType: onObjectCreate 30 | resourceKey: persistentvolumeclaim/default/data-zookeeper-cluster-0 31 | occurrence: 1 32 | observationPoint: 33 | when: afterAPIServerRecv 34 | by: kind-control-plane 35 | expression: trigger2 36 | - actionType: resumeAPIServer 37 | apiServerName: kind-control-plane3 38 | pauseScope: zookeepercluster/default/zookeeper-cluster 39 | trigger: 40 | definitions: 41 | - triggerName: trigger3 42 | condition: 43 | conditionType: onTimeout 44 | timeoutValue: 20 45 | expression: trigger3 46 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/zookeeper-operator-stale-state-2.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: pauseAPIServer 4 | apiServerName: kind-control-plane3 5 | pauseScope: zookeepercluster/default/zookeeper-cluster 6 | trigger: 7 | definitions: 8 | - triggerName: trigger1 9 | condition: 10 | conditionType: onObjectUpdate 11 | resourceKey: zookeepercluster/default/zookeeper-cluster 12 | prevStateDiff: '{"status": {"readyReplicas": 2}}' 13 | curStateDiff: '{"status": {"readyReplicas": 1}}' 14 | occurrence: 1 15 | observationPoint: 16 | when: afterAPIServerRecv 17 | by: kind-control-plane3 18 | expression: trigger1 19 | - actionType: reconnectController 20 | controllerLabel: zookeeper-operator 21 | reconnectAPIServer: kind-control-plane3 22 | async: true 23 | waitBefore: 10 24 | trigger: 25 | definitions: 26 | - triggerName: trigger2 27 | condition: 28 | conditionType: onObjectCreate 29 | resourceKey: persistentvolumeclaim/default/data-zookeeper-cluster-1 30 | occurrence: 1 31 | observationPoint: 32 | when: afterAPIServerRecv 33 | by: kind-control-plane 34 | expression: trigger2 35 | - actionType: resumeAPIServer 36 | apiServerName: kind-control-plane3 37 | pauseScope: zookeepercluster/default/zookeeper-cluster 38 | trigger: 39 | definitions: 40 | - triggerName: trigger3 41 | condition: 42 | conditionType: onTimeout 43 | timeoutValue: 20 44 | expression: trigger3 45 | -------------------------------------------------------------------------------- /bug_reproduction_test_plans/zookeeper-operator-unobserved-state-1.yaml: -------------------------------------------------------------------------------- 1 | workload: scaledown-scaleup 2 | actions: 3 | - actionType: pauseController 4 | pauseAt: beforeControllerRead 5 | pauseScope: zookeepercluster/default/zookeeper-cluster 6 | avoidOngoingRead: true 7 | trigger: 8 | definitions: 9 | - triggerName: trigger1 10 | condition: 11 | conditionType: onObjectCreate 12 | resourceKey: zookeepercluster/default/zookeeper-cluster 13 | occurrence: 1 14 | observationPoint: 15 | when: beforeControllerRecv 16 | by: informer 17 | expression: trigger1 18 | - actionType: resumeController 19 | pauseAt: beforeControllerRead 20 | pauseScope: zookeepercluster/default/zookeeper-cluster 21 | trigger: 22 | definitions: 23 | - triggerName: trigger2 24 | condition: 25 | conditionType: onObjectUpdate 26 | resourceKey: zookeepercluster/default/zookeeper-cluster 27 | occurrence: 1 28 | observationPoint: 29 | when: afterControllerRecv 30 | by: informer 31 | - triggerName: trigger3 32 | condition: 33 | conditionType: onObjectDelete 34 | resourceKey: zookeepercluster/default/zookeeper-cluster 35 | occurrence: 1 36 | observationPoint: 37 | when: afterControllerRecv 38 | by: informer 39 | expression: trigger2|trigger3 40 | -------------------------------------------------------------------------------- /check_test_plan_gen.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | 5 | def check_bug_reproduction_test_plans(): 6 | gen_configs = glob.glob( 7 | os.path.join( 8 | "sieve_learn_results/*/*/learn/*/*.yaml", 9 | ) 10 | ) 11 | 12 | reprod_configs = glob.glob("bug_reproduction_test_plans/*.yaml") 13 | 14 | for reprod_config in reprod_configs: 15 | if "indirect" in reprod_config: 16 | continue 17 | found = False 18 | for gen_config in gen_configs: 19 | if open(reprod_config).read() == open(gen_config).read(): 20 | print(reprod_config + " <= " + gen_config) 21 | found = True 22 | if not found: 23 | print("\033[91m" + reprod_config + " not found\033[0m") 24 | 25 | 26 | check_bug_reproduction_test_plans() 27 | -------------------------------------------------------------------------------- /deploy_script/configure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ansible-playbook docker.yaml -i ansible_hosts 3 | ansible-playbook go.yaml -i ansible_hosts 4 | ansible-playbook python.yaml -i ansible_hosts 5 | ansible-playbook kind.yaml -i ansible_hosts 6 | ansible-playbook kubectl.yaml -i ansible_hosts 7 | ansible-playbook helm.yaml -i ansible_hosts 8 | -------------------------------------------------------------------------------- /deploy_script/docker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Docker 3 | hosts: ec2 4 | become: true 5 | vars_files: 6 | - vars/default.yaml 7 | 8 | tasks: 9 | - name: Update apt packages 10 | apt: 11 | update_cache: "yes" 12 | force_apt_get: "yes" 13 | 14 | - name: Install packages needed for Docker 15 | apt: 16 | name: "{{ DOCKER_DEPS }}" 17 | state: present 18 | update_cache: yes 19 | 20 | - name: Add Docker GPG apt Key 21 | apt_key: 22 | url: https://download.docker.com/linux/ubuntu/gpg 23 | state: present 24 | 25 | - name: Save the current Ubuntu release version into a variable 26 | shell: lsb_release -cs 27 | register: ubuntu_version 28 | 29 | - name: Add Docker Repository 30 | apt_repository: 31 | repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ubuntu_version.stdout }} stable" 32 | state: present 33 | 34 | - name: Update apt packages 35 | apt: 36 | update_cache: "yes" 37 | force_apt_get: "yes" 38 | 39 | - name: Install Docker 40 | apt: 41 | name: "{{ DOCKER_TOOLS }}" 42 | state: latest 43 | update_cache: yes 44 | 45 | - name: Test Docker with hello world example 46 | shell: "docker run hello-world" 47 | register: hello_world_output 48 | 49 | - name: Show output of hello word example 50 | debug: 51 | msg: "Container Output: {{ hello_world_output.stdout }}" 52 | 53 | - name: Create docker group 54 | group: 55 | name: "docker" 56 | state: present 57 | 58 | - name: Adding user {{ USER }} to docker group 59 | user: 60 | name: "{{ USER }}" 61 | groups: "docker" 62 | append: "yes" 63 | -------------------------------------------------------------------------------- /deploy_script/go.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Docker 3 | hosts: ec2 4 | become: true 5 | vars_files: 6 | - vars/default.yaml 7 | 8 | tasks: 9 | - name: Remove old go 10 | ansible.builtin.file: 11 | path: /usr/local/go 12 | state: absent 13 | 14 | - name: Extract go1.13.9.linux-amd64.tar.gz into /usr/local/go 15 | ansible.builtin.unarchive: 16 | src: https://golang.org/dl/go1.13.9.linux-amd64.tar.gz 17 | dest: /usr/local 18 | remote_src: yes 19 | 20 | - name: Add PATH init value to bashrc 21 | ansible.builtin.lineinfile: 22 | path: "/home/{{ USER }}/.bashrc" 23 | line: export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin 24 | state: present 25 | insertafter: EOF 26 | 27 | - name: Add go to bashrc 28 | ansible.builtin.lineinfile: 29 | path: "/home/{{ USER }}/.bashrc" 30 | line: export PATH=$PATH:/usr/local/go/bin 31 | state: present 32 | insertafter: EOF 33 | 34 | - name: Set GOPATH 35 | ansible.builtin.lineinfile: 36 | path: "/home/{{ USER }}/.bashrc" 37 | line: "export GOPATH=/home/{{ USER }}/go" 38 | state: present 39 | insertafter: EOF 40 | 41 | - name: Add GOPATH/bin to bashrc 42 | ansible.builtin.lineinfile: 43 | path: "/home/{{ USER }}/.bashrc" 44 | line: export PATH=$PATH:$GOPATH/bin 45 | state: present 46 | insertafter: EOF 47 | 48 | - name: Test installed go version 49 | shell: "/usr/local/go/bin/go version" 50 | register: go_version_output 51 | 52 | - name: Show output of go version 53 | debug: 54 | msg: "Go Version Output: {{ go_version_output.stdout }}" 55 | -------------------------------------------------------------------------------- /deploy_script/helm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Helm 3 | hosts: ec2 4 | become: true 5 | vars_files: 6 | - vars/default.yaml 7 | 8 | tasks: 9 | - name: Add helm apt key 10 | apt_key: 11 | url: https://baltocdn.com/helm/signing.asc 12 | state: present 13 | 14 | - name: install apt-transport-https 15 | apt: 16 | name: apt-transport-https 17 | state: present 18 | 19 | - name: Add helm apt repositories 20 | apt_repository: 21 | repo: deb https://baltocdn.com/helm/stable/debian/ all main 22 | state: present 23 | filename: helm-stable-debian 24 | 25 | - name: install helm 26 | apt: 27 | name: helm 28 | state: present 29 | update_cache: yes -------------------------------------------------------------------------------- /deploy_script/kind.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Kind 3 | hosts: ec2 4 | vars_files: 5 | - vars/default.yaml 6 | 7 | tasks: 8 | - name: install kind 9 | shell: "/usr/local/go/bin/go get sigs.k8s.io/kind@v0.11.1" 10 | environment: 11 | GO111MODULE: "on" 12 | 13 | - name: Test kind 14 | shell: "/home/{{ USER }}/go/bin/kind version" 15 | register: kind_version_output 16 | 17 | - name: Show output of kind version 18 | debug: 19 | msg: "Kind Output: {{ kind_version_output.stdout }}" 20 | 21 | - name: Add KUBECONFIG to bashrc 22 | ansible.builtin.lineinfile: 23 | path: "/home/{{ USER }}/.bashrc" 24 | line: export KUBECONFIG=$HOME/.kube/kind-test-config 25 | state: present 26 | insertafter: EOF 27 | -------------------------------------------------------------------------------- /deploy_script/kubectl.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install kubectl 3 | hosts: ec2 4 | become: true 5 | vars_files: 6 | - vars/default.yaml 7 | 8 | tasks: 9 | - name: download kubectl 10 | shell: curl -LO https://dl.k8s.io/release/v1.22.1/bin/linux/amd64/kubectl 11 | 12 | - name: install kubectl 13 | shell: install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl -------------------------------------------------------------------------------- /deploy_script/python.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Docker 3 | hosts: ec2 4 | become: true 5 | vars_files: 6 | - vars/default.yaml 7 | 8 | tasks: 9 | - name: Install pip3 10 | apt: 11 | name: python3-pip 12 | state: present 13 | update_cache: yes 14 | 15 | - name: Install python packages using pip 16 | pip: 17 | name: "{{ PYTHON_PACKAGES }}" 18 | state: present 19 | -------------------------------------------------------------------------------- /deploy_script/vars/default.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | USER: "ubuntu" 3 | DOCKER_DEPS: 4 | - apt-transport-https 5 | - ca-certificates 6 | - curl 7 | - gnupg 8 | - lsb-release 9 | DOCKER_TOOLS: 10 | - docker-ce 11 | - docker-ce-cli 12 | - containerd.io 13 | PYTHON_PACKAGES: 14 | - kubernetes 15 | - docker 16 | - pyyaml 17 | - py-cui 18 | - deepdiff 19 | -------------------------------------------------------------------------------- /docs/paper-hotos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/docs/paper-hotos.pdf -------------------------------------------------------------------------------- /docs/paper-osdi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/docs/paper-osdi.pdf -------------------------------------------------------------------------------- /docs/poster.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/docs/poster.pdf -------------------------------------------------------------------------------- /docs/sieve-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/docs/sieve-arch.png -------------------------------------------------------------------------------- /docs/stale-state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/docs/stale-state.png -------------------------------------------------------------------------------- /examples/cass-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ########## 2 | # NOTE: When building this image, there is an assumption that you are in the top level directory of the repository. 3 | # $ docker build . -f operator/Dockerfile -t operator 4 | ########## 5 | 6 | # "builder" compiles and tests the code 7 | # This stage name is important to the Cloud Platform CI/CD infrastructure, and should be preserved 8 | FROM --platform=${BUILDPLATFORM} golang:1.14-stretch as builder 9 | 10 | # Disable cgo - this makes static binaries that will work on an Alpine image 11 | ENV CGO_ENABLED=0 12 | # ENV GOPROXY=https://proxy.golang.org,https://gocenter.io,direct 13 | 14 | # Target os and arch 15 | ARG TARGETARCH 16 | ENV GOOS=linux 17 | ENV GOARCH=${TARGETARCH} 18 | ENV GOPATH=/go 19 | 20 | 21 | WORKDIR /cass-operator 22 | 23 | COPY go.mod go.sum ./ 24 | 25 | # COPY instrumented controller-runtime and client-go 26 | COPY . ./ 27 | 28 | # Download go deps (including mage) 29 | RUN go mod download 30 | 31 | # At this point, we have the top level go.mod, the ./mage level go.mod, 32 | # and the ./operator level go.mod without copying any of the source code yet. 33 | # This means that the dependencies should be nicely without having 34 | # to rerun every time we modify our lib code 35 | 36 | # Install mage 37 | # The new go module system will put the version number in the path, so we 38 | # need to wildcard here to work with whatever version we are pinned to 39 | RUN cd $GOPATH/pkg/mod/github.com/magefile/mage* && go run bootstrap.go 40 | 41 | # Copy in source code 42 | COPY magefile.go ./ 43 | COPY mage ./mage 44 | COPY operator ./operator 45 | 46 | ARG VERSION_STAMP=DEV 47 | 48 | # Build any code not touched by tests (the generated client) 49 | RUN MO_VERSION=${VERSION_STAMP} mage operator:buildGo 50 | 51 | # Second stage 52 | # Produce a smaller image than the one used to build the code 53 | FROM alpine:3.11.2 as cass-operator 54 | ENV GOPATH=. 55 | 56 | RUN mkdir -p /var/lib/cass-operator/ 57 | RUN touch /var/lib/cass-operator/base_os 58 | # WORKDIR /go 59 | 60 | # All we need from the builder image is operator executable 61 | ARG TARGETARCH 62 | COPY --from=builder /cass-operator/build/bin/cass-operator-linux-${TARGETARCH} /bin/operator 63 | 64 | CMD [ "/bin/operator" ] 65 | -------------------------------------------------------------------------------- /examples/cass-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | go mod tidy 5 | mage operator:clean 6 | mage operator:buildDocker 7 | -------------------------------------------------------------------------------- /examples/cass-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cass-operator", 3 | "github_link": "https://github.com/datastax/cass-operator.git", 4 | "commit": "dbd4f7a10533bb2298aed0d40ea20bfd8c133da2", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.17.4", 7 | "dockerfile_path": "operator/docker/base/Dockerfile", 8 | "controller_image_name": "datastax/cass-operator:latest", 9 | "test_command": "python3 examples/cass-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "cassandradatacenter" 12 | ], 13 | "annotated_reconcile_functions": { 14 | "operator/pkg/reconciliation/handler.go": "github.com/datastax/cass-operator/operator/pkg/reconciliation.(*ReconcileCassandraDatacenter).Reconcile" 15 | }, 16 | "controller_pod_label": "cass-operator", 17 | "controller_deployment_file_path": "examples/cass-operator/deploy/controller-manifest.yaml", 18 | "test_setting": { 19 | "scaleup-scaledown": { 20 | "num_workers": 3 21 | } 22 | }, 23 | "state_update_summary_checker_mask": { 24 | "*": [ 25 | "poddisruptionbudget/default/cassandra-datacenter-pdb" 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /examples/cass-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f controller-manifest.yaml 5 | kubectl apply -f storageClass.yaml 6 | -------------------------------------------------------------------------------- /examples/cass-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/cass-operator-lock", 3 | "deployment/default/cass-operator", 4 | "endpointslice/default/cass-operator-metrics-sc8bk", 5 | "pod/default/cass-operator-595d8d4bc7-dd7vv", 6 | "replicaset/default/cass-operator-595d8d4bc7", 7 | "service/default/cass-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/cass-operator/oracle/scaledown-scaleup/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/cass-operator-lock", 3 | "deployment/default/cass-operator", 4 | "endpointslice/default/cass-operator-metrics-v7vsd", 5 | "pod/default/cass-operator-595d8d4bc7-4sq2p", 6 | "replicaset/default/cass-operator-595d8d4bc7", 7 | "service/default/cass-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/cass-operator/test/cdc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cassandra.datastax.com/v1beta1 2 | kind: CassandraDatacenter 3 | metadata: 4 | name: cassandra-datacenter 5 | spec: 6 | clusterName: cluster1 7 | serverType: cassandra 8 | serverVersion: 3.11.7 9 | managementApiAuth: 10 | insecure: {} 11 | size: 1 12 | storageConfig: 13 | cassandraDataVolumeClaimSpec: 14 | storageClassName: server-storage 15 | accessModes: 16 | - ReadWriteOnce 17 | resources: 18 | requests: 19 | storage: 3Gi 20 | config: 21 | cassandra-yaml: 22 | authenticator: org.apache.cassandra.auth.PasswordAuthenticator 23 | authorizer: org.apache.cassandra.auth.CassandraAuthorizer 24 | role_manager: org.apache.cassandra.auth.CassandraRoleManager 25 | jvm-options: 26 | initial_heap_size: 800M 27 | max_heap_size: 800M -------------------------------------------------------------------------------- /examples/cass-operator/test/cdc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cassandra.datastax.com/v1beta1 2 | kind: CassandraDatacenter 3 | metadata: 4 | name: cassandra-datacenter 5 | spec: 6 | clusterName: cluster1 7 | serverType: cassandra 8 | serverVersion: 3.11.7 9 | managementApiAuth: 10 | insecure: {} 11 | size: 2 12 | storageConfig: 13 | cassandraDataVolumeClaimSpec: 14 | storageClassName: server-storage 15 | accessModes: 16 | - ReadWriteOnce 17 | resources: 18 | requests: 19 | storage: 3Gi 20 | config: 21 | cassandra-yaml: 22 | authenticator: org.apache.cassandra.auth.PasswordAuthenticator 23 | authorizer: org.apache.cassandra.auth.CassandraAuthorizer 24 | role_manager: org.apache.cassandra.auth.CassandraRoleManager 25 | jvm-options: 26 | initial_heap_size: 800M 27 | max_heap_size: 800M -------------------------------------------------------------------------------- /examples/cass-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/cass-operator/test/cdc-1.yaml") 14 | .wait_for_pod_status("cluster1-cassandra-datacenter-default-sts-0", RUNNING) 15 | .cmd("kubectl delete CassandraDatacenter cassandra-datacenter") 16 | .wait_for_pod_status( 17 | "cluster1-cassandra-datacenter-default-sts-0", 18 | TERMINATED, 19 | 200, 20 | ) 21 | .wait_for_pvc_status( 22 | "server-data-cluster1-cassandra-datacenter-default-sts-0", 23 | TERMINATED, 24 | 10, 25 | ) 26 | .cmd("kubectl apply -f examples/cass-operator/test/cdc-1.yaml") 27 | .wait_for_pod_status("cluster1-cassandra-datacenter-default-sts-0", RUNNING) 28 | .wait_for_pod_status("create-pvc-*", TERMINATED), 29 | "scaledown-scaleup": new_built_in_workload() 30 | .cmd("kubectl apply -f examples/cass-operator/test/cdc-2.yaml") 31 | .wait_for_pod_status("cluster1-cassandra-datacenter-default-sts-1", RUNNING, 150) 32 | .cmd( 33 | 'kubectl patch CassandraDatacenter cassandra-datacenter --type merge -p=\'{"spec":{"size": 1}}\'' 34 | ) 35 | .wait_for_pod_status("cluster1-cassandra-datacenter-default-sts-1", TERMINATED, 150) 36 | .cmd( 37 | 'kubectl patch CassandraDatacenter cassandra-datacenter --type merge -p=\'{"spec":{"size": 2}}\'' 38 | ) 39 | .wait_for_pod_status("cluster1-cassandra-datacenter-default-sts-1", RUNNING, 150), 40 | } 41 | 42 | test_cases[sys.argv[1]].run(sys.argv[2]) 43 | -------------------------------------------------------------------------------- /examples/cassandra-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG GOLANG_BASE_IMAGE=golang:1.13.8 2 | 3 | FROM ${GOLANG_BASE_IMAGE} AS builder 4 | 5 | ARG version 6 | 7 | # Create a user so that operator can run as non-root 8 | RUN useradd -u 999 cassandra-operator 9 | 10 | WORKDIR /code 11 | 12 | # Copy go.mod and go.sum separately to ensure we re-download dependencies only 13 | # when these files change 14 | COPY go.mod go.sum ./ 15 | 16 | # Fetch Go modules in a separate layer for better caching 17 | # RUN go mod download 18 | 19 | COPY . ./ 20 | 21 | # Build binary 22 | RUN cd cmd/manager \ 23 | && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ 24 | -ldflags "-w -X main.version=${version}" \ 25 | -o /tmp/cassandra-operator 26 | 27 | # Build final image 28 | FROM alpine:3.11.2 29 | 30 | COPY --from=builder /tmp/cassandra-operator . 31 | COPY --from=builder /etc/passwd /etc/passwd 32 | USER 999 33 | RUN mkdir -p /tmp 34 | CMD ["./cassandra-operator"] 35 | -------------------------------------------------------------------------------- /examples/cassandra-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | cd docker/cassandra-operator 5 | make 6 | -------------------------------------------------------------------------------- /examples/cassandra-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cassandra-operator", 3 | "github_link": "https://github.com/instaclustr/cassandra-operator.git", 4 | "commit": "fe8f91da3cd8aab47f21f7a3aad4abc5d4b6a0dd", 5 | "cherry_pick_commits": [ 6 | "bd8077a478997f63862848d66d4912c59e4c46ff" 7 | ], 8 | "kubernetes_version": "v1.18.9", 9 | "client_go_version": "v0.0.0-20190918160344-1fbdaa4c8d90", 10 | "dockerfile_path": "docker/cassandra-operator/Dockerfile", 11 | "controller_image_name": "cassandra-operator:latest", 12 | "test_command": "python3 examples/cassandra-operator/test/test.py", 13 | "custom_resource_definitions": [ 14 | "cassandradatacenter", 15 | "cassandracluster", 16 | "cassandrabackup" 17 | ], 18 | "annotated_reconcile_functions": { 19 | "pkg/controller/cassandradatacenter/cassandradatacenter_controller.go": "github.com/instaclustr/cassandra-operator/pkg/controller/cassandradatacenter.(*ReconcileCassandraDataCenter).Reconcile" 20 | }, 21 | "controller_pod_label": "cassandra-operator", 22 | "controller_deployment_file_path": "examples/cassandra-operator/deploy/bundle.yaml", 23 | "end_state_checker_mask": { 24 | "*": { 25 | "configmap/default/cassandra-test-cluster-dc1-rack-config-rack1": [ 26 | [ 27 | "data", 28 | "cassandra_rackdc_properties" 29 | ] 30 | ] 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /examples/cassandra-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f crds.yaml 5 | kubectl apply -f bundle.yaml 6 | -------------------------------------------------------------------------------- /examples/cassandra-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/myoperator-lock", 3 | "deployment/default/cassandra-operator", 4 | "endpointslice/default/cassandra-operator-metrics-dgnhk", 5 | "pod/default/cassandra-operator-55bf946bb6-sw6qn", 6 | "replicaset/default/cassandra-operator-55bf946bb6", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/cassandra-operator/oracle/scaledown-scaleup-brittle/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/myoperator-lock", 3 | "deployment/default/cassandra-operator", 4 | "endpointslice/default/cassandra-operator-metrics-x7nt6", 5 | "pod/default/cassandra-operator-55bf946bb6-jkxbx", 6 | "replicaset/default/cassandra-operator-55bf946bb6", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/cassandra-operator/oracle/scaledown-scaleup/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/myoperator-lock", 3 | "deployment/default/cassandra-operator", 4 | "endpointslice/default/cassandra-operator-metrics-x7nt6", 5 | "pod/default/cassandra-operator-55bf946bb6-jkxbx", 6 | "replicaset/default/cassandra-operator-55bf946bb6", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/cassandra-operator/test/cdc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cassandraoperator.instaclustr.com/v1alpha1 2 | kind: CassandraDataCenter 3 | metadata: 4 | name: cassandra-datacenter 5 | labels: 6 | app: cassandra 7 | datacenter: dc1 8 | cluster: test-cluster 9 | spec: 10 | prometheusSupport: false 11 | optimizeKernelParams: true 12 | serviceAccountName: cassandra-performance 13 | deletePVCs: true 14 | nodes: 1 15 | cassandraImage: "gcr.io/cassandra-operator/cassandra-3.11.9:latest" 16 | sidecarImage: "gcr.io/cassandra-operator/instaclustr-icarus:latest" 17 | imagePullPolicy: Always 18 | imagePullSecrets: 19 | - name: regcred 20 | resources: 21 | limits: 22 | memory: 1Gi 23 | requests: 24 | memory: 1Gi 25 | sidecarResources: 26 | limits: 27 | memory: 512Mi 28 | requests: 29 | memory: 512Mi 30 | dataVolumeClaimSpec: 31 | accessModes: 32 | - ReadWriteOnce 33 | resources: 34 | requests: 35 | storage: 2Gi 36 | cassandraAuth: 37 | authenticator: PasswordAuthenticator 38 | authorizer: CassandraAuthorizer 39 | roleManager: CassandraRoleManager 40 | fsGroup: 999 41 | -------------------------------------------------------------------------------- /examples/cassandra-operator/test/cdc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cassandraoperator.instaclustr.com/v1alpha1 2 | kind: CassandraDataCenter 3 | metadata: 4 | name: cassandra-datacenter 5 | labels: 6 | app: cassandra 7 | datacenter: dc1 8 | cluster: test-cluster 9 | spec: 10 | prometheusSupport: false 11 | optimizeKernelParams: true 12 | serviceAccountName: cassandra-performance 13 | deletePVCs: true 14 | nodes: 2 15 | cassandraImage: "gcr.io/cassandra-operator/cassandra-3.11.9:latest" 16 | sidecarImage: "gcr.io/cassandra-operator/instaclustr-icarus:latest" 17 | imagePullPolicy: Always 18 | imagePullSecrets: 19 | - name: regcred 20 | resources: 21 | limits: 22 | memory: 1Gi 23 | requests: 24 | memory: 1Gi 25 | sidecarResources: 26 | limits: 27 | memory: 512Mi 28 | requests: 29 | memory: 512Mi 30 | dataVolumeClaimSpec: 31 | accessModes: 32 | - ReadWriteOnce 33 | resources: 34 | requests: 35 | storage: 2Gi 36 | cassandraAuth: 37 | authenticator: PasswordAuthenticator 38 | authorizer: CassandraAuthorizer 39 | roleManager: CassandraRoleManager 40 | fsGroup: 999 41 | -------------------------------------------------------------------------------- /examples/cassandra-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/cassandra-operator/test/cdc-1.yaml") 14 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-0", RUNNING) 15 | .cmd("kubectl delete CassandraDataCenter cassandra-datacenter") 16 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-0", TERMINATED, 10) 17 | .cmd("kubectl apply -f examples/cassandra-operator/test/cdc-1.yaml") 18 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-0", RUNNING), 19 | "scaledown-scaleup": new_built_in_workload() 20 | .cmd("kubectl apply -f examples/cassandra-operator/test/cdc-2.yaml") 21 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-1", RUNNING, 200) 22 | .cmd( 23 | 'kubectl patch CassandraDataCenter cassandra-datacenter --type merge -p=\'{"spec":{"nodes":1}}\'' 24 | ) 25 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-1", TERMINATED, 150) 26 | .wait_for_pvc_status( 27 | "data-volume-cassandra-test-cluster-dc1-rack1-1", 28 | TERMINATED, 29 | 20, 30 | ) 31 | .cmd( 32 | 'kubectl patch CassandraDataCenter cassandra-datacenter --type merge -p=\'{"spec":{"nodes":2}}\'' 33 | ) 34 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-1", RUNNING, 150), 35 | "scaledown-scaleup-brittle": new_built_in_workload() 36 | .cmd("kubectl apply -f examples/cassandra-operator/test/cdc-2.yaml") 37 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-1", RUNNING, 200) 38 | .cmd( 39 | 'kubectl patch CassandraDataCenter cassandra-datacenter --type merge -p=\'{"spec":{"nodes":1}}\'' 40 | ) 41 | .wait(50) 42 | .cmd( 43 | 'kubectl patch CassandraDataCenter cassandra-datacenter --type merge -p=\'{"spec":{"nodes":2}}\'' 44 | ) 45 | .wait_for_pod_status("cassandra-test-cluster-dc1-rack1-1", RUNNING, 150), 46 | } 47 | 48 | test_cases[sys.argv[1]].run(sys.argv[2]) 49 | -------------------------------------------------------------------------------- /examples/casskop-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copy the controller-manager into a thin image 2 | FROM alpine:latest 3 | 4 | LABEL org.opencontainers.image.documentation="https://github.com/Orange-OpenSource/casskop/blob/master/README.md" 5 | LABEL org.opencontainers.image.authors="Sébastien Allamand " 6 | LABEL org.opencontainers.image.source="https://github.com/Orange-OpenSource/casskop" 7 | LABEL org.opencontainers.image.vendor="Orange France - Digital Factory" 8 | LABEL org.opencontainers.image.version="0.1" 9 | LABEL org.opencontainers.image.description="Operateur des Gestion de Clusters Cassandra" 10 | LABEL org.opencontainers.image.url="https://github.com/Orange-OpenSource/casskop" 11 | LABEL org.opencontainers.image.title="Operateur Cassandra" 12 | 13 | LABEL org.label-schema.usage="https://github.com/Orange-OpenSource/casskop/blob/master/README.md" 14 | LABEL org.label-schema.docker.cmd="/usr/local/bin/casskop" 15 | LABEL org.label-schema.docker.cmd.devel="N/A" 16 | LABEL org.label-schema.docker.cmd.test="N/A" 17 | LABEL org.label-schema.docker.cmd.help="N/A" 18 | LABEL org.label-schema.docker.cmd.debug="N/A" 19 | LABEL org.label-schema.docker.params="LOG_LEVEL=define loglevel,RESYNC_PERIOD=period in second to execute resynchronisation,WATCH_NAMESPACE=namespace to watch for cassandraclusters,OPERATOR_NAME=name of the operator instance pod" 20 | 21 | 22 | RUN apk update 23 | RUN apk upgrade 24 | RUN apk add bash 25 | 26 | # install operator binary 27 | COPY build/_output/bin/casskop /usr/local/bin/ 28 | 29 | CMD ["/usr/local/bin/casskop"] 30 | -------------------------------------------------------------------------------- /examples/casskop-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | BUILD_IMAGE=ghcr.io/sieve-project/sieve/casskop-build:v0.18.0-forked-pr317 5 | WORKDIR=/go/casskop 6 | 7 | echo "Generate zzz-deepcopy objects" 8 | docker run --rm -v $(pwd):$WORKDIR \ 9 | --env GO111MODULE=on \ 10 | \ 11 | $BUILD_IMAGE /bin/bash -c 'operator-sdk generate k8s' 12 | 13 | echo "Generate crds" 14 | docker run --rm -v $(pwd):$WORKDIR \ 15 | --env GO111MODULE=on \ 16 | \ 17 | $BUILD_IMAGE /bin/bash -c 'operator-sdk generate crds' 18 | sed -i '/\- protocol/d' deploy/crds/db.orange.com_cassandraclusters_crd.yaml 19 | cp -v deploy/crds/* helm/*/crds/ 20 | cp -v deploy/crds/* */helm/*/crds/ 21 | 22 | 23 | echo "Build Cassandra Operator. Using cache from "$(go env GOCACHE) 24 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):$WORKDIR \ 25 | \ 26 | --env GO111MODULE=on \ 27 | $BUILD_IMAGE /bin/bash -c "operator-sdk build orangeopensource/casskop-operator:latest \ 28 | && chmod -R 777 build/_output/" 29 | -------------------------------------------------------------------------------- /examples/casskop-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "casskop-operator", 3 | "github_link": "https://github.com/Orange-OpenSource/casskop.git", 4 | "commit": "f87c8e05c1a2896732fc5f3a174f1eb99e936907", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.18.2", 7 | "dockerfile_path": "build/Dockerfile", 8 | "controller_image_name": "orangeopensource/casskop-operator:latest", 9 | "test_command": "python3 examples/casskop-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "cassandracluster", 12 | "cassandrarestore", 13 | "cassandrabackup" 14 | ], 15 | "annotated_reconcile_functions": { 16 | "pkg/controller/cassandracluster/cassandracluster_controller.go": "github.com/Orange-OpenSource/casskop/pkg/controller/cassandracluster.(*ReconcileCassandraCluster).Reconcile" 17 | }, 18 | "controller_pod_label": "casskop-operator", 19 | "controller_deployment_file_path": "examples/casskop-operator/deploy/values.yaml" 20 | } -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for CassKop - the Orange Cassandra Kubernetes operator 3 | name: cassandra-operator 4 | home: https://github.com/Orange-OpenSource/casskop 5 | sources: 6 | - https://github.com/Orange-OpenSource/casskop 7 | version: 1.1.3 8 | appVersion: 1.1.3-release 9 | maintainers: 10 | - name: allamand 11 | email: sebastien.allamand@orange.com 12 | - name: cscetbon 13 | email: cscetbon@gmail.com 14 | - name: jal06 15 | email: jeanarmel.luce@orange.com 16 | - name: erdrix 17 | email: aguitton.ext@orange.com 18 | - name: fdehay 19 | email: franck.dehay@orange.com 20 | - name: PERES-Richard 21 | email: richardperes.info@gmail.com 22 | keywords: 23 | - operator 24 | - cassandra 25 | - casskop 26 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | helm install -f values.yaml casskop-operator . 5 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/templates/_functions.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "cassandra-operator.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "cassandra-operator.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Return the appropriate apiVersion value to use for the capi-operator managed k8s resources 29 | */}} 30 | {{- define "cassandra-operator.apiVersion" -}} 31 | {{- printf "%s" "cassandraclusters.db.orange.com/v1alpha1" -}} 32 | {{- end -}} 33 | 34 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbacEnable }} 2 | kind: RoleBinding 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | labels: 6 | app: {{ template "cassandra-operator.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "cassandra-operator.name" . }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ template "cassandra-operator.name" . }} 14 | roleRef: 15 | kind: Role 16 | name: {{ template "cassandra-operator.name" . }} 17 | apiGroup: rbac.authorization.k8s.io 18 | {{- range .Values.clusterServiceAccountsName }} 19 | --- 20 | kind: RoleBinding 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | metadata: 23 | labels: 24 | app: {{ template "cassandra-operator.name" $ }} 25 | chart: {{ $.Chart.Name }}-{{ $.Chart.Version }} 26 | heritage: {{ $.Release.Service }} 27 | release: {{ $.Release.Name }} 28 | name: {{ . }}-cluster-node 29 | subjects: 30 | - kind: ServiceAccount 31 | name: {{ . }} 32 | roleRef: 33 | kind: Role 34 | name: {{ template "cassandra-operator.name" $ }}-cluster-node 35 | apiGroup: rbac.authorization.k8s.io 36 | {{- end }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.metricService }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "cassandra-operator.name" . }}-metrics 6 | labels: 7 | component: app 8 | app: {{ template "cassandra-operator.name" . }}-metrics 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | spec: 13 | selector: 14 | app: {{ template "cassandra-operator.name" . }} 15 | ports: 16 | - name: metrics 17 | port: 8383 18 | protocol: TCP 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/templates/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: {{ template "cassandra-operator.name" . }} 6 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 7 | heritage: {{ .Release.Service }} 8 | release: {{ .Release.Name }} 9 | name: {{ template "cassandra-operator.name" . }} 10 | {{- range .Values.clusterServiceAccountsName }} 11 | --- 12 | apiVersion: v1 13 | kind: ServiceAccount 14 | metadata: 15 | labels: 16 | app: {{ template "cassandra-operator.name" $ }} 17 | chart: {{ $.Chart.Name }}-{{ $.Chart.Version }} 18 | heritage: {{ $.Release.Service }} 19 | release: {{ $.Release.Name }} 20 | name: {{ . }} 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /examples/casskop-operator/deploy/values.yaml: -------------------------------------------------------------------------------- 1 | ## Cassandra Operator Image 2 | ## 3 | image: 4 | repository: ${SIEVE-DR}/casskop-operator 5 | tag: ${SIEVE-DT} 6 | pullPolicy: IfNotPresent 7 | imagePullSecrets: 8 | enabled: false 9 | # name: 10 | 11 | ## Prometheus-operator resource limits & requests 12 | ## Ref: https://kubernetes.io/docs/user-guide/compute-resources/ 13 | resources: 14 | requests: 15 | cpu: 10m 16 | memory: 50Mi 17 | limits: 18 | cpu: 1 19 | memory: 512Mi 20 | 21 | ## If true, create & deploy the CRD 22 | ## 23 | createCustomResource: true 24 | 25 | ## If true, create & use RBAC resources 26 | ## 27 | rbacEnable: true 28 | 29 | ## if true deploy service for metrics access 30 | metricService: false 31 | 32 | debug: 33 | enabled: false 34 | 35 | ## 36 | clusterServiceAccountsName: 37 | - cassandra-cluster-node 38 | -------------------------------------------------------------------------------- /examples/casskop-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/casskop-lock", 3 | "deployment/default/casskop-operator", 4 | "endpointslice/default/cassandra-operator-metrics-tx6r2", 5 | "pod/default/casskop-operator-546674cfdd-6ws9b", 6 | "replicaset/default/casskop-operator-546674cfdd", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/casskop-operator/oracle/reducepdb/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/casskop-lock", 3 | "deployment/default/casskop-operator", 4 | "endpointslice/default/cassandra-operator-metrics-msv9h", 5 | "pod/default/casskop-operator-546674cfdd-lzknf", 6 | "replicaset/default/casskop-operator-546674cfdd", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/casskop-operator/oracle/scaledown-to-zero/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/casskop-lock", 3 | "deployment/default/casskop-operator", 4 | "endpointslice/default/cassandra-operator-metrics-7h7xg", 5 | "pod/default/casskop-operator-546674cfdd-cdtcs", 6 | "replicaset/default/casskop-operator-546674cfdd", 7 | "service/default/cassandra-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/casskop-operator/test/cassandra-configmap-v1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: cassandra-configmap-v1 5 | data: 6 | 7 | pre_run.sh: |- 8 | echo " ** this is pre_run.sh script executed before run.sh **" 9 | #Examples: 10 | echo "Change default Authenticator & Authorizer" 11 | sed -ri 's/(authenticator:).*/\1 PasswordAuthenticator/' /etc/cassandra/cassandra.yaml 12 | sed -ri 's/(authorizer:).*/\1 CassandraAuthorizer/' /etc/cassandra/cassandra.yaml 13 | #test "$(hostname)" == 'cassandra-demo-dc1-rack2-0' && echo "update param" && sed -i 's/windows_timer_interval: 1/windows_timer_interval: 2/' /etc/cassandra/cassandra.yaml 14 | #test "$(hostname)" == 'cassandra-demo-dc1-rack3-0' && echo "-Dcassandra.replace_address_first_boot=172.31.183.209" > /etc/cassandra/jvm.options 15 | #test "$(hostname)" == 'cassandra-demo-dc2-rack1-0' && echo "-Dcassandra.override_decommission=true" > /etc/cassandra/jvm.options 16 | echo " ** end of pre_run.sh script, continue with run.sh **" 17 | 18 | post_run.sh: |- 19 | echo "Check Configured seeds by bootstrap" 20 | grep "seeds:" /etc/cassandra/cassandra.yaml 21 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/cc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | # - name: rack2 35 | # - name: rack3 36 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/cc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 4 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | # - name: rack2 35 | # - name: rack3 36 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/dc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/dc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | - name: dc2 35 | nodesPerRacks: 1 36 | rack: 37 | - name: rack1 38 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/dc-3.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | - name: dc2 35 | nodesPerRacks: 1 36 | rack: 37 | - name: rack1 38 | - name: dc3 39 | nodesPerRacks: 1 40 | rack: 41 | - name: rack1 42 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/nodes-0.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 0 32 | rack: 33 | - name: rack1 34 | # - name: rack2 35 | # - name: rack3 36 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/nodes-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 1 32 | rack: 33 | - name: rack1 34 | # - name: rack2 35 | # - name: rack3 36 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/nodes-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "db.orange.com/v1alpha1" 2 | kind: "CassandraCluster" 3 | metadata: 4 | name: cassandra-cluster 5 | labels: 6 | cluster: k8s.kaas 7 | spec: 8 | cassandraImage: cassandra:3.11 9 | bootstrapImage: orangeopensource/cassandra-bootstrap:0.1.8 10 | configMapName: cassandra-configmap-v1 11 | dataCapacity: "200Mi" 12 | # dataStorageClass: standard 13 | imagepullpolicy: IfNotPresent 14 | hardAntiAffinity: false # Do we ensure only 1 cassandra on each node ? 15 | deletePVC: true 16 | autoPilot: false 17 | gcStdout: true 18 | autoUpdateSeedList: false 19 | maxPodUnavailable: 1 20 | runAsUser: 999 21 | resources: 22 | requests: 23 | cpu: '1' 24 | memory: 2Gi 25 | limits: 26 | cpu: '1' 27 | memory: 2Gi 28 | topology: 29 | dc: 30 | - name: dc1 31 | nodesPerRacks: 2 32 | rack: 33 | - name: rack1 34 | # - name: rack2 35 | # - name: rack3 36 | -------------------------------------------------------------------------------- /examples/casskop-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/casskop-operator/test/cassandra-configmap-v1.yaml") 14 | .cmd("kubectl apply -f examples/casskop-operator/test/cc-1.yaml") 15 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-0", RUNNING) 16 | .cmd("kubectl delete CassandraCluster cassandra-cluster") 17 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-0", TERMINATED, timeout=20) 18 | .cmd("kubectl apply -f examples/casskop-operator/test/cc-1.yaml") 19 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-0", RUNNING), 20 | "reducepdb": new_built_in_workload(110) 21 | .cmd("kubectl apply -f examples/casskop-operator/test/cassandra-configmap-v1.yaml") 22 | .cmd("kubectl apply -f examples/casskop-operator/test/cc-2.yaml") 23 | .wait(60) 24 | .cmd("kubectl apply -f examples/casskop-operator/test/cc-1.yaml"), 25 | "scaledown-to-zero": new_built_in_workload() 26 | .cmd("kubectl apply -f examples/casskop-operator/test/cassandra-configmap-v1.yaml") 27 | .cmd("kubectl apply -f examples/casskop-operator/test/nodes-2.yaml") 28 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-0", RUNNING) 29 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-1", RUNNING) 30 | .cmd("kubectl apply -f examples/casskop-operator/test/nodes-1.yaml") 31 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-0", RUNNING) 32 | .wait_for_pod_status("cassandra-cluster-dc1-rack1-1", TERMINATED) 33 | .cmd("kubectl apply -f examples/casskop-operator/test/nodes-0.yaml"), 34 | } 35 | 36 | test_cases[sys.argv[1]].run(sys.argv[2]) 37 | -------------------------------------------------------------------------------- /examples/elastic-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the operator binary 2 | FROM --platform=$TARGETPLATFORM golang:1.17.5 as builder 3 | 4 | ARG TARGETPLATFORM 5 | ARG BUILDPLATFORM 6 | ARG GO_LDFLAGS 7 | ARG GO_TAGS 8 | WORKDIR /go/src/github.com/elastic/cloud-on-k8s 9 | 10 | # cache deps before building and copying source so that we don't need to re-download as much 11 | # and so that source changes don't invalidate our downloaded layer 12 | COPY ["go.mod", "go.sum", "./"] 13 | # RUN go mod download 14 | 15 | # Copy the go source 16 | COPY pkg/ pkg/ 17 | COPY cmd/ cmd/ 18 | COPY sieve-dependency/ sieve-dependency/ 19 | 20 | # Build 21 | RUN CGO_ENABLED=0 GOOS=linux \ 22 | go build \ 23 | -mod readonly \ 24 | -ldflags "$GO_LDFLAGS" -tags="$GO_TAGS" -a \ 25 | -o elastic-operator github.com/elastic/cloud-on-k8s/cmd 26 | 27 | # Copy the operator binary into a lighter image 28 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5 29 | 30 | ARG VERSION 31 | 32 | # Add required ECK labels and override labels from base image 33 | LABEL name="Elastic Cloud on Kubernetes" \ 34 | io.k8s.display-name="Elastic Cloud on Kubernetes" \ 35 | maintainer="eck@elastic.co" \ 36 | vendor="Elastic" \ 37 | version="$VERSION" \ 38 | url="https://www.elastic.co/guide/en/cloud-on-k8s/" \ 39 | summary="Run Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes and OpenShift" \ 40 | description="Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Beats, and Enterprise Search on Kubernetes" \ 41 | io.k8s.description="Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Beats, and Enterprise Search on Kubernetes" 42 | 43 | # Update the base image packages to the latest versions 44 | RUN microdnf update --setopt=tsflags=nodocs && microdnf clean all 45 | 46 | COPY --from=builder /go/src/github.com/elastic/cloud-on-k8s/elastic-operator . 47 | # COPY config/eck.yaml /conf/eck.yaml 48 | 49 | # Copy NOTICE.txt and LICENSE.txt into the image 50 | COPY *.txt /licenses/ 51 | 52 | USER 1001 53 | 54 | ENTRYPOINT ["./elastic-operator"] 55 | CMD ["manager"] 56 | -------------------------------------------------------------------------------- /examples/elastic-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | sed -i 's/go-generate generate-config-file /go-generate/g' Makefile 5 | OPERATOR_IMAGE=elastic/elastic-operator:latest make docker-build 6 | -------------------------------------------------------------------------------- /examples/elastic-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elastic-operator", 3 | "github_link": "https://github.com/elastic/cloud-on-k8s.git", 4 | "commit": "660bc92fbfca469af552a833d8f6a4834c629649", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.23.0", 7 | "dockerfile_path": "Dockerfile", 8 | "controller_image_name": "elastic/elastic-operator:latest", 9 | "test_command": "python3 examples/elastic-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "elasticsearch" 12 | ], 13 | "annotated_reconcile_functions": { 14 | "pkg/controller/elasticsearch/elasticsearch_controller.go": "github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch.(*ReconcileElasticsearch).Reconcile" 15 | }, 16 | "controller_pod_label": "elastic-operator", 17 | "controller_deployment_file_path": "examples/elastic-operator/deploy/operator.yaml" 18 | } -------------------------------------------------------------------------------- /examples/elastic-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl create -f crds.yaml 5 | kubectl create -f operator.yaml 6 | -------------------------------------------------------------------------------- /examples/elastic-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "controllerrevision/default/elastic-operator-854df5f78b", 3 | "pod/default/elastic-operator-0", 4 | "statefulset/default/elastic-operator" 5 | ] -------------------------------------------------------------------------------- /examples/elastic-operator/oracle/scaledown-scaleup/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "controllerrevision/default/elastic-operator-854df5f78b", 3 | "pod/default/elastic-operator-0", 4 | "statefulset/default/elastic-operator" 5 | ] -------------------------------------------------------------------------------- /examples/elastic-operator/test/es-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: elasticsearch.k8s.elastic.co/v1 2 | kind: Elasticsearch 3 | metadata: 4 | name: elasticsearch-cluster 5 | spec: 6 | version: 7.16.2 7 | nodeSets: 8 | - name: default 9 | count: 1 10 | config: 11 | node.store.allow_mmap: false 12 | -------------------------------------------------------------------------------- /examples/elastic-operator/test/es-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: elasticsearch.k8s.elastic.co/v1 2 | kind: Elasticsearch 3 | metadata: 4 | name: elasticsearch-cluster 5 | spec: 6 | version: 7.16.2 7 | nodeSets: 8 | - name: default 9 | count: 2 10 | config: 11 | node.store.allow_mmap: false 12 | -------------------------------------------------------------------------------- /examples/elastic-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload(100) 13 | .cmd("kubectl apply -f examples/elastic-operator/test/es-1.yaml") 14 | .wait_for_pod_status("elasticsearch-cluster-es-default-0", RUNNING) 15 | .wait_for_secret_existence("elasticsearch-cluster-es-elastic-user", True) 16 | .cmd("kubectl delete elasticsearch elasticsearch-cluster") 17 | .wait_for_pod_status("elasticsearch-cluster-es-default-0", TERMINATED) 18 | .wait_for_secret_existence("elasticsearch-cluster-es-elastic-user", False) 19 | .cmd("kubectl apply -f examples/elastic-operator/test/es-1.yaml") 20 | .wait_for_pod_status("elasticsearch-cluster-es-default-0", RUNNING) 21 | .wait_for_secret_existence("elasticsearch-cluster-es-elastic-user", True), 22 | "scaledown-scaleup": new_built_in_workload(100) 23 | .cmd("kubectl apply -f examples/elastic-operator/test/es-2.yaml") 24 | .wait_for_pod_status("elasticsearch-cluster-es-default-1", RUNNING) 25 | .wait_for_secret_existence("elasticsearch-cluster-es-elastic-user", True) 26 | .cmd( 27 | 'kubectl patch elasticsearch elasticsearch-cluster --type=\'json\' -p=\'[{"op": "replace", "path": "/spec/nodeSets/0/count", "value": 1}]\'' 28 | ) 29 | .wait_for_pod_status("elasticsearch-cluster-es-default-1", TERMINATED) 30 | .wait_for_pvc_status( 31 | "elasticsearch-data-elasticsearch-cluster-es-default-1", TERMINATED 32 | ) 33 | .cmd( 34 | 'kubectl patch elasticsearch elasticsearch-cluster --type=\'json\' -p=\'[{"op": "replace", "path": "/spec/nodeSets/0/count", "value": 2}]\'' 35 | ) 36 | .wait_for_pod_status("elasticsearch-cluster-es-default-1", RUNNING), 37 | } 38 | 39 | test_cases[sys.argv[1]].run(sys.argv[2]) 40 | -------------------------------------------------------------------------------- /examples/kapp-controller/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM golang:1.19.5 AS deps 2 | 3 | ARG TARGETOS TARGETARCH KCTRL_VER=development 4 | WORKDIR /workspace 5 | 6 | # dependencies 7 | COPY ./hack/dependencies.* ./hack/ 8 | COPY go.* ./ 9 | COPY vendor vendor 10 | RUN mkdir out 11 | RUN go run ./hack/dependencies.go install -d out --arch ${TARGETARCH} --os ${TARGETOS} 12 | 13 | # kapp-controller 14 | COPY . . 15 | # helpful ldflags reference: https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications 16 | RUN --mount=type=cache,target=/root/.cache/go-build \ 17 | CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ 18 | go build -mod=vendor -ldflags="-X 'main.Version=$KCTRL_VER'" -trimpath -o out/kapp-controller ./cmd/controller 19 | 20 | # --- run image --- 21 | FROM photon:4.0 22 | 23 | # Install openssh for git 24 | RUN tdnf install -y git openssh-clients 25 | 26 | # Create the kapp-controller user in the root group, the home directory will be mounted as a volume 27 | RUN echo "kapp-controller:x:1000:0:/home/kapp-controller:/usr/sbin/nologin" > /etc/passwd 28 | # Give the root group write access to the openssh's root bundle directory 29 | # so we can rename the certs file with our dynamic config, and append custom roots at runtime 30 | RUN chmod g+w /etc/pki/tls/certs 31 | # Copy the ca-bundle so we have an original 32 | RUN cp /etc/pki/tls/certs/ca-bundle.crt /etc/pki/tls/certs/ca-bundle.crt.orig 33 | 34 | COPY --from=deps /workspace/out/* ./ 35 | 36 | # Run as kapp-controller by default, will be overridden to a random uid on OpenShift 37 | USER 1000 38 | ENV PATH="/:${PATH}" 39 | ENTRYPOINT ["/kapp-controller"] 40 | -------------------------------------------------------------------------------- /examples/kapp-controller/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "# sieve.client v0.0.0 4 | ## explicit; go 1.19 5 | sieve.client" >> vendor/modules.txt 6 | 7 | ytt -f config/ | kbld -f- 8 | old_tag=$(docker images | grep kbld | awk '{print $2}') 9 | echo $old_tag 10 | docker tag kbld:$old_tag kapp-controller:latest 11 | docker rmi kbld:$old_tag 12 | -------------------------------------------------------------------------------- /examples/kapp-controller/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kapp-controller", 3 | "github_link": "git@github.com:carvel-dev/kapp-controller.git", 4 | "commit": "8d8de5c2fb080a23db604e1c4f4c0f29a4b13ca0", 5 | "kubernetes_version": "v1.24.10", 6 | "client_go_version": "v0.25.6", 7 | "go_mod": "vendor", 8 | "vendored_client_go_path": "vendor/k8s.io/client-go", 9 | "vendored_sieve_client_path": "vendor/sieve.client", 10 | "dockerfile_path": "Dockerfile", 11 | "controller_image_name": "kapp-controller:latest", 12 | "test_command": "python3 examples/kapp-controller/test/test.py", 13 | "custom_resource_definitions": [ 14 | "internalpackagemetadata", 15 | "internalpackage", 16 | "app", 17 | "packageinstall", 18 | "packagerepository" 19 | ], 20 | "annotated_reconcile_functions": { 21 | "pkg/app/reconciler.go": "github.com/vmware-tanzu/carvel-kapp-controller/pkg/app.(*Reconciler).Reconcile" 22 | }, 23 | "controller_pod_label": "kapp-controller", 24 | "container_name": "kapp-controller", 25 | "controller_deployment_file_path": "examples/kapp-controller/deploy/release.yml" 26 | } -------------------------------------------------------------------------------- /examples/kapp-controller/deploy/default-ns.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: default-ns-sa 5 | namespace: default 6 | --- 7 | kind: Role 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | metadata: 10 | name: default-ns-role 11 | namespace: default 12 | rules: 13 | - apiGroups: ["*"] 14 | resources: ["*"] 15 | verbs: ["*"] 16 | --- 17 | kind: RoleBinding 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | metadata: 20 | name: default-ns-role-binding 21 | namespace: default 22 | subjects: 23 | - kind: ServiceAccount 24 | name: default-ns-sa 25 | namespace: default 26 | roleRef: 27 | apiGroup: rbac.authorization.k8s.io 28 | kind: Role 29 | name: default-ns-role 30 | -------------------------------------------------------------------------------- /examples/kapp-controller/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f release.yml 5 | kubectl apply -f default-ns.yml 6 | -------------------------------------------------------------------------------- /examples/kapp-controller/test/app.yml: -------------------------------------------------------------------------------- 1 | apiVersion: kappctrl.k14s.io/v1alpha1 2 | kind: App 3 | metadata: 4 | name: simple-app 5 | namespace: default 6 | spec: 7 | serviceAccountName: default-ns-sa 8 | fetch: 9 | - git: 10 | url: https://github.com/k14s/k8s-simple-app-example 11 | ref: origin/develop 12 | subPath: config-step-2-template 13 | template: 14 | - ytt: {} 15 | deploy: 16 | - kapp: {} 17 | -------------------------------------------------------------------------------- /examples/kapp-controller/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "create": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/kapp-controller/test/app.yml") 14 | .wait_for_pod_status("simple-app-*", RUNNING), 15 | } 16 | 17 | test_cases[sys.argv[1]].run(sys.argv[2]) 18 | -------------------------------------------------------------------------------- /examples/mongodb-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | docker build \ 5 | --build-arg GIT_COMMIT=$GIT_COMMIT \ 6 | --build-arg GIT_BRANCH=$GIT_BRANCH \ 7 | --build-arg GO_LDFLAGS="$GO_LDFLAGS" \ 8 | --no-cache \ 9 | -t "percona/mongodb-operator:latest" -f build/Dockerfile . 10 | -------------------------------------------------------------------------------- /examples/mongodb-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f bundle.yaml 5 | -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/disable-enable-arbiter/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-q9fht", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/disable-enable-shard-brittle/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-ftm5w", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/disable-enable-shard/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-ftm5w", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-2xgk9", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/run-cert-manager/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-9gz77", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/mongodb-operator/oracle/scaleup-scaledown/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-server-mongodb-operator-lock", 3 | "deployment/default/percona-server-mongodb-operator", 4 | "pod/default/percona-server-mongodb-operator-7f696b75f5-9gzpz", 5 | "replicaset/default/percona-server-mongodb-operator-7f696b75f5" 6 | ] -------------------------------------------------------------------------------- /examples/nifikop-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the manager binary 2 | FROM golang:1.15 as builder 3 | 4 | WORKDIR /workspace 5 | # Copy the go source 6 | COPY . ./ 7 | 8 | RUN go mod tidy 9 | 10 | # Build 11 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go 12 | 13 | # Use distroless as minimal base image to package the manager binary 14 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 15 | FROM gcr.io/distroless/static:nonroot 16 | LABEL org.opencontainers.image.documentation="https://github.com/Orange-OpenSource/nifikop/blob/master/README.md" 17 | LABEL org.opencontainers.image.authors="Alexandre Guitton " 18 | LABEL org.opencontainers.image.source="https://github.com/Orange-OpenSource/nifikop" 19 | LABEL org.opencontainers.image.vendor="Orange France - Digital Factory" 20 | LABEL org.opencontainers.image.version="0.1" 21 | LABEL org.opencontainers.image.description="Operateur des Gestion de Clusters Nifi" 22 | LABEL org.opencontainers.image.url="https://github.com/Orange-OpenSource/nifikop" 23 | LABEL org.opencontainers.image.title="Operateur NiFi" 24 | 25 | LABEL org.label-schema.usage="https://github.com/Orange-OpenSource/nifikop/blob/master/README.md" 26 | LABEL org.label-schema.docker.cmd="/usr/local/bin/nifikop" 27 | LABEL org.label-schema.docker.cmd.devel="N/A" 28 | LABEL org.label-schema.docker.cmd.test="N/A" 29 | LABEL org.label-schema.docker.cmd.help="N/A" 30 | LABEL org.label-schema.docker.cmd.debug="N/A" 31 | LABEL org.label-schema.docker.params="LOG_LEVEL=define loglevel,RESYNC_PERIOD=period in second to execute resynchronisation,WATCH_NAMESPACE=namespace to watch for nificlusters,OPERATOR_NAME=name of the operator instance pod" 32 | 33 | WORKDIR / 34 | COPY --from=builder /workspace/manager . 35 | 36 | #USER 65532:65532 37 | USER 1001:1001 38 | 39 | ENTRYPOINT ["/manager"] 40 | -------------------------------------------------------------------------------- /examples/nifikop-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | docker build \ 5 | --no-cache \ 6 | -t "orangeopensource/nifikop-operator:latest" -f Dockerfile . 7 | -------------------------------------------------------------------------------- /examples/nifikop-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nifikop-operator", 3 | "github_link": "https://github.com/Orange-OpenSource/nifikop.git", 4 | "commit": "1546e0242107bf2f2c1256db50f47c79956dd1c6", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.20.2", 7 | "dockerfile_path": "Dockerfile", 8 | "controller_image_name": "orangeopensource/nifikop-operator:latest", 9 | "test_command": "python3 examples/nifikop-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "nificluster" 12 | ], 13 | "annotated_reconcile_functions": { 14 | "controllers/nificluster_controller.go": "github.com/Orange-OpenSource/nifikop/controllers.(*NifiClusterReconciler).Reconcile" 15 | }, 16 | "controller_pod_label": "nifikop-operator", 17 | "controller_deployment_file_path": "examples/nifikop-operator/deploy/values.yaml", 18 | "end_state_checker_mask": { 19 | "*": { 20 | "nificluster/default/simplenifi": [ 21 | [ 22 | "status", 23 | "state" 24 | ], 25 | [ 26 | "status", 27 | "prometheusReportingTask", 28 | "version" 29 | ] 30 | ], 31 | "lease/default/f1c5ece8.example.com": [ 32 | [ 33 | "spec", 34 | "leaseTransitions" 35 | ] 36 | ], 37 | "pod/default/zookeeper-0": [ 38 | [ 39 | "status", 40 | "containerStatuses", 41 | "*", 42 | "lastTerminationState" 43 | ], 44 | [ 45 | "status", 46 | "containerStatuses", 47 | "*", 48 | "restartCount" 49 | ] 50 | ] 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for NiFiKop - the Orange NiFi Kubernetes operator 3 | name: nifikop 4 | home: https://github.com/Orange-OpenSource/nifikop 5 | sources: 6 | - https://github.com/Orange-OpenSource/nifikop 7 | version: 0.6.3 8 | appVersion: 0.6.3-release 9 | icon: 10 | maintainers: 11 | - name: erdrix 12 | email: aguitton.ext@orange.com 13 | - name: fdehay 14 | email: franck.dehay@orange.com 15 | keywords: 16 | - operator 17 | - nifi 18 | - nifikop 19 | - data -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f role.yaml 5 | ./zk.sh 6 | helm install -f values.yaml nifikop-operator . 7 | -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: fabric8-rbac 5 | subjects: 6 | - kind: ServiceAccount 7 | # Reference to upper's `metadata.name` 8 | name: default 9 | # Reference to upper's `metadata.namespace` 10 | namespace: default 11 | roleRef: 12 | kind: ClusterRole 13 | name: cluster-admin 14 | apiGroup: rbac.authorization.k8s.io 15 | -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Congratulations. You have just deployed Nifikop the NiFi Operator. 2 | Check its status by running: 3 | kubectl --namespace {{ .Release.Namespace }} get pods -l "release={{ .Release.Name }}" 4 | 5 | Visit https://github.com/Orange-OpenSource/nifikop for instructions on hot to create & configure Nifi clusters using the operator. -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/templates/_functions.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "nifikop.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "nifikop.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Return the appropriate apiVersion value to use for the capi-operator managed k8s resources 29 | */}} 30 | {{- define "nifikop.apiVersion" -}} 31 | {{- printf "%s" "nificlusters.nifi.orange.com/v1alpha1" -}} 32 | {{- end -}} 33 | 34 | -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/templates/role_binding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbacEnable }} 2 | {{- range $namespace := $.Values.namespaces }} 3 | {{- $_ := set $ "vals" $.Values }} 4 | --- 5 | kind: RoleBinding 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | metadata: 8 | labels: 9 | app: {{ template "nifikop.name" $ }} 10 | chart: {{ $.Chart.Name }}-{{ $.Chart.Version }} 11 | heritage: {{ $.Release.Service }} 12 | release: {{ $.Release.Name }} 13 | name: {{ template "nifikop.name" $ }} 14 | namespace: {{$namespace}} 15 | subjects: 16 | - kind: ServiceAccount 17 | name: {{ template "nifikop.name" $ }} 18 | namespace: {{$.Release.Namespace}} 19 | roleRef: 20 | kind: Role 21 | name: {{ template "nifikop.name" $ }} 22 | apiGroup: rbac.authorization.k8s.io 23 | {{- end }} 24 | {{- end }} 25 | --- -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.metricService }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "nifikop.name" . }}-metrics 6 | labels: 7 | component: app 8 | app: {{ template "nifikop.name" . }}-metrics 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | spec: 13 | selector: 14 | app: {{ template "nifikop.name" . }} 15 | ports: 16 | - name: metrics 17 | port: 9710 18 | protocol: TCP 19 | {{- end }} -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/templates/service_account.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | labels: 6 | app: {{ template "nifikop.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | {{- if and .Values.serviceAccount .Values.serviceAccount.name}} 11 | name: {{ .Values.serviceAccount.name }} 12 | {{- else }} 13 | name: {{ template "nifikop.name" . }} 14 | {{- end }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/values.yaml: -------------------------------------------------------------------------------- 1 | ## NiFi Operator Image 2 | ## 3 | image: 4 | repository: ${SIEVE-DR}/nifikop-operator 5 | tag: ${SIEVE-DT} 6 | pullPolicy: IfNotPresent 7 | imagePullSecrets: 8 | enabled: false 9 | # name: 10 | vaultAddress: "" 11 | # vaultSecret containing a `ca.crt` key with the Vault CA Certificate 12 | vaultSecret: "" 13 | # set of namespaces where the operator watches resources 14 | namespaces: [] 15 | 16 | ## Prometheus-operator resource limits & requests 17 | ## Ref: https://kubernetes.io/docs/user-guide/compute-resources/ 18 | resources: 19 | requests: 20 | cpu: 10m 21 | memory: 50Mi 22 | limits: 23 | cpu: 1 24 | memory: 512Mi 25 | 26 | ## If true, create & deploy the CRD 27 | ## 28 | createCustomResource: true 29 | 30 | ## If true, create & use RBAC resources 31 | ## 32 | rbacEnable: false 33 | 34 | ## If true, create serviceAccount 35 | ## 36 | serviceAccount: 37 | create: false 38 | 39 | ## if true deploy service for metrics access 40 | metricService: false 41 | 42 | debug: 43 | enabled: false 44 | 45 | certManager: 46 | enabled: false 47 | clusterScoped: false 48 | -------------------------------------------------------------------------------- /examples/nifikop-operator/deploy/zk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | helm repo add bitnami https://charts.bitnami.com/bitnami 3 | helm install zookeeper bitnami/zookeeper \ 4 | --set resources.requests.memory=256Mi \ 5 | --set resources.requests.cpu=250m \ 6 | --set resources.limits.memory=256Mi \ 7 | --set resources.limits.cpu=250m \ 8 | --set global.storageClass=standard \ 9 | --set networkPolicy.enabled=false \ 10 | --set replicaCount=1 \ 11 | --version v7.4.3 12 | 13 | -------------------------------------------------------------------------------- /examples/nifikop-operator/oracle/change-config/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/nifikop-operator", 3 | "pod/default/nifikop-operator-75bbb6d6-9c2x8", 4 | "replicaset/default/nifikop-operator-75bbb6d6" 5 | ] -------------------------------------------------------------------------------- /examples/nifikop-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/nifikop-operator", 3 | "pod/default/nifikop-operator-75bbb6d6-66pkg", 4 | "replicaset/default/nifikop-operator-75bbb6d6" 5 | ] -------------------------------------------------------------------------------- /examples/nifikop-operator/oracle/scaledown-scaleup/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/nifikop-operator", 3 | "pod/default/nifikop-operator-75bbb6d6-vgzhg", 4 | "replicaset/default/nifikop-operator-75bbb6d6" 5 | ] -------------------------------------------------------------------------------- /examples/nifikop-operator/test/nc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nifi.orange.com/v1alpha1 2 | kind: NifiCluster 3 | metadata: 4 | name: simplenifi 5 | spec: 6 | service: 7 | headlessEnabled: true 8 | zkAddress: "zookeeper:2181" 9 | zkPath: "/simplenifi" 10 | clusterImage: "apache/nifi:1.12.1" 11 | oneNifiNodePerNode: false 12 | nodeConfigGroups: 13 | default_group: 14 | isNode: true 15 | storageConfigs: 16 | - mountPath: "/opt/nifi/nifi-current/logs" 17 | name: logs 18 | pvcSpec: 19 | accessModes: 20 | - ReadWriteOnce 21 | storageClassName: "standard" 22 | resources: 23 | requests: 24 | storage: 10Gi 25 | serviceAccountName: "default" 26 | resourcesRequirements: 27 | limits: 28 | cpu: "0.5" 29 | memory: 2Gi 30 | requests: 31 | cpu: "0.5" 32 | memory: 2Gi 33 | nodes: 34 | - id: 1 35 | nodeConfigGroup: "default_group" 36 | propagateLabels: true 37 | nifiClusterTaskSpec: 38 | retryDurationMinutes: 10 39 | listenersConfig: 40 | internalListeners: 41 | - type: "http" 42 | name: "http" 43 | containerPort: 8080 44 | - type: "cluster" 45 | name: "cluster" 46 | containerPort: 6007 47 | - type: "s2s" 48 | name: "s2s" 49 | containerPort: 10000 50 | - type: "prometheus" 51 | name: "prometheus" 52 | containerPort: 9090 53 | externalServices: 54 | - name: "clusterip" 55 | spec: 56 | type: ClusterIP 57 | portConfigs: 58 | - port: 8080 59 | internalListenerName: "http" 60 | serviceAnnotations: 61 | toto: tata 62 | - name: "loadbalancer" 63 | spec: 64 | type: LoadBalancer 65 | portConfigs: 66 | - port: 8080 67 | internalListenerName: "http" 68 | serviceAnnotations: 69 | toto: tata 70 | - name: "nodepart" 71 | spec: 72 | type: NodePort 73 | portConfigs: 74 | - port: 8080 75 | internalListenerName: "http" 76 | serviceAnnotations: 77 | toto: tata 78 | -------------------------------------------------------------------------------- /examples/nifikop-operator/test/nc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nifi.orange.com/v1alpha1 2 | kind: NifiCluster 3 | metadata: 4 | name: simplenifi 5 | spec: 6 | service: 7 | headlessEnabled: true 8 | zkAddress: "zookeeper:2181" 9 | zkPath: "/simplenifi" 10 | clusterImage: "apache/nifi:1.12.1" 11 | oneNifiNodePerNode: false 12 | nodeConfigGroups: 13 | default_group: 14 | isNode: true 15 | storageConfigs: 16 | - mountPath: "/opt/nifi/nifi-current/logs" 17 | name: logs 18 | pvcSpec: 19 | accessModes: 20 | - ReadWriteOnce 21 | storageClassName: "standard" 22 | resources: 23 | requests: 24 | storage: 10Gi 25 | serviceAccountName: "default" 26 | resourcesRequirements: 27 | limits: 28 | cpu: "0.5" 29 | memory: 2Gi 30 | requests: 31 | cpu: "0.5" 32 | memory: 2Gi 33 | nodes: 34 | - id: 1 35 | nodeConfigGroup: "default_group" 36 | - id: 2 37 | nodeConfigGroup: "default_group" 38 | propagateLabels: true 39 | nifiClusterTaskSpec: 40 | retryDurationMinutes: 10 41 | listenersConfig: 42 | internalListeners: 43 | - type: "http" 44 | name: "http" 45 | containerPort: 8080 46 | - type: "cluster" 47 | name: "cluster" 48 | containerPort: 6007 49 | - type: "s2s" 50 | name: "s2s" 51 | containerPort: 10000 52 | - type: "prometheus" 53 | name: "prometheus" 54 | containerPort: 9090 55 | externalServices: 56 | - name: "clusterip" 57 | spec: 58 | type: ClusterIP 59 | portConfigs: 60 | - port: 8080 61 | internalListenerName: "http" 62 | serviceAnnotations: 63 | toto: tata 64 | - name: "loadbalancer" 65 | spec: 66 | type: LoadBalancer 67 | portConfigs: 68 | - port: 8080 69 | internalListenerName: "http" 70 | serviceAnnotations: 71 | toto: tata 72 | - name: "nodepart" 73 | spec: 74 | type: NodePort 75 | portConfigs: 76 | - port: 8080 77 | internalListenerName: "http" 78 | serviceAnnotations: 79 | toto: tata 80 | -------------------------------------------------------------------------------- /examples/rabbitmq-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the manager binary 2 | FROM golang:1.16 as builder 3 | 4 | WORKDIR /workspace 5 | 6 | # Dependencies are cached unless we change go.mod or go.sum 7 | COPY go.mod go.mod 8 | COPY go.sum go.sum 9 | # RUN go mod download 10 | 11 | # Copy the go source 12 | COPY main.go main.go 13 | COPY api/ api/ 14 | COPY controllers/ controllers/ 15 | COPY internal/ internal/ 16 | COPY sieve-dependency/ sieve-dependency/ 17 | 18 | # Build 19 | RUN go mod download k8s.io/apimachinery 20 | RUN go mod download k8s.io/klog 21 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -tags timetzdata -o manager main.go 22 | 23 | # --------------------------------------- 24 | FROM alpine:latest as etc-builder 25 | 26 | RUN echo "rabbitmq-cluster-operator:x:1000:" > /etc/group && \ 27 | echo "rabbitmq-cluster-operator:x:1000:1000::/home/rabbitmq-cluster-operator:/usr/sbin/nologin" > /etc/passwd 28 | 29 | 30 | RUN apk add -U --no-cache ca-certificates 31 | 32 | # --------------------------------------- 33 | FROM scratch 34 | 35 | ARG GIT_COMMIT 36 | LABEL GitCommit=$GIT_COMMIT 37 | 38 | WORKDIR / 39 | COPY --from=builder /workspace/manager . 40 | COPY --from=etc-builder /etc/passwd /etc/group /etc/ 41 | COPY --from=etc-builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 42 | 43 | USER 1000:1000 44 | 45 | ENTRYPOINT ["/manager"] 46 | -------------------------------------------------------------------------------- /examples/rabbitmq-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | DOCKER_REGISTRY_SERVER=rabbitmq OPERATOR_IMAGE=rabbitmq-operator make docker-build 5 | -------------------------------------------------------------------------------- /examples/rabbitmq-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rabbitmq-operator", 3 | "github_link": "https://github.com/rabbitmq/cluster-operator.git", 4 | "commit": "4f13b9a942ad34fece0171d2174aa0264b10e947", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.20.2", 7 | "dockerfile_path": "Dockerfile", 8 | "controller_image_name": "rabbitmq/rabbitmq-operator:latest", 9 | "test_command": "python3 examples/rabbitmq-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "rabbitmqcluster" 12 | ], 13 | "annotated_reconcile_functions": { 14 | "controllers/rabbitmqcluster_controller.go": "github.com/rabbitmq/cluster-operator/controllers.(*RabbitmqClusterReconciler).Reconcile" 15 | }, 16 | "controller_pod_label": "rabbitmq-operator", 17 | "controller_deployment_file_path": "examples/rabbitmq-operator/deploy/cluster-operator.yaml", 18 | "test_setting": { 19 | "resize-pvc": { 20 | "use_csi_driver": true 21 | } 22 | }, 23 | "end_state_checker_mask": { 24 | "*": { 25 | "service/default/rabbitmq-cluster": [ 26 | [ 27 | "spec", 28 | "ports" 29 | ] 30 | ], 31 | "pod/*/*": [ 32 | [ 33 | "status", 34 | "containerStatuses", 35 | "*", 36 | "lastTerminationState" 37 | ], 38 | [ 39 | "status", 40 | "containerStatuses", 41 | "*", 42 | "restartCount" 43 | ] 44 | ] 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /examples/rabbitmq-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f cluster-operator.yaml 5 | -------------------------------------------------------------------------------- /examples/rabbitmq-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/rabbitmq-operator", 3 | "pod/default/rabbitmq-operator-b7d5945b-rjgls", 4 | "replicaset/default/rabbitmq-operator-b7d5945b" 5 | ] -------------------------------------------------------------------------------- /examples/rabbitmq-operator/oracle/resize-pvc/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/rabbitmq-operator", 3 | "pod/default/rabbitmq-operator-b7d5945b-4xgk5", 4 | "replicaset/default/rabbitmq-operator-b7d5945b" 5 | ] -------------------------------------------------------------------------------- /examples/rabbitmq-operator/oracle/scaleup-scaledown/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "deployment/default/rabbitmq-operator", 3 | "pod/default/rabbitmq-operator-b7d5945b-vjpp4", 4 | "replicaset/default/rabbitmq-operator-b7d5945b" 5 | ] -------------------------------------------------------------------------------- /examples/rabbitmq-operator/test/rmqc-1-15Gi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rabbitmq.com/v1beta1 2 | kind: RabbitmqCluster 3 | metadata: 4 | name: rabbitmq-cluster 5 | spec: 6 | replicas: 1 7 | persistence: 8 | storage: "15Gi" 9 | -------------------------------------------------------------------------------- /examples/rabbitmq-operator/test/rmqc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rabbitmq.com/v1beta1 2 | kind: RabbitmqCluster 3 | metadata: 4 | name: rabbitmq-cluster 5 | spec: 6 | replicas: 1 7 | persistence: 8 | storage: "10Gi" -------------------------------------------------------------------------------- /examples/rabbitmq-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/rabbitmq-operator/test/rmqc-1.yaml") 14 | .wait_for_pod_status("rabbitmq-cluster-server-0", RUNNING) 15 | .cmd("kubectl delete RabbitmqCluster rabbitmq-cluster") 16 | .wait_for_pod_status("rabbitmq-cluster-server-0", TERMINATED) 17 | .cmd("kubectl apply -f examples/rabbitmq-operator/test/rmqc-1.yaml") 18 | .wait_for_pod_status("rabbitmq-cluster-server-0", RUNNING), 19 | "scaleup-scaledown": new_built_in_workload(70) 20 | .cmd("kubectl apply -f examples/rabbitmq-operator/test/rmqc-1.yaml") 21 | .wait_for_pod_status("rabbitmq-cluster-server-0", RUNNING) 22 | .cmd( 23 | 'kubectl patch RabbitmqCluster rabbitmq-cluster --type merge -p=\'{"spec":{"replicas":3}}\'' 24 | ) 25 | .wait_for_pod_status("rabbitmq-cluster-server-2", RUNNING) 26 | .cmd( 27 | 'kubectl patch RabbitmqCluster rabbitmq-cluster --type merge -p=\'{"spec":{"replicas":2}}\'' 28 | ), 29 | "resize-pvc": new_built_in_workload(80) 30 | .cmd("kubectl apply -f examples/rabbitmq-operator/test/rmqc-1.yaml") 31 | .wait_for_pod_status("rabbitmq-cluster-server-0", RUNNING) 32 | .cmd( 33 | 'kubectl patch RabbitmqCluster rabbitmq-cluster --type merge -p=\'{"spec":{"persistence":{"storage":"15Gi"}}}\'' 34 | ) 35 | .wait_for_sts_storage_size("rabbitmq-cluster-server", "15Gi"), 36 | } 37 | 38 | test_cases[sys.argv[1]].run(sys.argv[2]) 39 | -------------------------------------------------------------------------------- /examples/xtradb-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.14 AS go_builder 2 | WORKDIR /go/src/github.com/percona/percona-xtradb-cluster-operator 3 | 4 | COPY . . 5 | 6 | ARG GIT_COMMIT 7 | ARG GIT_BRANCH 8 | ARG GO_LDFLAGS 9 | ARG GOOS=linux 10 | ARG GOARCH=amd64 11 | ARG CGO_ENABLED=0 12 | 13 | RUN mkdir -p build/_output/bin \ 14 | && GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=$CGO_ENABLED GO_LDFLAGS=$GO_LDFLAGS \ 15 | go build -ldflags "-w -s -X main.GitCommit=$GIT_COMMIT -X main.GitBranch=$GIT_BRANCH" \ 16 | -o build/_output/bin/percona-xtradb-cluster-operator \ 17 | cmd/manager/main.go \ 18 | && cp -r build/_output/bin/percona-xtradb-cluster-operator /usr/local/bin/percona-xtradb-cluster-operator 19 | 20 | RUN go get k8s.io/apimachinery/pkg/util/sets \ 21 | && go build -o build/_output/bin/peer-list cmd/peer-list/main.go \ 22 | && cp -r build/_output/bin/peer-list /usr/local/bin/ 23 | 24 | # LABEL name="Percona XtraDB Cluster Operator" \ 25 | # vendor="Percona" \ 26 | # summary="Percona XtraDB Cluster is an active/active high availability and high scalability open source solution for MySQL clustering" \ 27 | # description="Percona XtraDB Cluster is a high availability solution that helps enterprises avoid downtime and outages and meet expected customer experience." \ 28 | # maintainer="Percona Development " 29 | 30 | FROM registry.access.redhat.com/ubi7/ubi-minimal AS ubi7 31 | RUN microdnf update && microdnf clean all 32 | 33 | # COPY LICENSE /licenses/ 34 | COPY --from=go_builder /usr/local/bin/percona-xtradb-cluster-operator /usr/local/bin/percona-xtradb-cluster-operator 35 | COPY --from=go_builder /usr/local/bin/peer-list /peer-list 36 | COPY build/pxc-entrypoint.sh /pxc-entrypoint.sh 37 | COPY build/pxc-init-entrypoint.sh /pxc-init-entrypoint.sh 38 | COPY build/unsafe-bootstrap.sh /unsafe-bootstrap.sh 39 | COPY build/pxc-configure-pxc.sh /pxc-configure-pxc.sh 40 | COPY build/liveness-check.sh /liveness-check.sh 41 | COPY build/readiness-check.sh /readiness-check.sh 42 | 43 | USER nobody -------------------------------------------------------------------------------- /examples/xtradb-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | docker build \ 5 | --build-arg GIT_COMMIT=$GIT_COMMIT \ 6 | --build-arg GIT_BRANCH=$GIT_BRANCH \ 7 | --build-arg GO_LDFLAGS="$GO_LDFLAGS" \ 8 | --no-cache \ 9 | -t "percona/xtradb-operator:latest" -f build/Dockerfile . 10 | -------------------------------------------------------------------------------- /examples/xtradb-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl apply -f bundle.yaml 5 | -------------------------------------------------------------------------------- /examples/xtradb-operator/oracle/disable-enable-haproxy/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-xtradb-cluster-operator-lock", 3 | "deployment/default/percona-xtradb-cluster-operator", 4 | "endpointslice/default/percona-xtradb-cluster-operator-4mggn", 5 | "pod/default/percona-xtradb-cluster-operator-56c7bd8b98-xtnjx", 6 | "replicaset/default/percona-xtradb-cluster-operator-56c7bd8b98", 7 | "service/default/percona-xtradb-cluster-operator" 8 | ] -------------------------------------------------------------------------------- /examples/xtradb-operator/oracle/disable-enable-proxysql/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-xtradb-cluster-operator-lock", 3 | "deployment/default/percona-xtradb-cluster-operator", 4 | "endpointslice/default/percona-xtradb-cluster-operator-zxsdc", 5 | "pod/default/percona-xtradb-cluster-operator-56c7bd8b98-vgdsf", 6 | "replicaset/default/percona-xtradb-cluster-operator-56c7bd8b98", 7 | "service/default/percona-xtradb-cluster-operator" 8 | ] -------------------------------------------------------------------------------- /examples/xtradb-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-xtradb-cluster-operator-lock", 3 | "deployment/default/percona-xtradb-cluster-operator", 4 | "endpointslice/default/percona-xtradb-cluster-operator-qg5rw", 5 | "pod/default/percona-xtradb-cluster-operator-56c7bd8b98-vhmq9", 6 | "replicaset/default/percona-xtradb-cluster-operator-56c7bd8b98", 7 | "service/default/percona-xtradb-cluster-operator" 8 | ] -------------------------------------------------------------------------------- /examples/xtradb-operator/oracle/run-cert-manager/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-xtradb-cluster-operator-lock", 3 | "deployment/default/percona-xtradb-cluster-operator", 4 | "endpointslice/default/percona-xtradb-cluster-operator-wlcfp", 5 | "pod/default/percona-xtradb-cluster-operator-56c7bd8b98-8rzgw", 6 | "replicaset/default/percona-xtradb-cluster-operator-56c7bd8b98", 7 | "service/default/percona-xtradb-cluster-operator" 8 | ] -------------------------------------------------------------------------------- /examples/xtradb-operator/oracle/scaleup-scaledown/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/percona-xtradb-cluster-operator-lock", 3 | "deployment/default/percona-xtradb-cluster-operator", 4 | "endpointslice/default/percona-xtradb-cluster-operator-zqtgv", 5 | "pod/default/percona-xtradb-cluster-operator-56c7bd8b98-t4mmk", 6 | "replicaset/default/percona-xtradb-cluster-operator-56c7bd8b98", 7 | "service/default/percona-xtradb-cluster-operator" 8 | ] -------------------------------------------------------------------------------- /examples/xtradb-operator/test/cr-4.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: pxc.percona.com/v1-7-0 2 | kind: PerconaXtraDBCluster 3 | metadata: 4 | name: xtradb-cluster 5 | finalizers: 6 | - delete-pxc-pods-in-order 7 | - delete-proxysql-pvc 8 | - delete-pxc-pvc 9 | spec: 10 | crVersion: 1.7.0 11 | secretsName: xtradb-cluster-secrets 12 | vaultSecretName: keyring-secret-vault 13 | sslSecretName: xtradb-cluster-ssl 14 | sslInternalSecretName: xtradb-cluster-ssl-internal 15 | logCollectorSecretName: xtradb-log-collector-secrets 16 | allowUnsafeConfigurations: false 17 | updateStrategy: RollingUpdate 18 | upgradeOptions: 19 | versionServiceEndpoint: https://check.percona.com 20 | apply: recommended 21 | schedule: "0 4 * * *" 22 | pxc: 23 | size: 4 24 | image: percona/percona-xtradb-cluster:8.0.21-12.1 25 | autoRecovery: true 26 | resources: 27 | requests: 28 | memory: 1G 29 | cpu: 600m 30 | affinity: 31 | antiAffinityTopologyKey: "kubernetes.io/hostname" 32 | podDisruptionBudget: 33 | maxUnavailable: 1 34 | volumeSpec: 35 | persistentVolumeClaim: 36 | resources: 37 | requests: 38 | storage: 6Gi 39 | gracePeriod: 600 40 | haproxy: 41 | enabled: false 42 | size: 3 43 | image: percona/percona-xtradb-cluster-operator:1.7.0-haproxy 44 | resources: 45 | requests: 46 | memory: 1G 47 | cpu: 600m 48 | affinity: 49 | antiAffinityTopologyKey: "kubernetes.io/hostname" 50 | podDisruptionBudget: 51 | maxUnavailable: 1 52 | gracePeriod: 30 53 | proxysql: 54 | enabled: false 55 | size: 3 56 | image: percona/percona-xtradb-cluster-operator:1.7.0-proxysql 57 | resources: 58 | requests: 59 | memory: 1G 60 | cpu: 600m 61 | affinity: 62 | antiAffinityTopologyKey: "kubernetes.io/hostname" 63 | volumeSpec: 64 | persistentVolumeClaim: 65 | resources: 66 | requests: 67 | storage: 2Gi 68 | podDisruptionBudget: 69 | maxUnavailable: 1 70 | gracePeriod: 30 71 | logcollector: 72 | enabled: false 73 | image: percona/percona-xtradb-cluster-operator:1.7.0-logcollector 74 | pmm: 75 | enabled: false 76 | image: percona/pmm-client:2.12.0 77 | serverHost: monitoring-service 78 | serverUser: pmm -------------------------------------------------------------------------------- /examples/xtradb-operator/test/cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: pxc.percona.com/v1-7-0 2 | kind: PerconaXtraDBCluster 3 | metadata: 4 | name: xtradb-cluster 5 | finalizers: 6 | - delete-pxc-pods-in-order 7 | - delete-proxysql-pvc 8 | - delete-pxc-pvc 9 | spec: 10 | crVersion: 1.7.0 11 | secretsName: xtradb-cluster-secrets 12 | vaultSecretName: keyring-secret-vault 13 | sslSecretName: xtradb-cluster-ssl 14 | sslInternalSecretName: xtradb-cluster-ssl-internal 15 | logCollectorSecretName: xtradb-log-collector-secrets 16 | allowUnsafeConfigurations: false 17 | updateStrategy: RollingUpdate 18 | upgradeOptions: 19 | versionServiceEndpoint: https://check.percona.com 20 | apply: recommended 21 | schedule: "0 4 * * *" 22 | pxc: 23 | size: 3 24 | image: percona/percona-xtradb-cluster:8.0.21-12.1 25 | autoRecovery: true 26 | resources: 27 | requests: 28 | memory: 1G 29 | cpu: 600m 30 | affinity: 31 | antiAffinityTopologyKey: "kubernetes.io/hostname" 32 | podDisruptionBudget: 33 | maxUnavailable: 1 34 | volumeSpec: 35 | persistentVolumeClaim: 36 | resources: 37 | requests: 38 | storage: 6Gi 39 | gracePeriod: 600 40 | haproxy: 41 | enabled: false 42 | size: 3 43 | image: percona/percona-xtradb-cluster-operator:1.7.0-haproxy 44 | resources: 45 | requests: 46 | memory: 1G 47 | cpu: 600m 48 | affinity: 49 | antiAffinityTopologyKey: "kubernetes.io/hostname" 50 | podDisruptionBudget: 51 | maxUnavailable: 1 52 | gracePeriod: 30 53 | proxysql: 54 | enabled: false 55 | size: 3 56 | image: percona/percona-xtradb-cluster-operator:1.7.0-proxysql 57 | resources: 58 | requests: 59 | memory: 1G 60 | cpu: 600m 61 | affinity: 62 | antiAffinityTopologyKey: "kubernetes.io/hostname" 63 | volumeSpec: 64 | persistentVolumeClaim: 65 | resources: 66 | requests: 67 | storage: 2Gi 68 | podDisruptionBudget: 69 | maxUnavailable: 1 70 | gracePeriod: 30 71 | logcollector: 72 | enabled: false 73 | image: percona/percona-xtradb-cluster-operator:1.7.0-logcollector 74 | pmm: 75 | enabled: false 76 | image: percona/pmm-client:2.12.0 77 | serverHost: monitoring-service 78 | serverUser: pmm -------------------------------------------------------------------------------- /examples/yugabyte-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG GOLANG_BASE_IMAGE=golang:1.13.9 2 | 3 | FROM ${GOLANG_BASE_IMAGE} AS builder 4 | 5 | WORKDIR /src 6 | 7 | # Copy go.mod and go.sum separately to ensure we re-download dependencies only 8 | # when these files change 9 | COPY go.mod go.sum ./ 10 | 11 | # Fetch Go modules in a separate layer for better caching 12 | # RUN go mod download 13 | 14 | COPY . ./ 15 | 16 | RUN cd cmd/manager \ 17 | && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ 18 | -ldflags "-w" \ 19 | -o /tmp/yugabyte-operator 20 | 21 | FROM registry.access.redhat.com/ubi7/ubi-minimal:latest 22 | 23 | ENV OPERATOR=/usr/local/bin/yugabyte-operator \ 24 | USER_UID=1001 \ 25 | USER_NAME=yugabyte-operator 26 | 27 | COPY --from=builder /tmp/yugabyte-operator /usr/local/bin/yugabyte-operator 28 | 29 | COPY build/bin /usr/local/bin 30 | RUN /usr/local/bin/user_setup 31 | 32 | ENTRYPOINT ["/usr/local/bin/entrypoint"] 33 | 34 | USER ${USER_UID} 35 | -------------------------------------------------------------------------------- /examples/yugabyte-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | docker build \ 5 | --no-cache \ 6 | -t "yugabyte/yugabyte-operator:latest" -f build/Dockerfile . 7 | -------------------------------------------------------------------------------- /examples/yugabyte-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yugabyte-operator", 3 | "github_link": "https://github.com/yugabyte/yugabyte-operator.git", 4 | "commit": "966ef1978ed5d714119548b2c4343925fe49f882", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.17.4", 7 | "apimachinery_version": "v0.17.4", 8 | "dockerfile_path": "build/Dockerfile", 9 | "controller_image_name": "yugabyte/yugabyte-operator:latest", 10 | "test_command": "python3 examples/yugabyte-operator/test/test.py", 11 | "custom_resource_definitions": [ 12 | "ybcluster" 13 | ], 14 | "annotated_reconcile_functions": { 15 | "pkg/controller/ybcluster/ybcluster_controller.go": "github.com/yugabyte/yugabyte-operator/pkg/controller/ybcluster.(*ReconcileYBCluster).Reconcile" 16 | }, 17 | "controller_pod_label": "yugabyte-operator", 18 | "controller_deployment_file_path": "examples/yugabyte-operator/deploy/operator.yaml", 19 | "state_update_summary_checker_mask": { 20 | "*": [ 21 | "pod/default/yb-master-0", 22 | "pod/default/yb-master-1", 23 | "pod/default/yb-master-2" 24 | ] 25 | } 26 | } -------------------------------------------------------------------------------- /examples/yugabyte-operator/deploy/crds/yugabyte.com_v1alpha1_ybcluster_cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: yugabyte.com/v1alpha1 2 | kind: YBCluster 3 | metadata: 4 | name: example-ybcluster 5 | namespace: yb-operator 6 | spec: 7 | replicationFactor: 3 8 | master: 9 | replicas: 3 10 | storage: 11 | size: 1Gi 12 | tserver: 13 | replicas: 3 14 | storage: 15 | count: 1 16 | size: 1Gi 17 | -------------------------------------------------------------------------------- /examples/yugabyte-operator/deploy/crds/yugabyte.com_v1alpha1_ybcluster_full_cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: yugabyte.com/v1alpha1 2 | kind: YBCluster 3 | metadata: 4 | name: example-ybcluster 5 | namespace: yb-operator 6 | spec: 7 | image: 8 | repository: yugabytedb/yugabyte 9 | tag: 2.7.0.0-b17 10 | pullPolicy: IfNotPresent 11 | 12 | replicationFactor: 3 13 | master: 14 | replicas: 3 15 | masterUIPort: 7000 16 | masterRPCPort: 7100 17 | enableLoadBalancer: true 18 | podManagementPolicy: Parallel 19 | storage: 20 | count: 1 21 | size: 1Gi 22 | storageClass: standard 23 | resources: 24 | requests: 25 | cpu: 200m 26 | memory: 256Mi 27 | limits: 28 | cpu: 500m 29 | memory: 512Mi 30 | gflags: 31 | - key: default_memory_limit_to_ram_ratio 32 | value: "0.85" 33 | 34 | tserver: 35 | replicas: 3 36 | tserverUIPort: 9000 37 | tserverRPCPort: 9100 38 | ycqlPort: 9042 39 | yedisPort: 6379 40 | ysqlPort: 5433 41 | enableLoadBalancer: true 42 | podManagementPolicy: Parallel 43 | storage: 44 | count: 1 45 | size: 1Gi 46 | storageClass: standard 47 | resources: 48 | requests: 49 | cpu: 200m 50 | memory: 256Mi 51 | limits: 52 | cpu: 500m 53 | memory: 512Mi 54 | gflags: 55 | - key: default_memory_limit_to_ram_ratio 56 | value: "0.85" 57 | -------------------------------------------------------------------------------- /examples/yugabyte-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl create -f crds/yugabyte.com_ybclusters_crd.yaml 5 | kubectl create -f operator.yaml 6 | -------------------------------------------------------------------------------- /examples/yugabyte-operator/oracle/disable-enable-tls/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/yugabyte-k8s-operator-lock", 3 | "deployment/default/yugabyte-operator", 4 | "endpointslice/default/yugabyte-operator-metrics-d9c28", 5 | "pod/default/yugabyte-operator-86f6465d9b-2g8wm", 6 | "replicaset/default/yugabyte-operator-86f6465d9b", 7 | "service/default/yugabyte-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/yugabyte-operator/oracle/disable-enable-tuiport/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/yugabyte-k8s-operator-lock", 3 | "deployment/default/yugabyte-operator", 4 | "endpointslice/default/yugabyte-operator-metrics-ljqm4", 5 | "pod/default/yugabyte-operator-86f6465d9b-gwd8g", 6 | "replicaset/default/yugabyte-operator-86f6465d9b", 7 | "service/default/yugabyte-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/yugabyte-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/yugabyte-k8s-operator-lock", 3 | "deployment/default/yugabyte-operator", 4 | "endpointslice/default/yugabyte-operator-metrics-gcb65", 5 | "pod/default/yugabyte-operator-86f6465d9b-m6t5z", 6 | "replicaset/default/yugabyte-operator-86f6465d9b", 7 | "service/default/yugabyte-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/yugabyte-operator/oracle/scaleup-scaledown-tserver/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/yugabyte-k8s-operator-lock", 3 | "deployment/default/yugabyte-operator", 4 | "endpointslice/default/yugabyte-operator-metrics-7l6xv", 5 | "pod/default/yugabyte-operator-86f6465d9b-x9wpb", 6 | "replicaset/default/yugabyte-operator-86f6465d9b", 7 | "service/default/yugabyte-operator-metrics" 8 | ] -------------------------------------------------------------------------------- /examples/yugabyte-operator/test/yb-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: yugabyte.com/v1alpha1 2 | kind: YBCluster 3 | metadata: 4 | name: example-ybcluster 5 | spec: 6 | replicationFactor: 3 7 | master: 8 | replicas: 3 9 | storage: 10 | size: 1Gi 11 | tserver: 12 | replicas: 3 13 | storage: 14 | count: 1 15 | size: 1Gi -------------------------------------------------------------------------------- /examples/yugabyte-operator/test/yb-tserverUIPort-enabled.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: yugabyte.com/v1alpha1 2 | kind: YBCluster 3 | metadata: 4 | name: example-ybcluster 5 | spec: 6 | replicationFactor: 3 7 | master: 8 | replicas: 3 9 | storage: 10 | size: 1Gi 11 | tserver: 12 | replicas: 3 13 | storage: 14 | count: 1 15 | size: 1Gi 16 | tserverUIPort: 9000 -------------------------------------------------------------------------------- /examples/zookeeper-operator/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG DOCKER_REGISTRY 2 | ARG GO_VERSION=1.13.8 3 | ARG ALPINE_VERSION=3.11 4 | FROM ${DOCKER_REGISTRY:+$DOCKER_REGISTRY/}golang:${GO_VERSION}-alpine${ALPINE_VERSION} as go-builder 5 | 6 | ARG PROJECT_NAME=zookeeper-operator 7 | ARG REPO_PATH=github.com/pravega/$PROJECT_NAME 8 | 9 | # Build version and commit should be passed in when performing docker build 10 | ARG VERSION=0.0.0-localdev 11 | ARG GIT_SHA=0000000 12 | 13 | WORKDIR /src 14 | COPY pkg ./pkg 15 | COPY cmd ./cmd 16 | COPY go.mod ./ 17 | COPY sieve-dependency/ sieve-dependency/ 18 | 19 | # Download all dependencies. 20 | # RUN go mod download 21 | 22 | RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o /src/${PROJECT_NAME} \ 23 | -ldflags "-X ${REPO_PATH}/pkg/version.Version=${VERSION} -X ${REPO_PATH}/pkg/version.GitSHA=${GIT_SHA}" \ 24 | /src/cmd/manager 25 | 26 | # ============================================================================= 27 | 28 | FROM ${DOCKER_REGISTRY:+$DOCKER_REGISTRY/}alpine:${ALPINE_VERSION} AS final 29 | 30 | 31 | ARG PROJECT_NAME=zookeeper-operator 32 | 33 | COPY --from=go-builder /src/${PROJECT_NAME} /usr/local/bin/${PROJECT_NAME} 34 | 35 | RUN adduser -D ${PROJECT_NAME} 36 | USER ${PROJECT_NAME} 37 | 38 | ENTRYPOINT ["/usr/local/bin/zookeeper-operator"] 39 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | make build-image 5 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zookeeper-operator", 3 | "github_link": "https://github.com/pravega/zookeeper-operator.git", 4 | "commit": "cda03d2f270bdfb51372192766123904f6d88278", 5 | "kubernetes_version": "v1.18.9", 6 | "client_go_version": "v0.17.2", 7 | "dockerfile_path": "Dockerfile", 8 | "controller_image_name": "pravega/zookeeper-operator:latest", 9 | "test_command": "python3 examples/zookeeper-operator/test/test.py", 10 | "custom_resource_definitions": [ 11 | "zookeepercluster" 12 | ], 13 | "annotated_reconcile_functions": { 14 | "pkg/controller/zookeepercluster/zookeepercluster_controller.go": "github.com/pravega/zookeeper-operator/pkg/controller/zookeepercluster.(*ReconcileZookeeperCluster).Reconcile" 15 | }, 16 | "controller_pod_label": "zookeeper-operator", 17 | "controller_deployment_file_path": "examples/zookeeper-operator/deploy/default_ns/operator.yaml", 18 | "end_state_checker_mask": { 19 | "*": { 20 | "zookeepercluster/default/zookeeper-cluster": [ 21 | [ 22 | "status", 23 | "members", 24 | "ready" 25 | ] 26 | ] 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /examples/zookeeper-operator/deploy/default_ns/operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: zookeeper-operator 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | name: zookeeper-operator 10 | sievetag: zookeeper-operator 11 | template: 12 | metadata: 13 | labels: 14 | name: zookeeper-operator 15 | sievetag: zookeeper-operator 16 | spec: 17 | serviceAccountName: zookeeper-operator 18 | containers: 19 | - name: zookeeper-operator 20 | # Replace this with the built image name 21 | image: ${SIEVE-DR}/zookeeper-operator:${SIEVE-DT} 22 | ports: 23 | - containerPort: 60000 24 | name: metrics 25 | command: 26 | - zookeeper-operator 27 | imagePullPolicy: IfNotPresent 28 | env: 29 | - name: WATCH_NAMESPACE 30 | valueFrom: 31 | fieldRef: 32 | fieldPath: metadata.namespace 33 | - name: POD_NAME 34 | valueFrom: 35 | fieldRef: 36 | fieldPath: metadata.name 37 | - name: OPERATOR_NAME 38 | value: "zookeeper-operator" 39 | - name: KUBERNETES_SERVICE_HOST 40 | value: "kind-control-plane" 41 | - name: KUBERNETES_SERVICE_PORT 42 | value: "6443" 43 | envFrom: 44 | - configMapRef: 45 | name: sieve-testing-global-config 46 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/deploy/default_ns/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: zookeeper-operator 5 | 6 | --- 7 | 8 | kind: Role 9 | apiVersion: rbac.authorization.k8s.io/v1beta1 10 | metadata: 11 | name: zookeeper-operator 12 | rules: 13 | - apiGroups: 14 | - zookeeper.pravega.io 15 | resources: 16 | - "*" 17 | verbs: 18 | - "*" 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - pods 23 | - services 24 | - endpoints 25 | - persistentvolumeclaims 26 | - events 27 | - configmaps 28 | - secrets 29 | verbs: 30 | - "*" 31 | - apiGroups: 32 | - apps 33 | resources: 34 | - deployments 35 | - daemonsets 36 | - replicasets 37 | - statefulsets 38 | verbs: 39 | - "*" 40 | - apiGroups: 41 | - policy 42 | resources: 43 | - poddisruptionbudgets 44 | verbs: 45 | - "*" 46 | --- 47 | kind: RoleBinding 48 | apiVersion: rbac.authorization.k8s.io/v1beta1 49 | metadata: 50 | name: zookeeper-operator 51 | subjects: 52 | - kind: ServiceAccount 53 | name: zookeeper-operator 54 | namespace: default 55 | roleRef: 56 | kind: Role 57 | name: zookeeper-operator 58 | apiGroup: rbac.authorization.k8s.io 59 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | kubectl create -f crds 5 | kubectl create -f default_ns/rbac.yaml 6 | kubectl create -f default_ns/operator.yaml 7 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/oracle/recreate/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/zookeeper-operator-lock", 3 | "deployment/default/zookeeper-operator", 4 | "pod/default/zookeeper-operator-5fc77867c7-k2fhl", 5 | "replicaset/default/zookeeper-operator-5fc77867c7" 6 | ] -------------------------------------------------------------------------------- /examples/zookeeper-operator/oracle/scaledown-scaleup/controller_family.json: -------------------------------------------------------------------------------- 1 | [ 2 | "configmap/default/zookeeper-operator-lock", 3 | "deployment/default/zookeeper-operator", 4 | "pod/default/zookeeper-operator-5fc77867c7-twctv", 5 | "replicaset/default/zookeeper-operator-5fc77867c7" 6 | ] -------------------------------------------------------------------------------- /examples/zookeeper-operator/test/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | current = os.path.dirname(os.path.realpath(__file__)) 5 | sieve_root = os.path.dirname(os.path.dirname(os.path.dirname(current))) 6 | sys.path.append(sieve_root) 7 | 8 | from sieve_test_driver.test_framework import new_built_in_workload 9 | from sieve_common.common import RUNNING, TERMINATED 10 | 11 | test_cases = { 12 | "recreate": new_built_in_workload() 13 | .cmd("kubectl apply -f examples/zookeeper-operator/test/zkc-1.yaml") 14 | .wait_for_pod_status("zookeeper-cluster-0", RUNNING) 15 | .cmd("kubectl delete ZookeeperCluster zookeeper-cluster") 16 | .wait_for_pod_status("zookeeper-cluster-0", TERMINATED) 17 | .wait_for_pvc_status("data-zookeeper-cluster-0", TERMINATED) 18 | .cmd("kubectl apply -f examples/zookeeper-operator/test/zkc-1.yaml") 19 | .wait_for_pod_status("zookeeper-cluster-0", RUNNING), 20 | "scaledown-scaleup": new_built_in_workload() 21 | .cmd("kubectl apply -f examples/zookeeper-operator/test/zkc-2.yaml") 22 | .wait_for_pod_status("zookeeper-cluster-1", RUNNING) 23 | .wait(30) 24 | .cmd( 25 | 'kubectl patch ZookeeperCluster zookeeper-cluster --type merge -p=\'{"spec":{"replicas":1}}\'' 26 | ) 27 | .wait_for_pod_status("zookeeper-cluster-1", TERMINATED) 28 | .wait_for_pvc_status("data-zookeeper-cluster-1", TERMINATED) 29 | .cmd( 30 | 'kubectl patch ZookeeperCluster zookeeper-cluster --type merge -p=\'{"spec":{"replicas":2}}\'' 31 | ) 32 | .wait_for_pod_status("zookeeper-cluster-1", RUNNING), 33 | } 34 | 35 | test_cases[sys.argv[1]].run(sys.argv[2]) 36 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/test/zkc-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: zookeeper.pravega.io/v1beta1 2 | kind: ZookeeperCluster 3 | metadata: 4 | name: zookeeper-cluster 5 | spec: 6 | replicas: 1 7 | persistence: 8 | reclaimPolicy: Delete 9 | 10 | -------------------------------------------------------------------------------- /examples/zookeeper-operator/test/zkc-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: zookeeper.pravega.io/v1beta1 2 | kind: ZookeeperCluster 3 | metadata: 4 | name: zookeeper-cluster 5 | spec: 6 | replicas: 2 7 | persistence: 8 | reclaimPolicy: Delete 9 | 10 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | python3 -m black . 4 | -------------------------------------------------------------------------------- /go.work: -------------------------------------------------------------------------------- 1 | go 1.19 2 | 3 | use ( 4 | ./sieve_client 5 | ./sieve_server 6 | ./sieve_instrumentation 7 | ) 8 | -------------------------------------------------------------------------------- /go.work.sum: -------------------------------------------------------------------------------- 1 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= 2 | github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= 3 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 4 | github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= 5 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= 6 | github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= 7 | github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= 8 | github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= 9 | github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= 10 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 11 | github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= 12 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= 13 | golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= 14 | golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= 15 | golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= 16 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k= 17 | gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 18 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 19 | -------------------------------------------------------------------------------- /parallel_testing/README.md: -------------------------------------------------------------------------------- 1 | ## Run test configs in parallel on multiple workers 2 | 3 | ### How to run 4 | 1. Finish the learning mode and generate all the test configs on a master node(could be any worker node) 5 | 2. Create a file called `hosts` under this parallel_testing directory and list all the node's address. Except for this master node, write `:` to indicate that this is a local node. An example of a `hosts` file with the vm1.com being the master: 6 | ``` 7 | : 8 | ubuntu@vm2.com 9 | ubuntu@vm3.com 10 | ``` 11 | 3. On this master node's parallel_testing directory, run: 12 | `bash runtest.sh` 13 | If you want to pull from your own docker repo, modify the first step in the runtest.sh to add `-d ${DOCKERREPO}` to the python command. 14 | 15 | ### Behavior 16 | This shell script will 17 | 1. generate all the docker pull commands and test commands needed into files. 18 | 2. Run the same docker pull commands on all nodes 19 | 3. scp configs files to all worker nodes 20 | 4. clean up previous run results in sieve_test_results 21 | 5. Run all tests in distributed manner on the nodes 22 | e.g. if we have three jobs and 2 vms 23 | ``` 24 | 1. python3 sieve.py -p yugabyte-operator -c config-1.yaml 25 | 2. python3 sieve.py -p yugabyte-operator -c config-2.yaml 26 | 3. python3 sieve.py -p yugabyte-operator -c config-3.yaml 27 | ``` 28 | GNU parallel will distribute the jobs dynamically as 29 | ``` 30 | vm1: 31 | python3 sieve.py -p yugabyte-operator -c config-1.yaml 32 | python3 sieve.py -p yugabyte-operator -c config-3.yaml 33 | vm2: 34 | python3 sieve.py -p yugabyte-operator -c config-2.yaml 35 | ``` 36 | 6. collect run results back to master node 37 | 7. squash all the test results into one file and save it with a uniqle name under parallel_testing directory 38 | 8. Clean up kind clusters after massive testing 39 | 40 | ### Note 41 | - It assumes the sieve project home directory is under `/home/ubuntu` 42 | - CAUTION: Do not leave critical results in sieve_test_results directory. It gets cleared every time when the testrun.sh script is executed. The results are automatically saved in a summary file under parallel_testing directory after each mass testing. 43 | -------------------------------------------------------------------------------- /parallel_testing/combine_json.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import json 3 | import time 4 | import os 5 | import sys 6 | 7 | 8 | def merge(result, patch): 9 | """ 10 | Recursive function to merge two dict 11 | """ 12 | for key in patch: 13 | if key not in result: 14 | result[key] = patch[key] 15 | else: 16 | if type(patch[key]) is not dict: 17 | print("ERROR: Duplicate config, overwriting") 18 | result[key] = patch[key] 19 | else: 20 | merge(result[key], patch[key]) 21 | 22 | 23 | if __name__ == "__main__": 24 | t = time.localtime() 25 | result_folder = sys.argv[1] 26 | controller = sys.argv[2] 27 | json_names = glob.glob( 28 | os.path.join(result_folder, "sieve_test_results/{}-*.json".format(controller)) 29 | ) 30 | generated_test_plans = glob.glob( 31 | os.path.join( 32 | result_folder, 33 | controller, 34 | "*", 35 | "learn", 36 | "*", 37 | "*-test-plan-*.yaml", 38 | ) 39 | ) 40 | 41 | result = {} 42 | result["failed"] = [] 43 | for fname in json_names: 44 | with open(fname, "r") as in_json: 45 | patch = json.load(in_json) 46 | merge(result, patch) 47 | for test_plan in generated_test_plans: 48 | tokens = test_plan.split("/") 49 | workload_name = tokens[-6] 50 | expected_name = "{}-{}-{}.json".format( 51 | controller, 52 | workload_name, 53 | os.path.basename(test_plan), 54 | ) 55 | # print(test_plan) 56 | # print(expected_name) 57 | found = False 58 | for json_name in json_names: 59 | if json_name.endswith(expected_name): 60 | found = True 61 | if not found: 62 | result["failed"].append(test_plan) 63 | 64 | with open( 65 | "test-summary-{}-{}-{}-{}-{}.json".format( 66 | t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min 67 | ), 68 | "w", 69 | ) as merged: 70 | json.dump(result, merged, indent=4, sort_keys=True) 71 | -------------------------------------------------------------------------------- /parallel_testing/runlearn.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.path.append("../") 4 | 5 | import argparse 6 | import os 7 | 8 | controllers_to_run = { 9 | "cassandra-operator": ["recreate", "scaledown-scaleup"], 10 | "zookeeper-operator": ["recreate", "scaledown-scaleup"], 11 | "rabbitmq-operator": ["recreate", "scaleup-scaledown", "resize-pvc"], 12 | "mongodb-operator": [ 13 | "recreate", 14 | "scaleup-scaledown", 15 | "disable-enable-shard", 16 | "disable-enable-arbiter", 17 | "run-cert-manager", 18 | ], 19 | "cass-operator": ["recreate", "scaledown-scaleup"], 20 | "casskop-operator": ["recreate", "scaledown-to-zero", "reducepdb"], 21 | "xtradb-operator": [ 22 | "recreate", 23 | "disable-enable-haproxy", 24 | "disable-enable-proxysql", 25 | "run-cert-manager", 26 | "scaleup-scaledown", 27 | ], 28 | "yugabyte-operator": [ 29 | "recreate", 30 | "scaleup-scaledown-tserver", 31 | "disable-enable-tls", 32 | "disable-enable-tuiport", 33 | ], 34 | "nifikop-operator": ["recreate", "scaledown-scaleup", "change-config"], 35 | "elastic-operator": ["recreate", "scaledown-scaleup"], 36 | } 37 | 38 | if __name__ == "__main__": 39 | parser = argparse.ArgumentParser(description="Automate learning run.") 40 | parser.add_argument( 41 | "-r", 42 | dest="registry", 43 | help="Container registry", 44 | default="ghcr.io/sieve-project/action", 45 | ) 46 | parser.add_argument("-c", dest="controllers", help="Controllers to test", nargs="+") 47 | args = parser.parse_args() 48 | os.chdir("..") 49 | 50 | if args.controllers is None: 51 | print("No controller specified, running learning mode for all controllers") 52 | controllers = controllers_to_run.keys() 53 | else: 54 | controllers = args.controllers 55 | 56 | os.system("docker pull %s/node:learn" % args.registry) 57 | for controller in controllers: 58 | os.system("docker pull %s/%s:learn" % (args.registry, controller)) 59 | for testcase in controllers_to_run[controller]: 60 | os.system( 61 | "python3 sieve.py -m learn -c {} -w {} -r {}".format( 62 | controller, testcase, args.registry 63 | ) 64 | ) 65 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 88 3 | target-version = ['py36'] 4 | include = '\.pyi?$' 5 | exclude = ''' 6 | /( 7 | \.eggs # exclude a few common directories in the 8 | | \.git # root of the project 9 | | \.hg 10 | | \.mypy_cache 11 | | \.tox 12 | | \.venv 13 | | _build 14 | | buck-out 15 | | build 16 | | dist 17 | | fakegopath 18 | | log 19 | | app 20 | )/ 21 | ''' 22 | -------------------------------------------------------------------------------- /report_bugs.py: -------------------------------------------------------------------------------- 1 | import json 2 | import glob 3 | 4 | test_result_files = glob.glob("sieve_test_results/*.json") 5 | potential_bug_list = "" 6 | for test_result_file in test_result_files: 7 | test_result = json.load(open(test_result_file)) 8 | for controller in test_result: 9 | for test_case in test_result[controller]: 10 | for mode in test_result[controller][test_case]: 11 | for test_plan in test_result[controller][test_case][mode]: 12 | inner_result = test_result[controller][test_case][mode][test_plan] 13 | if ( 14 | inner_result["injection_completed"] 15 | and inner_result["workload_completed"] 16 | and inner_result["no_exception"] 17 | and inner_result["number_errors"] > 0 18 | ): 19 | potential_bug_list += test_result_file + "\n" 20 | 21 | print( 22 | "Please refer to the following test results for potential bugs found by Sieve\n" 23 | + potential_bug_list 24 | ) 25 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | kubernetes==12.0.1 2 | pysqlite3==0.4.6 3 | PyYAML==5.4.1 4 | py-cui==0.1.3 5 | docker==5.0.2 6 | deepdiff==5.5.0 -------------------------------------------------------------------------------- /sieve_analyzer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/sieve_analyzer/__init__.py -------------------------------------------------------------------------------- /sieve_aux/csi-driver/csi-storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-hostpath-sc 5 | provisioner: hostpath.csi.k8s.io 6 | reclaimPolicy: Delete 7 | volumeBindingMode: Immediate 8 | allowVolumeExpansion: true 9 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/README.md: -------------------------------------------------------------------------------- 1 | The deployment for Kubernetes 1.21 uses the CSI snapshotter sidecar 2 | 4.x and thus is incompatible with Kubernetes clusters where older 3 | snapshotter CRDs are installed. 4 | 5 | It uses separate pods and service accounts for each sidecar. This is 6 | not how they would normally be deployed. It gets done this way to test 7 | that the individual RBAC rules are correct. 8 | 9 | The health-monitor-agent is no longer getting deployed because its 10 | functionality was moved into kubelet in Kubernetes 1.21. 11 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/deploy.sh: -------------------------------------------------------------------------------- 1 | ../util/deploy-hostpath.sh -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/destroy.sh: -------------------------------------------------------------------------------- 1 | ../util/destroy-hostpath.sh -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-attacher.yaml: -------------------------------------------------------------------------------- 1 | kind: StatefulSet 2 | apiVersion: apps/v1 3 | metadata: 4 | name: csi-hostpath-attacher 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: csi-hostpath-attacher 9 | app.kubernetes.io/component: attacher 10 | spec: 11 | serviceName: "csi-hostpath-attacher" 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/instance: hostpath.csi.k8s.io 16 | app.kubernetes.io/part-of: csi-driver-host-path 17 | app.kubernetes.io/name: csi-hostpath-attacher 18 | app.kubernetes.io/component: attacher 19 | template: 20 | metadata: 21 | labels: 22 | app.kubernetes.io/instance: hostpath.csi.k8s.io 23 | app.kubernetes.io/part-of: csi-driver-host-path 24 | app.kubernetes.io/name: csi-hostpath-attacher 25 | app.kubernetes.io/component: attacher 26 | spec: 27 | affinity: 28 | podAffinity: 29 | requiredDuringSchedulingIgnoredDuringExecution: 30 | - labelSelector: 31 | matchExpressions: 32 | - key: app.kubernetes.io/instance 33 | operator: In 34 | values: 35 | - hostpath.csi.k8s.io 36 | topologyKey: kubernetes.io/hostname 37 | serviceAccountName: csi-attacher 38 | containers: 39 | - name: csi-attacher 40 | image: k8s.gcr.io/sig-storage/csi-attacher:v3.2.1 41 | args: 42 | - --v=5 43 | - --csi-address=/csi/csi.sock 44 | securityContext: 45 | # This is necessary only for systems with SELinux, where 46 | # non-privileged sidecar containers cannot access unix domain socket 47 | # created by privileged CSI driver container. 48 | privileged: true 49 | volumeMounts: 50 | - mountPath: /csi 51 | name: socket-dir 52 | 53 | volumes: 54 | - hostPath: 55 | path: /var/lib/kubelet/plugins/csi-hostpath 56 | type: DirectoryOrCreate 57 | name: socket-dir 58 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-driverinfo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: CSIDriver 3 | metadata: 4 | name: hostpath.csi.k8s.io 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: hostpath.csi.k8s.io 9 | app.kubernetes.io/component: csi-driver 10 | spec: 11 | # Supports persistent and ephemeral inline volumes. 12 | volumeLifecycleModes: 13 | - Persistent 14 | - Ephemeral 15 | # To determine at runtime which mode a volume uses, pod info and its 16 | # "csi.storage.k8s.io/ephemeral" entry are needed. 17 | podInfoOnMount: true 18 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-provisioner.yaml: -------------------------------------------------------------------------------- 1 | kind: StatefulSet 2 | apiVersion: apps/v1 3 | metadata: 4 | name: csi-hostpath-provisioner 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: csi-hostpath-provisioner 9 | app.kubernetes.io/component: provisioner 10 | spec: 11 | serviceName: "csi-hostpath-provisioner" 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/instance: hostpath.csi.k8s.io 16 | app.kubernetes.io/part-of: csi-driver-host-path 17 | app.kubernetes.io/name: csi-hostpath-provisioner 18 | app.kubernetes.io/component: provisioner 19 | template: 20 | metadata: 21 | labels: 22 | app.kubernetes.io/instance: hostpath.csi.k8s.io 23 | app.kubernetes.io/part-of: csi-driver-host-path 24 | app.kubernetes.io/name: csi-hostpath-provisioner 25 | app.kubernetes.io/component: provisioner 26 | spec: 27 | affinity: 28 | podAffinity: 29 | requiredDuringSchedulingIgnoredDuringExecution: 30 | - labelSelector: 31 | matchExpressions: 32 | - key: app.kubernetes.io/instance 33 | operator: In 34 | values: 35 | - hostpath.csi.k8s.io 36 | topologyKey: kubernetes.io/hostname 37 | serviceAccountName: csi-provisioner 38 | containers: 39 | - name: csi-provisioner 40 | image: k8s.gcr.io/sig-storage/csi-provisioner:v2.2.1 41 | args: 42 | - -v=5 43 | - --csi-address=/csi/csi.sock 44 | - --feature-gates=Topology=true 45 | securityContext: 46 | # This is necessary only for systems with SELinux, where 47 | # non-privileged sidecar containers cannot access unix domain socket 48 | # created by privileged CSI driver container. 49 | privileged: true 50 | volumeMounts: 51 | - mountPath: /csi 52 | name: socket-dir 53 | volumes: 54 | - hostPath: 55 | path: /var/lib/kubelet/plugins/csi-hostpath 56 | type: DirectoryOrCreate 57 | name: socket-dir 58 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-resizer.yaml: -------------------------------------------------------------------------------- 1 | kind: StatefulSet 2 | apiVersion: apps/v1 3 | metadata: 4 | name: csi-hostpath-resizer 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: csi-hostpath-resizer 9 | app.kubernetes.io/component: resizer 10 | spec: 11 | serviceName: "csi-hostpath-resizer" 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/instance: hostpath.csi.k8s.io 16 | app.kubernetes.io/part-of: csi-driver-host-path 17 | app.kubernetes.io/name: csi-hostpath-resizer 18 | app.kubernetes.io/component: resizer 19 | template: 20 | metadata: 21 | labels: 22 | app.kubernetes.io/instance: hostpath.csi.k8s.io 23 | app.kubernetes.io/part-of: csi-driver-host-path 24 | app.kubernetes.io/name: csi-hostpath-resizer 25 | app.kubernetes.io/component: resizer 26 | spec: 27 | affinity: 28 | podAffinity: 29 | requiredDuringSchedulingIgnoredDuringExecution: 30 | - labelSelector: 31 | matchExpressions: 32 | - key: app.kubernetes.io/instance 33 | operator: In 34 | values: 35 | - hostpath.csi.k8s.io 36 | topologyKey: kubernetes.io/hostname 37 | serviceAccountName: csi-resizer 38 | containers: 39 | - name: csi-resizer 40 | image: k8s.gcr.io/sig-storage/csi-resizer:v1.2.0 41 | args: 42 | - -v=5 43 | - -csi-address=/csi/csi.sock 44 | securityContext: 45 | # This is necessary only for systems with SELinux, where 46 | # non-privileged sidecar containers cannot access unix domain socket 47 | # created by privileged CSI driver container. 48 | privileged: true 49 | volumeMounts: 50 | - mountPath: /csi 51 | name: socket-dir 52 | volumes: 53 | - hostPath: 54 | path: /var/lib/kubelet/plugins/csi-hostpath 55 | type: DirectoryOrCreate 56 | name: socket-dir 57 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-snapshotclass.yaml: -------------------------------------------------------------------------------- 1 | # Usage of the v1 API implies that the cluster must have 2 | # external-snapshotter v4.x installed. 3 | apiVersion: snapshot.storage.k8s.io/v1 4 | kind: VolumeSnapshotClass 5 | metadata: 6 | name: csi-hostpath-snapclass 7 | labels: 8 | app.kubernetes.io/instance: hostpath.csi.k8s.io 9 | app.kubernetes.io/part-of: csi-driver-host-path 10 | app.kubernetes.io/name: csi-hostpath-snapclass 11 | app.kubernetes.io/component: volumesnapshotclass 12 | driver: hostpath.csi.k8s.io #csi-hostpath 13 | deletionPolicy: Delete 14 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/hostpath/csi-hostpath-snapshotter.yaml: -------------------------------------------------------------------------------- 1 | kind: StatefulSet 2 | apiVersion: apps/v1 3 | metadata: 4 | name: csi-hostpath-snapshotter 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: csi-hostpath-snapshotter 9 | app.kubernetes.io/component: snapshotter 10 | spec: 11 | serviceName: "csi-hostpath-snapshotter" 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/instance: hostpath.csi.k8s.io 16 | app.kubernetes.io/part-of: csi-driver-host-path 17 | app.kubernetes.io/name: csi-hostpath-snapshotter 18 | app.kubernetes.io/component: snapshotter 19 | template: 20 | metadata: 21 | labels: 22 | app.kubernetes.io/instance: hostpath.csi.k8s.io 23 | app.kubernetes.io/part-of: csi-driver-host-path 24 | app.kubernetes.io/name: csi-hostpath-snapshotter 25 | app.kubernetes.io/component: snapshotter 26 | spec: 27 | affinity: 28 | podAffinity: 29 | requiredDuringSchedulingIgnoredDuringExecution: 30 | - labelSelector: 31 | matchExpressions: 32 | - key: app.kubernetes.io/instance 33 | operator: In 34 | values: 35 | - hostpath.csi.k8s.io 36 | topologyKey: kubernetes.io/hostname 37 | serviceAccountName: csi-snapshotter 38 | containers: 39 | - name: csi-snapshotter 40 | image: k8s.gcr.io/sig-storage/csi-snapshotter:v4.1.1 41 | args: 42 | - -v=5 43 | - --csi-address=/csi/csi.sock 44 | securityContext: 45 | # This is necessary only for systems with SELinux, where 46 | # non-privileged sidecar containers cannot access unix domain socket 47 | # created by privileged CSI driver container. 48 | privileged: true 49 | volumeMounts: 50 | - mountPath: /csi 51 | name: socket-dir 52 | volumes: 53 | - hostPath: 54 | path: /var/lib/kubelet/plugins/csi-hostpath 55 | type: DirectoryOrCreate 56 | name: socket-dir 57 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21-test/test-driver.yaml: -------------------------------------------------------------------------------- 1 | # This file describes how to test this deployment of the CSI hostpath driver 2 | # using the Kubernetes 1.17 E2E test suite. For details see: 3 | # https://github.com/kubernetes/kubernetes/tree/v1.17.0/test/e2e/storage/external 4 | 5 | StorageClass: 6 | FromName: true 7 | SnapshotClass: 8 | FromName: true 9 | DriverInfo: 10 | Name: hostpath.csi.k8s.io 11 | SupportedSizeRange: 12 | Min: 1Mi 13 | Capabilities: 14 | block: true 15 | controllerExpansion: true 16 | exec: true 17 | multipods: true 18 | nodeExpansion: true 19 | persistence: true 20 | singleNodeVolume: true 21 | snapshotDataSource: true 22 | topology: true 23 | InlineVolumes: 24 | - shared: true 25 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/README.md: -------------------------------------------------------------------------------- 1 | The deployment for Kubernetes 1.21 uses the CSI snapshotter sidecar 2 | 4.x and thus is incompatible with Kubernetes clusters where older 3 | snapshotter CRDs are installed. 4 | 5 | The health-monitor-agent is no longer getting deployed because its 6 | functionality was moved into kubelet in Kubernetes 1.21. 7 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/deploy.sh: -------------------------------------------------------------------------------- 1 | ../util/deploy-hostpath.sh -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/destroy.sh: -------------------------------------------------------------------------------- 1 | ../util/destroy-hostpath.sh -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/hostpath/csi-hostpath-driverinfo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: CSIDriver 3 | metadata: 4 | name: hostpath.csi.k8s.io 5 | labels: 6 | app.kubernetes.io/instance: hostpath.csi.k8s.io 7 | app.kubernetes.io/part-of: csi-driver-host-path 8 | app.kubernetes.io/name: hostpath.csi.k8s.io 9 | app.kubernetes.io/component: csi-driver 10 | spec: 11 | # Supports persistent and ephemeral inline volumes. 12 | volumeLifecycleModes: 13 | - Persistent 14 | - Ephemeral 15 | # To determine at runtime which mode a volume uses, pod info and its 16 | # "csi.storage.k8s.io/ephemeral" entry are needed. 17 | podInfoOnMount: true 18 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/hostpath/csi-hostpath-snapshotclass.yaml: -------------------------------------------------------------------------------- 1 | # Usage of the v1 API implies that the cluster must have 2 | # external-snapshotter v4.x installed. 3 | apiVersion: snapshot.storage.k8s.io/v1 4 | kind: VolumeSnapshotClass 5 | metadata: 6 | name: csi-hostpath-snapclass 7 | labels: 8 | app.kubernetes.io/instance: hostpath.csi.k8s.io 9 | app.kubernetes.io/part-of: csi-driver-host-path 10 | app.kubernetes.io/name: csi-hostpath-snapclass 11 | app.kubernetes.io/component: volumesnapshotclass 12 | driver: hostpath.csi.k8s.io #csi-hostpath 13 | deletionPolicy: Delete 14 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-1.21/test-driver.yaml: -------------------------------------------------------------------------------- 1 | # This file describes how to test this deployment of the CSI hostpath driver 2 | # using the Kubernetes 1.17 E2E test suite. For details see: 3 | # https://github.com/kubernetes/kubernetes/tree/v1.17.0/test/e2e/storage/external 4 | 5 | StorageClass: 6 | FromName: true 7 | SnapshotClass: 8 | FromName: true 9 | DriverInfo: 10 | Name: hostpath.csi.k8s.io 11 | SupportedSizeRange: 12 | Min: 1Mi 13 | Capabilities: 14 | block: true 15 | controllerExpansion: true 16 | exec: true 17 | multipods: true 18 | nodeExpansion: true 19 | persistence: true 20 | singleNodeVolume: true 21 | snapshotDataSource: true 22 | topology: true 23 | InlineVolumes: 24 | - shared: true 25 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-latest: -------------------------------------------------------------------------------- 1 | kubernetes-1.21 -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/kubernetes-latest-test: -------------------------------------------------------------------------------- 1 | kubernetes-1.21-test -------------------------------------------------------------------------------- /sieve_aux/csi-driver/deploy/util/destroy-hostpath.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2021 The Kubernetes Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This script performs the step to destroy the hostpath plugin driver 17 | # completely by checking all the resources. 18 | # This should be in sync with the deploy script based on any future additions/deletions 19 | # of the resources 20 | 21 | # The script assumes that kubectl is available on the OS path 22 | # where it is executed. 23 | 24 | set -e 25 | set -o pipefail 26 | 27 | # Deleting all the resources installed by the deploy-script as the part of csi-hostpath-driver. 28 | # Every resource in the driver installation has the label representing the installation instance. 29 | # Using app.kubernetes.io/instance: hostpath.csi.k8s.io and app.kubernetes.io/part-of: csi-driver-host-path labels to identify the installation set 30 | # 31 | # kubectl maintains a few standard resources under "all" category which can be deleted by using just "kubectl delete all" 32 | # and other resources such as roles, clusterrole, serivceaccount etc needs to be deleted explicitly 33 | kubectl delete all --all-namespaces -l app.kubernetes.io/instance=hostpath.csi.k8s.io,app.kubernetes.io/part-of=csi-driver-host-path --wait=true 34 | kubectl delete role,clusterrole,rolebinding,clusterrolebinding,serviceaccount,storageclass,csidriver --all-namespaces -l app.kubernetes.io/instance=hostpath.csi.k8s.io,app.kubernetes.io/part-of=csi-driver-host-path --wait=true 35 | -------------------------------------------------------------------------------- /sieve_aux/csi-driver/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SNAPSHOTTER_VERSION=v2.0.1 4 | 5 | # Install VolumeSnapshot CRD 6 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml 7 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml 8 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml 9 | 10 | # Create snapshot controller 11 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml 12 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml 13 | 14 | # Check for install 15 | kubectl get volumesnapshotclasses.snapshot.storage.k8s.io 16 | kubectl get volumesnapshots.snapshot.storage.k8s.io 17 | kubectl get volumesnapshotcontents.snapshot.storage.k8s.io 18 | 19 | # Deploy 20 | ./deploy/kubernetes-latest/deploy.sh 21 | 22 | # Check for pod 23 | kubectl get pods 24 | 25 | sleep 60s 26 | 27 | kubectl get pods 28 | 29 | kubectl apply -f csi-storageclass.yaml 30 | 31 | sleep 10s 32 | 33 | # Change default storage class 34 | kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' 35 | kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' 36 | 37 | kubectl get storageclass 38 | -------------------------------------------------------------------------------- /sieve_client/go.mod: -------------------------------------------------------------------------------- 1 | module sieve.client 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/stretchr/testify v1.7.0 7 | gopkg.in/yaml.v2 v2.4.0 8 | k8s.io/apimachinery v0.18.9 9 | ) 10 | -------------------------------------------------------------------------------- /sieve_common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/sieve_common/__init__.py -------------------------------------------------------------------------------- /sieve_instrumentation/go.mod: -------------------------------------------------------------------------------- 1 | module instrumentation 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/dave/dst v0.27.2 7 | github.com/kr/pretty v0.3.1 // indirect 8 | github.com/stretchr/testify v1.8.1 // indirect 9 | golang.org/x/tools v0.4.0 // indirect 10 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /sieve_oracle/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/sieve_oracle/__init__.py -------------------------------------------------------------------------------- /sieve_oracle/customized_safety_checker.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | 4 | class SafetyCheckerSuite: 5 | def __init__(self, resource_keys, checker_name, checker_function): 6 | self.resource_keys = resource_keys 7 | self.checker_name = checker_name 8 | self.checker_function = checker_function 9 | 10 | 11 | # Customized safety checker example: 12 | # This checker checks a safety property: 13 | # The rabbitmq-cluster-server statefulset should never have more than one replica 14 | # (the property is not correct; this is just an example) 15 | # Sieve will apply this checker to every state 16 | # As long as there is one state where the property does not hold (return false in the function) 17 | # Sieve will report an alarm 18 | def example_rabbitmq_safety_checker(state): 19 | key = "statefulset/default/rabbitmq-cluster-server" 20 | if key in state: 21 | object_state = json.loads(state[key]) 22 | if object_state["Spec"]["Replicas"] > 1: 23 | return False 24 | return True 25 | 26 | 27 | # This is another example that is similar to the checker mentioned in 28 | # https://github.com/sieve-project/sieve/issues/42 29 | def example_foo_safety_checker(state): 30 | key1 = "statefulset/default/sts1" 31 | key2 = "statefulset/default/sts2" 32 | ratio = 0.7 33 | if key1 in state and key2 in state: 34 | object_state1 = json.loads(state[key1]) 35 | object_state2 = json.loads(state[key2]) 36 | if ( 37 | object_state1["Spec"]["Replicas"] * ratio 38 | < object_state2["Spec"]["Replicas"] 39 | ): 40 | return False 41 | return True 42 | 43 | 44 | # Users can specify customized safety checker by adding SafetyCheckerSuite here 45 | # Each SafetyCheckerSuite has three elements: 46 | # 1. the list of resources to check, here there is only one resource to check: statefulset/default/rabbitmq-cluster-server 47 | # 2. the checker's name 48 | # 3. the checker function 49 | customized_safety_checker_suites = [ 50 | # SafetyCheckerSuite( 51 | # ["statefulset/default/rabbitmq-cluster-server"], 52 | # "example_checker", 53 | # example_rabbitmq_safety_checker, 54 | # ) 55 | ] 56 | -------------------------------------------------------------------------------- /sieve_perturbation_policies/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/sieve_perturbation_policies/__init__.py -------------------------------------------------------------------------------- /sieve_server/expression.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "log" 4 | 5 | func reverse(tokens []string) { 6 | for i, j := 0, len(tokens)-1; i < j; i, j = i+1, j-1 { 7 | tokens[i], tokens[j] = tokens[j], tokens[i] 8 | } 9 | } 10 | 11 | func isOperator(text string) bool { 12 | return text == ";" || text == "&" || text == "|" || text == "(" || text == ")" 13 | } 14 | 15 | func priority(text string) int { 16 | if text == ";" { 17 | return 1 18 | } else if text == "|" { 19 | return 2 20 | } else if text == "&" { 21 | return 3 22 | } else if text == "(" { 23 | return 0 24 | } else if text == ")" { 25 | return 0 26 | } 27 | log.Fatalf("invalid operator %s\n", text) 28 | return -1 29 | } 30 | 31 | func expressionToInfixTokens(exp string) []string { 32 | tokens := []string{} 33 | currentToken := "" 34 | for _, c := range exp { 35 | if isOperator(string(c)) { 36 | if currentToken != "" { 37 | tokens = append(tokens, currentToken) 38 | currentToken = "" 39 | } 40 | tokens = append(tokens, string(c)) 41 | } else { 42 | currentToken = currentToken + string(c) 43 | } 44 | } 45 | tokens = append(tokens, currentToken) 46 | return tokens 47 | } 48 | 49 | func infixToPostfix(infix []string) []string { 50 | tokenStack := NewStack() 51 | postfix := []string{} 52 | for _, token := range infix { 53 | if !isOperator(token) { 54 | postfix = append(postfix, token) 55 | } else if token == "(" { 56 | tokenStack.Push(token) 57 | } else if token == ")" { 58 | for tokenStack.Top() != "(" { 59 | postfix = append(postfix, tokenStack.Pop()) 60 | } 61 | tokenStack.Pop() 62 | } else { 63 | for !tokenStack.Empty() && priority(token) < priority(tokenStack.Top()) { 64 | postfix = append(postfix, tokenStack.Pop()) 65 | } 66 | tokenStack.Push(token) 67 | } 68 | } 69 | for !tokenStack.Empty() { 70 | postfix = append(postfix, tokenStack.Pop()) 71 | } 72 | return postfix 73 | } 74 | 75 | func infixToPrefix(infix []string) []string { 76 | reverse(infix) 77 | infixLen := len(infix) 78 | for i := 0; i < infixLen; i++ { 79 | if infix[i] == "(" { 80 | infix[i] = ")" 81 | } else if infix[i] == ")" { 82 | infix[i] = "(" 83 | } 84 | } 85 | prefix := infixToPostfix(infix) 86 | reverse(prefix) 87 | return prefix 88 | } 89 | -------------------------------------------------------------------------------- /sieve_server/go.mod: -------------------------------------------------------------------------------- 1 | module sieve-server 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/imdario/mergo v0.3.11 // indirect 7 | golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect 8 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 // indirect 9 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect 10 | gopkg.in/yaml.v2 v2.4.0 11 | k8s.io/api v0.18.9 12 | k8s.io/apimachinery v0.18.9 13 | k8s.io/client-go v0.18.9 14 | sieve.client v0.0.0 15 | ) 16 | 17 | replace sieve.client => ../sieve_client 18 | -------------------------------------------------------------------------------- /sieve_server/notification.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type TriggerNotification interface { 4 | getBlockingCh() chan string 5 | } 6 | 7 | type TimeoutNotification struct { 8 | conditionName string 9 | } 10 | 11 | func (n *TimeoutNotification) getBlockingCh() chan string { 12 | return nil 13 | } 14 | 15 | type AnnotatedAPICallNotification struct { 16 | module string 17 | filePath string 18 | receiverType string 19 | funName string 20 | observedWhen string 21 | observedBy string 22 | blockingCh chan string 23 | } 24 | 25 | func (n *AnnotatedAPICallNotification) getBlockingCh() chan string { 26 | return n.blockingCh 27 | } 28 | 29 | type ObjectCreateNotification struct { 30 | resourceKey string 31 | observedWhen string 32 | observedBy string 33 | blockingCh chan string 34 | } 35 | 36 | func (n *ObjectCreateNotification) getBlockingCh() chan string { 37 | return n.blockingCh 38 | } 39 | 40 | type ObjectDeleteNotification struct { 41 | resourceKey string 42 | observedWhen string 43 | observedBy string 44 | blockingCh chan string 45 | } 46 | 47 | func (n *ObjectDeleteNotification) getBlockingCh() chan string { 48 | return n.blockingCh 49 | } 50 | 51 | type ObjectUpdateNotification struct { 52 | resourceKey string 53 | observedWhen string 54 | observedBy string 55 | prevState map[string]interface{} 56 | curState map[string]interface{} 57 | fieldKeyMask map[string]struct{} 58 | fieldPathMask map[string]struct{} 59 | fieldKeyMaskAPIForm map[string]struct{} 60 | fieldPathMaskAPIForm map[string]struct{} 61 | blockingCh chan string 62 | } 63 | 64 | func (n *ObjectUpdateNotification) getBlockingCh() chan string { 65 | return n.blockingCh 66 | } 67 | 68 | type AsyncDoneNotification struct { 69 | } 70 | -------------------------------------------------------------------------------- /sieve_server/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | "net/rpc" 7 | "os" 8 | 9 | sieve "sieve.client" 10 | ) 11 | 12 | // Sieve server runs on one of the kind-control-plane node (not in the pod). 13 | // The server reads the config `server.yaml` and decides which listener to use. 14 | // The listener will handle the RPC from sieve client (called by controllers or k8s components). 15 | func main() { 16 | log.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds) 17 | log.Println("registering rpc server...") 18 | args := os.Args 19 | phase := args[1] 20 | switch phase { 21 | case sieve.LEARN: 22 | rpc.Register(NewLearnListener()) 23 | case sieve.TEST: 24 | rpc.Register(NewTestCoordinator()) 25 | default: 26 | log.Fatalf("Cannot recognize mode: %s\n", phase) 27 | } 28 | log.Println("setting up connection...") 29 | addr, err := net.ResolveTCPAddr("tcp", ":12345") 30 | checkError(err) 31 | inbound, err := net.ListenTCP("tcp", addr) 32 | checkError(err) 33 | rpc.Accept(inbound) 34 | } 35 | -------------------------------------------------------------------------------- /sieve_server/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Stack struct { 4 | elements []string 5 | topPtr int 6 | } 7 | 8 | func NewStack() *Stack { 9 | return &Stack{ 10 | elements: []string{}, 11 | topPtr: -1, 12 | } 13 | } 14 | 15 | func (s *Stack) Empty() bool { 16 | return s.topPtr == -1 17 | } 18 | 19 | func (s *Stack) Top() string { 20 | return s.elements[s.topPtr] 21 | } 22 | 23 | func (s *Stack) Push(element string) { 24 | if len(s.elements) > s.topPtr+1 { 25 | s.elements[s.topPtr+1] = element 26 | } else { 27 | s.elements = append(s.elements, element) 28 | } 29 | s.topPtr += 1 30 | } 31 | 32 | func (s *Stack) Pop() string { 33 | ret := s.elements[s.topPtr] 34 | s.topPtr -= 1 35 | return ret 36 | } 37 | -------------------------------------------------------------------------------- /sieve_test_driver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieve-project/sieve/763cd38e3305e7e3ad2a4bef67e812d141bdf8e8/sieve_test_driver/__init__.py -------------------------------------------------------------------------------- /start_porting.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import json 4 | from sieve_common.config import * 5 | 6 | port_folder = sys.argv[1] 7 | build_folder = os.path.join(port_folder, "build") 8 | deploy_folder = os.path.join(port_folder, "deploy") 9 | test_folder = os.path.join(port_folder, "test") 10 | oracle_folder = os.path.join(port_folder, "oracle") 11 | 12 | os.makedirs(port_folder, exist_ok=True) 13 | os.makedirs(build_folder, exist_ok=True) 14 | os.makedirs(deploy_folder, exist_ok=True) 15 | os.makedirs(test_folder, exist_ok=True) 16 | os.makedirs(oracle_folder, exist_ok=True) 17 | 18 | build_script = os.path.join(build_folder, "build.sh") 19 | deploy_script = os.path.join(deploy_folder, "deploy.sh") 20 | f = open(build_script, "w") 21 | f.write("#!/bin/bash\n") 22 | f.close() 23 | f = open(deploy_script, "w") 24 | f.write("#!/bin/bash\n") 25 | f.close() 26 | os.system("chmod +x " + build_script) 27 | os.system("chmod +x " + deploy_script) 28 | 29 | config_json = os.path.join(port_folder, "config.json") 30 | controller_config_map = { 31 | "name": "", 32 | "github_link": "", 33 | "commit": "", 34 | "kubernetes_version": "", 35 | "client_go_version": "", 36 | "dockerfile_path": "", 37 | "controller_image_name": "", 38 | "annotated_reconcile_functions": {}, 39 | "test_command": "", 40 | "custom_resource_definitions": [], 41 | "controller_pod_label": "", 42 | "controller_deployment_file_path": "", 43 | } 44 | json.dump(controller_config_map, open(config_json, "w"), indent=4) 45 | --------------------------------------------------------------------------------