From 599ced00187c841b77cecb5d1064de53e24efa7c Mon Sep 17 00:00:00 2001 From: Konstantinos Samaras-Tsakiris <ksamtsak@gmail.com> Date: Sun, 28 Nov 2021 22:00:32 +0100 Subject: [PATCH 1/4] Fix install job creation --- controllers/drupalsite_controller.go | 36 +++++++++++++--------------- controllers/drupalsite_resources.go | 18 ++++++++------ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/controllers/drupalsite_controller.go b/controllers/drupalsite_controller.go index b518eeae..43605aa9 100644 --- a/controllers/drupalsite_controller.go +++ b/controllers/drupalsite_controller.go @@ -270,7 +270,11 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Check if the site is installed or cloned and mark the condition if !drupalSite.ConditionTrue("Initialized") { - if r.isDrupalSiteInstalled(ctx, drupalSite) || r.isCloneJobCompleted(ctx, drupalSite) { + installed, err := r.isDrupalSiteInstalled(ctx, drupalSite) + if err != nil { + // Initialized? Unknown + update = setConditionStatus(drupalSite, "Initialized", false, err, true) || update + } else if installed { update = setInitialized(drupalSite) || update } else { update = setNotInitialized(drupalSite) || update @@ -429,19 +433,6 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request) // business logic -// isInstallJobCompleted checks if the drush job is successfully completed -func (r *DrupalSiteReconciler) isInstallJobCompleted(ctx context.Context, d *webservicesv1a1.DrupalSite) bool { - found := &batchv1.Job{} - jobObject := &batchv1.Job{ObjectMeta: metav1.ObjectMeta{Name: "install-" + d.Name, Namespace: d.Namespace}} - err := r.Get(ctx, types.NamespacedName{Name: jobObject.Name, Namespace: jobObject.Namespace}, found) - if err == nil { - if found.Status.Succeeded != 0 { - return true - } - } - return false -} - // isCloneJobCompleted checks if the clone job is successfully completed func (r *DrupalSiteReconciler) isCloneJobCompleted(ctx context.Context, d *webservicesv1a1.DrupalSite) bool { cloneJob := &batchv1.Job{} @@ -467,14 +458,21 @@ func (r *DrupalSiteReconciler) isDrupalSiteReady(ctx context.Context, d *webserv } // isDrupalSiteInstalled checks if the drupal site is initialized by running drush status command in the PHP pod -func (r *DrupalSiteReconciler) isDrupalSiteInstalled(ctx context.Context, d *webservicesv1a1.DrupalSite) bool { +func (r *DrupalSiteReconciler) isDrupalSiteInstalled(ctx context.Context, d *webservicesv1a1.DrupalSite) (bool, reconcileError) { if r.isDrupalSiteReady(ctx, d) { - if _, err := r.execToServerPodErrOnStderr(ctx, d, "php-fpm", nil, checkIfSiteIsInstalled()...); err != nil { - return false + _, stderr, err := r.execToServerPod(ctx, d, "php-fpm", nil, checkIfSiteIsInstalled()...) + // Error running exec => condition unknown + if err != nil { + return false, newApplicationError(err, ErrClientK8s) } - return true + // The script executed and returned this error message + // TODO: check error code instead of message! + if stderr == "Drupal is not installed" { + return false, nil + } + return true, nil } - return false + return false, nil } // isDBODProvisioned checks if the DBOD has been provisioned by checking the status of DBOD custom resource diff --git a/controllers/drupalsite_resources.go b/controllers/drupalsite_resources.go index 78908e3a..85b5c831 100644 --- a/controllers/drupalsite_resources.go +++ b/controllers/drupalsite_resources.go @@ -247,13 +247,17 @@ func (r *DrupalSiteReconciler) ensureResources(drp *webservicesv1a1.DrupalSite, transientErrs = append(transientErrs, transientErr.Wrap("%v: for Nginx SVC")) } if r.isDBODProvisioned(ctx, drp) { - if drp.Spec.Configuration.CloneFrom == "" { - if transientErr := r.ensureResourceX(ctx, drp, "site_install_job", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for site install Job")) - } - } else { - if transientErr := r.ensureResourceX(ctx, drp, "clone_job", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for clone Job")) + // Important check to confirm that the site isn't initialized already, + // before creating an install/clone job! + if !drp.ConditionTrue("Initialized") { + if drp.Spec.Configuration.CloneFrom == "" { + if transientErr := r.ensureResourceX(ctx, drp, "site_install_job", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for site install Job")) + } + } else { + if transientErr := r.ensureResourceX(ctx, drp, "clone_job", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for clone Job")) + } } } } -- GitLab From aba9c7e2e065120096d602274a3dda5f5e1145db Mon Sep 17 00:00:00 2001 From: Konstantinos Samaras-Tsakiris <ksamtsak@gmail.com> Date: Sun, 28 Nov 2021 22:06:33 +0100 Subject: [PATCH 2/4] Take into account condition being unknown --- api/v1alpha1/drupalsite_types.go | 6 ++++++ controllers/drupalsite_resources.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/drupalsite_types.go b/api/v1alpha1/drupalsite_types.go index 638b6344..28ac475a 100644 --- a/api/v1alpha1/drupalsite_types.go +++ b/api/v1alpha1/drupalsite_types.go @@ -211,6 +211,12 @@ func (drp DrupalSite) ConditionTrue(condition status.ConditionType) (update bool return init != nil && init.Status == v1.ConditionTrue } +// ConditionFalse reports if the condition is false +func (drp DrupalSite) ConditionFalse(condition status.ConditionType) (update bool) { + init := drp.Status.Conditions.GetCondition(condition) + return init != nil && init.Status == v1.ConditionFalse +} + // ConditionReasonSet reports if the condition Reason is not empty func (drp DrupalSite) ConditionReasonSet(condition status.ConditionType) (update bool) { init := drp.Status.Conditions.GetCondition(condition) diff --git a/controllers/drupalsite_resources.go b/controllers/drupalsite_resources.go index 85b5c831..9376679b 100644 --- a/controllers/drupalsite_resources.go +++ b/controllers/drupalsite_resources.go @@ -249,7 +249,7 @@ func (r *DrupalSiteReconciler) ensureResources(drp *webservicesv1a1.DrupalSite, if r.isDBODProvisioned(ctx, drp) { // Important check to confirm that the site isn't initialized already, // before creating an install/clone job! - if !drp.ConditionTrue("Initialized") { + if drp.ConditionFalse("Initialized") { if drp.Spec.Configuration.CloneFrom == "" { if transientErr := r.ensureResourceX(ctx, drp, "site_install_job", log); transientErr != nil { transientErrs = append(transientErrs, transientErr.Wrap("%v: for site install Job")) -- GitLab From f36361c840fe457d225d14c23cc0624cc9b61597 Mon Sep 17 00:00:00 2001 From: Konstantinos Samaras-Tsakiris <ksamtsak@gmail.com> Date: Sun, 28 Nov 2021 22:36:07 +0100 Subject: [PATCH 3/4] Make QoS class name 'eco' --- api/v1alpha1/drupalsite_types.go | 2 +- config/crd/bases/drupal.webservices.cern.ch_drupalsites.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/drupalsite_types.go b/api/v1alpha1/drupalsite_types.go index 28ac475a..ae755f23 100644 --- a/api/v1alpha1/drupalsite_types.go +++ b/api/v1alpha1/drupalsite_types.go @@ -75,7 +75,7 @@ type Configuration struct { // TODO: support branches https://gitlab.cern.ch/drupal/paas/drupalsite-operator/-/issues/28 // QoSClass specifies the website's performance and availability requirements. The default value is "standard". - // +kubebuilder:validation:Enum:=critical;test;standard + // +kubebuilder:validation:Enum:=critical;eco;standard // +kubebuilder:default=standard // +optional QoSClass `json:"qosClass,omitempty"` diff --git a/config/crd/bases/drupal.webservices.cern.ch_drupalsites.yaml b/config/crd/bases/drupal.webservices.cern.ch_drupalsites.yaml index b4ab1ba0..2e9d0210 100644 --- a/config/crd/bases/drupal.webservices.cern.ch_drupalsites.yaml +++ b/config/crd/bases/drupal.webservices.cern.ch_drupalsites.yaml @@ -82,7 +82,7 @@ spec: availability requirements. The default value is "standard". enum: - critical - - test + - eco - standard type: string webDAVPassword: -- GitLab From e04d6e0de6d224f6e938f8dba7f48dcf71342c6a Mon Sep 17 00:00:00 2001 From: Konstantinos Samaras-Tsakiris <konstantinos.samaras-tsakiris@cern.ch> Date: Sun, 28 Nov 2021 23:07:20 +0100 Subject: [PATCH 4/4] Apply 3 suggestion(s) to 1 file(s) --- controllers/drupalsite_controller.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/drupalsite_controller.go b/controllers/drupalsite_controller.go index 43605aa9..21fcf1a1 100644 --- a/controllers/drupalsite_controller.go +++ b/controllers/drupalsite_controller.go @@ -273,7 +273,7 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request) installed, err := r.isDrupalSiteInstalled(ctx, drupalSite) if err != nil { // Initialized? Unknown - update = setConditionStatus(drupalSite, "Initialized", false, err, true) || update + update = setConditionStatus(drupalSite, "Initialized", true, err, true) || update } else if installed { update = setInitialized(drupalSite) || update } else { @@ -463,7 +463,7 @@ func (r *DrupalSiteReconciler) isDrupalSiteInstalled(ctx context.Context, d *web _, stderr, err := r.execToServerPod(ctx, d, "php-fpm", nil, checkIfSiteIsInstalled()...) // Error running exec => condition unknown if err != nil { - return false, newApplicationError(err, ErrClientK8s) + return true, newApplicationError(err, ErrClientK8s) } // The script executed and returned this error message // TODO: check error code instead of message! @@ -472,7 +472,7 @@ func (r *DrupalSiteReconciler) isDrupalSiteInstalled(ctx context.Context, d *web } return true, nil } - return false, nil + return true, newApplicationError(fmt.Errorf("Can't check install status"), ErrTemporary) } // isDBODProvisioned checks if the DBOD has been provisioned by checking the status of DBOD custom resource -- GitLab