Skip to content

Commit

Permalink
controllers: support disposeDevDB flag (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
datdao authored Sep 18, 2023
1 parent 61e88e9 commit c4334e5
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 5 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ jobs:
# Expect the new column to be present.
kubectl exec $POD_MYSQL -- mysql -uroot -h 127.0.0.1 -ppass -e "SHOW COLUMNS FROM myapp.users LIKE 'phone';"
# Expect the devdb deployment is scaled to 1.
kubectl get deployment atlasschema-mysql-atlas-dev-db -o=jsonpath='{.spec.replicas}' | grep -q '1'
# SET PREWARM_DEVDB to true
kubectl set env -n atlas-operator-system deployment/atlas-operator-controller-manager PREWARM_DEVDB=false
# Reset database resources
kubectl delete pods -l app=mysql
kubectl wait --for condition=ready pods -l app=mysql --timeout=60s
# Apply the desired schema and wait for it to be ready.
kubectl delete -f config/integration/schema
kubectl apply -f config/integration/schema
kubectl wait --for=condition=ready --timeout=120s atlasschemas --all
# Expect the devdb deployment is scaled to 0.
kubectl get deployment atlasschema-mysql-atlas-dev-db -o=jsonpath='{.spec.replicas}' | grep -q '0'
- name: Reset database resources
run: |
kubectl delete pods -l app=mysql
Expand Down
5 changes: 5 additions & 0 deletions charts/atlas-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ spec:
{{- toYaml .Values.resources | nindent 12 }}
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
env:
{{- if .Values.prewarmDevDB }}
- name: PREWARM_DEVDB
value: "true"
{{- end }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
Expand Down
4 changes: 4 additions & 0 deletions charts/atlas-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ nodeSelector: {}
tolerations: []

affinity: {}

# By default, the operator will recreate devdb pods after migration
# Set this to true to keep the devdb pods around.
prewarmDevDB: true
4 changes: 3 additions & 1 deletion controllers/atlasschema_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type (
configMapWatcher *watch.ResourceWatcher
secretWatcher *watch.ResourceWatcher
recorder record.EventRecorder
prewarmDevDB bool
}
// managedData contains information about the managed database and its desired state.
managedData struct {
Expand All @@ -73,14 +74,15 @@ type (
}
)

func NewAtlasSchemaReconciler(mgr Manager, execPath string) *AtlasSchemaReconciler {
func NewAtlasSchemaReconciler(mgr Manager, execPath string, prewarmDevDB bool) *AtlasSchemaReconciler {
return &AtlasSchemaReconciler{
Client: mgr.GetClient(),
scheme: mgr.GetScheme(),
execPath: execPath,
configMapWatcher: watch.New(),
secretWatcher: watch.New(),
recorder: mgr.GetEventRecorderFor("atlasschema-controller"),
prewarmDevDB: prewarmDevDB,
}
}

Expand Down
5 changes: 4 additions & 1 deletion controllers/atlasschema_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

const (
Expand Down Expand Up @@ -109,7 +110,9 @@ func TestReconcile_Reconcile(t *testing.T) {
ObjectMeta: meta,
Spec: dbv1alpha1.AtlasSchemaSpec{},
}
h, reconcile := newRunner(NewAtlasSchemaReconciler, func(cb *fake.ClientBuilder) {
h, reconcile := newRunner(func(mgr Manager, name string) reconcile.Reconciler {
return NewAtlasSchemaReconciler(mgr, name, true)
}, func(cb *fake.ClientBuilder) {
cb.WithObjects(obj)
})
assert := func(except ctrl.Result, ready bool, reason, msg string) {
Expand Down
31 changes: 29 additions & 2 deletions controllers/devdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ const (

// cleanUp clean up any resources created by the controller
func (r *AtlasSchemaReconciler) cleanUp(ctx context.Context, sc *dbv1alpha1.AtlasSchema) {
// If prewarmDevDB is false, scale down the deployment to 0
if !r.prewarmDevDB {
deploy := &appsv1.Deployment{}
key := nameDevDB(sc.ObjectMeta)
err := r.Get(ctx, key, deploy)
if err != nil {
r.recorder.Eventf(sc, corev1.EventTypeWarning, "CleanUpDevDB", "Error getting devDB deployment: %v", err)
return
}
deploy.Spec.Replicas = new(int32)
if err := r.Update(ctx, deploy); err != nil {
r.recorder.Eventf(sc, corev1.EventTypeWarning, "CleanUpDevDB", "Error scaling down devDB deployment: %v", err)
}
return
}

// delete pods to clean up
pods := &corev1.PodList{}
err := r.List(ctx, pods, client.MatchingLabels(map[string]string{
labelInstance: nameDevDB(sc.ObjectMeta).Name,
Expand All @@ -69,10 +86,20 @@ func (r *AtlasSchemaReconciler) devURL(ctx context.Context, sc *dbv1alpha1.Atlas
}
// make sure we have a dev db running
key := nameDevDB(sc.ObjectMeta)
switch err := r.Get(ctx, key, &appsv1.Deployment{}); {
deploy := &appsv1.Deployment{}
switch err := r.Get(ctx, key, deploy); {
case err == nil:
// The dev database already exists,
// return the connection string.
// If it is scaled down, scale it up.
if deploy.Spec.Replicas == nil || *deploy.Spec.Replicas == 0 {
*deploy.Spec.Replicas = int32(1)
if err := r.Update(ctx, deploy); err != nil {
return "", transient(err)
}
r.recorder.Eventf(sc, corev1.EventTypeNormal, "ScaledUpDevDB", "Scaled up dev database deployment: %s", deploy.Name)
return "", transientAfter(errors.New("waiting for dev database to be ready"), 15*time.Second)
}

case apierrors.IsNotFound(err):
// The dev database does not exist, create it.
deploy, err := deploymentDevDB(key, drv, isSchemaBound(drv, &targetURL))
Expand Down
21 changes: 20 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"bytes"
"flag"
"os"
"strconv"
"time"

"golang.org/x/mod/semver"
Expand Down Expand Up @@ -53,6 +54,8 @@ const (
envNoUpdate = "SKIP_VERCHECK"
vercheckURL = "https://vercheck.ariga.io"
execPath = "/atlas"
// prewarmDevDB when disabled it deletes the devDB pods after the schema is created
prewarmDevDB = "PREWARM_DEVDB"
)

func init() {
Expand Down Expand Up @@ -91,7 +94,8 @@ func main() {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
if err = controllers.NewAtlasSchemaReconciler(mgr, execPath).
prewarmDevDB := getPrewarmDevDBEnv()
if err = controllers.NewAtlasSchemaReconciler(mgr, execPath, prewarmDevDB).
SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "AtlasSchema")
os.Exit(1)
Expand Down Expand Up @@ -154,3 +158,18 @@ func checkForUpdate() {
<-time.After(24 * time.Hour)
}
}

// getPrewarmDevDBEnv returns the value of the env var PREWARM_DEVDB.
// if the env var is not set, it returns true.
func getPrewarmDevDBEnv() bool {
env := os.Getenv(prewarmDevDB)
if env == "" {
return true
}
prewarmDevDB, err := strconv.ParseBool(env)
if err != nil {
setupLog.Error(err, "invalid value for env var PREWARM_DEVDB, expected true or false")
os.Exit(1)
}
return prewarmDevDB
}

0 comments on commit c4334e5

Please sign in to comment.