diff --git a/controllers/drupalsite_controller.go b/controllers/drupalsite_controller.go
index e6b3f358969a88bb5f27564cec0b827a1e4fc30c..cbcf37175d380a1f9ba17f333d3a803987ce4bf3 100644
--- a/controllers/drupalsite_controller.go
+++ b/controllers/drupalsite_controller.go
@@ -138,8 +138,12 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request)
 		return ctrl.Result{}, nil
 	}
 
-	handleTransientErr := func(transientErr reconcileError, logstrFmt string) (reconcile.Result, error) {
-		setNotReady(drupalSite, transientErr)
+	handleTransientErr := func(transientErr reconcileError, logstrFmt string, status string) (reconcile.Result, error) {
+		if status == "Ready" {
+			setConditionStatus(drupalSite, "Ready", false, transientErr, false)
+		} else if status == "UpdateNeeded" {
+			setConditionStatus(drupalSite, "UpdateNeeded", false, transientErr, false)
+		}
 		r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
 		if transientErr.Temporary() {
 			log.Error(transientErr, fmt.Sprintf(logstrFmt, transientErr.Unwrap()))
@@ -180,10 +184,11 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request)
 
 	// TODO simplify logic by splitting into 2
 	// Condition `UpdateNeeded` <- either image not matching `drupalVersion` or `drush updb` needed
-	if updateNeeded, err := r.updateNeeded(ctx, drupalSite); err != nil || updateNeeded {
-		if err != nil {
+	updateNeeded, typeUpdate, reconcileErr := r.updateNeeded(ctx, drupalSite)
+	if reconcileErr != nil || updateNeeded {
+		if reconcileErr != nil {
 			// Do not return in this case, but continue the reconciliation
-			update = setConditionStatus(drupalSite, "UpdateNeeded", true, err, true) || update
+			update = setConditionStatus(drupalSite, "UpdateNeeded", true, reconcileErr, true) || update
 		} else {
 			update = setConditionStatus(drupalSite, "UpdateNeeded", true, nil, false) || update
 		}
@@ -202,75 +207,74 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request)
 	if transientErrs := r.ensureResources(drupalSite, log); transientErrs != nil {
 		transientErr := concat(transientErrs)
 		setNotReady(drupalSite, transientErr)
-		return handleTransientErr(transientErr, "%v while ensuring the resources")
-	}
-
-	// If an update process is marked, then put the site in maintenance mode, and if not, take it off maintenance
-	if drupalSite.ConditionTrue("CodeUpdating") || drupalSite.ConditionTrue("DBUpdating") {
-		if _, err := r.execToServerPodErrOnStderr(ctx, drupalSite, "php-fpm", nil, enableSiteMaintenanceModeCommandForDrupalSite()...); err != nil {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
-	} else {
-		if _, err := r.execToServerPodErrOnStderr(ctx, drupalSite, "php-fpm", nil, disableSiteMaintenanceModeCommandForDrupalSite()...); err != nil {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
+		return handleTransientErr(transientErr, "%v while ensuring the resources", "Ready")
 	}
 
-	// Set "CodeUpdating" and perform code update
+	// Set "UpdateNeeded" and perform code update
 	// 1. set the Status.previousDrupalVersion
 	// 2. wait for Builds to be ready
-	// 3. set condition "CodeUpdating":=True
-	// 4. ensure updated deployment
-	// 5. set condition "CodeUpdating":=False
-	if drupalSite.ConditionTrue("UpdateNeeded") && !drupalSite.ConditionReasonSet("CodeUpdating") {
+	// 3. ensure updated deployment
+	// 4. set condition "CodeUpdatingFailed" to true if there is an unrecoverable error & rollback
 
+	if drupalSite.ConditionTrue("UpdateNeeded") && typeUpdate == "CodeUpdate" {
 		// wait for Builds to succeed
 		if err := r.checkBuildstatusForUpdate(ctx, drupalSite); err != nil {
 			if err.Temporary() {
-				return handleTransientErr(err, "%v while building images for the new Drupal version")
+				// try to reconcile after a few seconds like half a minute or so
+				return handleTransientErr(err, "%v while building images for the new Drupal version", "UpdateNeeded")
 			} else {
-				setConditionStatus(drupalSite, "CodeUpdating", false, err, false)
+				err.Wrap("%v: Failed to update version " + drupalSite.Spec.DrupalVersion)
+				setConditionStatus(drupalSite, "CodeUpdatingFailed", true, err, false)
 				return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
 			}
 		}
 
-		if update := setConditionStatus(drupalSite, "CodeUpdating", true, nil, false); update {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
-
 		if err := r.ensureUpdatedDeployment(ctx, drupalSite); err != nil {
 			if err.Temporary() {
-				return handleTransientErr(err, "%v while deploying the updated Drupal images")
+				return handleTransientErr(err, "%v while deploying the updated Drupal images of version", "UpdateNeeded")
 			} else {
-				setConditionStatus(drupalSite, "CodeUpdating", false, err, false)
-				return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
+				err.Wrap("%v: Failed to update version " + drupalSite.Spec.DrupalVersion)
+				setConditionStatus(drupalSite, "CodeUpdatingFailed", true, err, false)
+				//rollback here
+				if err := r.rollBackCodeUpdate(ctx, drupalSite, newApplicationError(nil, ErrDeploymentUpdateFailed)); err != nil {
+					return ctrl.Result{}, nil
+				}
 			}
 		}
 
-		if update := setConditionStatus(drupalSite, "CodeUpdating", false, nil, false); update {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
+		setConditionStatus(drupalSite, "CodeUpdatingFailed", false, nil, false)
+		setConditionStatus(drupalSite, "UpdateNeeded", false, nil, false)
+		return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
 	}
 
+	// If an update process is marked, then put the site in maintenance mode, and if not, take it off maintenance
+	// if drupalSite.ConditionTrue("CodeUpdating") || drupalSite.ConditionTrue("DBUpdating") {
+
+	// } else {
+	// 	if _, err := r.execToServerPodErrOnStderr(ctx, drupalSite, "php-fpm", nil, disableSiteMaintenanceModeCommandForDrupalSite()...); err != nil {
+	// 		return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
+	// 	}
+	// }
+
 	// Set "DBUpdating" and perform DB update
-	if drupalSite.ConditionTrue("UpdateNeeded") && !drupalSite.ConditionReasonSet("CodeUpdating") &&
-		!drupalSite.ConditionTrue("CodeUpdating") && !drupalSite.ConditionReasonSet("DBUpdating") {
-		if update := setConditionStatus(drupalSite, "DBUpdating", true, nil, false); update {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
-		err := r.runDBUpdate(ctx, drupalSite)
-		if err != nil {
-			if err.Temporary() {
-				return handleTransientErr(err, "%v while running DB update")
-			} else {
-				setConditionStatus(drupalSite, "DBUpdating", false, err, false)
-				return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-			}
-		}
-		if update := setConditionStatus(drupalSite, "DBUpdating", false, nil, false); update {
-			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
-		}
-	}
+	//
+	// if drupalSite.ConditionTrue("UpdateNeeded") && typeUpdate == "DBUpdate" {
+	// 	if err := r.takeDBBackup(ctx, drupalSite); err != nil {
+
+	// 	}
+	// 	if _, err := r.execToServerPodErrOnStderr(ctx, drupalSite, "php-fpm", nil, enableSiteMaintenanceModeCommandForDrupalSite()...); err != nil {
+	// 		return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
+	// 	}
+	// 	err := r.runDBUpdate(ctx, drupalSite)
+	// 	if err != nil {
+	// 		if err.Temporary() {
+	// 			return handleTransientErr(err, "%v while running DB update")
+	// 		} else {
+	// 			setConditionStatus(drupalSite, "DBUpdating", false, err, false)
+	// 			return r.updateCRStatusOrFailReconcile(ctx, log, drupalSite)
+	// 		}
+	// 	}
+	// }
 
 	// 4. Check DBOD has been provisioned and reconcile if needed
 	if dbodReady := r.isDBODProvisioned(ctx, drupalSite); !dbodReady {
@@ -423,39 +427,49 @@ func (r *DrupalSiteReconciler) isGivenImageInNginxImageStreamTagItems(ctx contex
 	return false, ErrClientK8s
 }
 
-// updateNeeded checks if a code or DB update is required based on the image tag and drupalVersion in the CR spec and the drush status
-func (r *DrupalSiteReconciler) updateNeeded(ctx context.Context, d *webservicesv1a1.DrupalSite) (bool, reconcileError) {
+// didRollOutSucceed checks if the deployment has rolled out the new pods successfully and the new pods are running
+func (r *DrupalSiteReconciler) didRollOutSucceed(ctx context.Context, d *webservicesv1a1.DrupalSite) (bool, error) {
+	pod, err := r.getRunningPod(ctx, d)
+	if err != nil {
+		return false, err
+	}
+	if pod.Status.Phase != corev1.PodRunning || pod.Annotations["drupalVersion"] != d.Spec.DrupalVersion {
+		return false, errors.New("Pod did not roll out successfully")
+	}
+	return true, nil
+}
+
+// UpdateNeeded checks if a code or DB update is required based on the image tag and drupalVersion in the CR spec and the drush status
+func (r *DrupalSiteReconciler) updateNeeded(ctx context.Context, d *webservicesv1a1.DrupalSite) (bool, string, reconcileError) {
 	deployment, err := r.getRunningdeployment(ctx, d)
 	if err != nil {
-		return false, newApplicationError(err, ErrClientK8s)
+		return false, "", newApplicationError(err, ErrClientK8s)
 	}
 	// If the deployment has a different image tag, then update needed
 	// NOTE: a more robust check could be done with Drush inside the pod
 	if len(deployment.Spec.Template.Spec.Containers) > 0 {
 		image := deployment.Spec.Template.Spec.Containers[0].Image
 		if len(image) < 2 {
-			return false, newApplicationError(errors.New("server deployment image doesn't have a version tag"), ErrInvalidSpec)
-		}
-		deploymentProgressing := GetDeploymentCondition(deployment.Status, appsv1.DeploymentProgressing)
-		imageInTag, err := r.isGivenImageInNginxImageStreamTagItems(ctx, d, image)
-		if err != nil {
-			return false, newApplicationError(errors.New("cannot check if the given image is part of the nginx imagestream tag items  "), ErrClientK8s)
+			return false, "", newApplicationError(errors.New("server deployment image doesn't have a version tag"), ErrInvalidSpec)
 		}
-		// sout, err := r.execToServerPodErrOnStderr(ctx, d, "php-fpm", nil, checkSiteMaitenanceStatus()...)
-		// fmt.Println(sout[1:])
-		if !imageInTag && deploymentProgressing.Status != corev1.ConditionTrue {
-			return true, nil
+		imageInTag := d.Spec.DrupalVersion == strings.Split(image, ":")[2]
+		// if err != nil {
+		// 	return false, "", newApplicationError(errors.New("cannot check if the given image is part of the nginx imagestream tag items  "), ErrClientK8s)
+		// }
+		// Check if image is different, check if current site is ready and installed
+		if !imageInTag && d.ConditionTrue("Ready") && d.ConditionTrue("Installed") {
+			return true, "CodeUpdate", nil
 		}
 	}
-	// If drush updb-status needs update, then update needed
+	// If drush updb-status needs update, then a database update needed
 	sout, err := r.execToServerPodErrOnStderr(ctx, d, "php-fpm", nil, checkUpdbStatus()...)
 	if err != nil {
-		return false, newApplicationError(err, ErrPodExec)
+		return false, "", newApplicationError(err, ErrPodExec)
 	}
 	if sout != "" {
-		return true, nil
+		return true, "DBUpdate", nil
 	}
-	return false, nil
+	return false, "", nil
 }
 
 // GetDeploymentCondition returns the condition with the provided type.
@@ -490,8 +504,10 @@ func (r *DrupalSiteReconciler) checkBuildstatusForUpdate(ctx context.Context, d
 		return newApplicationError(err, ErrClientK8s)
 	case status == "Failed" || status == "Error":
 		return r.rollBackCodeUpdate(ctx, d, newApplicationError(nil, ErrBuildFailed))
+	case status != buildv1.BuildPhaseComplete:
+		return newApplicationError(err, ErrTemporary)
 	}
-	return newApplicationError(err, ErrTemporary)
+	return nil
 }
 
 // ensureUpdatedDeployment runs the logic to do the base update for a new Drupal version
@@ -508,7 +524,6 @@ func (r *DrupalSiteReconciler) ensureUpdatedDeployment(ctx context.Context, d *w
 			return newApplicationError(err, ErrClientK8s)
 		}
 	}
-
 	// Check if deployment has rolled out
 	deployment, err := r.getRunningdeployment(ctx, d)
 	if err != nil {
@@ -521,10 +536,9 @@ func (r *DrupalSiteReconciler) ensureUpdatedDeployment(ctx context.Context, d *w
 		}
 	}
 
-	if GetDeploymentCondition(deployment.Status, appsv1.DeploymentAvailable) != nil {
-		if GetDeploymentCondition(deployment.Status, appsv1.DeploymentAvailable).Status == corev1.ConditionTrue {
-
-		}
+	rollout, err := r.didRollOutSucceed(ctx, d)
+	if rollout != true || err != nil {
+		return newApplicationError(err, ErrTemporary)
 	}
 
 	return nil
@@ -545,18 +559,26 @@ func (r *DrupalSiteReconciler) rollBackCodeUpdate(ctx context.Context, d *webser
 		}
 	}
 
+	d.Spec.DrupalVersion = d.Status.PreviousDrupalVersion
 	// Make error permanent
-	if err.Temporary() {
-		err = newApplicationError(err, ErrPermanent)
-	}
-	setConditionStatus(d, "CodeUpdating", false, err, false)
-	return err
-}
-
-func (r *DrupalSiteReconciler) runDBUpdate(ctx context.Context, d *webservicesv1a1.DrupalSite) reconcileError {
+	// if err.Temporary() {
+	// 	err = newApplicationError(err, ErrPermanent)
+	// }
+	setConditionStatus(d, "UpdateNeeded", false, nil, false)
 	return nil
 }
 
+// func (r *DrupalSiteReconciler) runDBUpdate(ctx context.Context, d *webservicesv1a1.DrupalSite) reconcileError {
+// 	sout, err := r.execToServerPodErrOnStderr(ctx, d, "php-fpm", nil, runUpDBCommand()...)
+// 	if err != nil {
+// 		return newApplicationError(err, ErrPodExec)
+// 	}
+// 	if sout != "" {
+// 		return nil
+// 	}
+// 	return
+// }
+
 // CODE BELOW WILL GO soon -------------
 
 // getenvOrDie checks for the given variable in the environment, if not exists
diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index f609935a4728b2dfe24e1261da81b1ca3f172d87..b1f0dfc74ac4e3dbc560c3d80b60a87dc06f9a84 100644
--- a/controllers/drupalsite_controller_test.go
+++ b/controllers/drupalsite_controller_test.go
@@ -145,7 +145,7 @@ var _ = Describe("DrupalSite controller", func() {
 
 				By("Expecting the drush job to have the EnvFrom secret field set correctly")
 				Eventually(func() bool {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					if len(job.Spec.Template.Spec.Containers) == 0 || len(job.Spec.Template.Spec.Containers[0].EnvFrom) == 0 {
 						return false
 					}
@@ -207,7 +207,7 @@ var _ = Describe("DrupalSite controller", func() {
 				// Check Drush job
 				By("Expecting Drush job created")
 				Eventually(func() []v1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					return job.ObjectMeta.OwnerReferences
 				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 
@@ -362,11 +362,11 @@ var _ = Describe("DrupalSite controller", func() {
 				// Check Drush job
 				By("Expecting Drush job recreated")
 				Eventually(func() error {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					return k8sClient.Delete(ctx, &job)
 				}, timeout, interval).Should(Succeed())
 				Eventually(func() []v1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					return job.ObjectMeta.OwnerReferences
 				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 
@@ -564,7 +564,7 @@ var _ = Describe("DrupalSite controller", func() {
 
 				By("Expecting the drush job to have the EnvFrom secret field set correctly")
 				Eventually(func() bool {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					if len(job.Spec.Template.Spec.Containers) == 0 || len(job.Spec.Template.Spec.Containers[0].EnvFrom) == 0 {
 						return false
 					}
@@ -626,7 +626,7 @@ var _ = Describe("DrupalSite controller", func() {
 				// Check Drush job
 				By("Expecting Drush job created")
 				Eventually(func() []v1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: "drush-" + key.Name, Namespace: key.Namespace}, &job)
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-install-" + key.Name, Namespace: key.Namespace}, &job)
 					return job.ObjectMeta.OwnerReferences
 				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 
diff --git a/controllers/drupalsite_resources.go b/controllers/drupalsite_resources.go
index 573c90ecf3e9d7624df3419220a0ea6997982e90..ca03569e891cda536b6a7abefe06cbf29d004aae 100644
--- a/controllers/drupalsite_resources.go
+++ b/controllers/drupalsite_resources.go
@@ -63,12 +63,22 @@ import (
 //	log.Info("EXEC", "stdout", sout, "stderr", serr)
 // ````
 func (r *DrupalSiteReconciler) execToServerPod(ctx context.Context, d *webservicesv1a1.DrupalSite, containerName string, stdin io.Reader, command ...string) (stdout string, stderr string, err error) {
+	pod, err := r.getRunningPod(ctx, d)
+	if err != nil {
+		return "", "", err
+	}
+	fmt.Println(pod.Name)
+	return execToPodThroughAPI(containerName, pod.Name, d.Namespace, stdin, command...)
+}
+
+// getRunningPod fetches the list of the running pods for the current deployment and returns the first one from the list
+func (r *DrupalSiteReconciler) getRunningPod(ctx context.Context, d *webservicesv1a1.DrupalSite) (corev1.Pod, error) {
 	podList := corev1.PodList{}
 	podLabels, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
 		MatchLabels: map[string]string{"drupalSite": d.Name, "app": "drupal"},
 	})
 	if err != nil {
-		return "", "", err
+		return corev1.Pod{}, err
 	}
 	options := client.ListOptions{
 		LabelSelector: podLabels,
@@ -76,13 +86,12 @@ func (r *DrupalSiteReconciler) execToServerPod(ctx context.Context, d *webservic
 	}
 	err = r.List(ctx, &podList, &options)
 	if err != nil {
-		return "", "", err
+		return corev1.Pod{}, err
 	}
 	if len(podList.Items) == 0 {
-		return "", "", errors.New("can't find pod with these labels")
+		return corev1.Pod{}, errors.New("can't find pod with these labels")
 	}
-	fmt.Println(podList.Items[0].Name)
-	return execToPodThroughAPI(containerName, podList.Items[0].Name, d.Namespace, stdin, command...)
+	return podList.Items[0], nil
 }
 
 // execToServerPodErrOnStder works like `execToServerPod`, but puts the contents of stderr in the error, if not empty
@@ -257,7 +266,7 @@ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservic
 		}
 		return nil
 	case "deploy_drupal":
-		if d.ConditionTrue("CodeUpdating") || d.ConditionTrue("DBUpdating") {
+		if d.ConditionTrue("UpdateNeeded") {
 			return nil
 		}
 		if dbodSecret := r.getDBODProvisionedSecret(ctx, d); len(dbodSecret) != 0 {
@@ -700,6 +709,7 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string
 				"{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"php-" + d.Name + ":" + drupalVersion + "\",\"namespace\":\"" + d.Namespace +
 				"\"},\"fieldPath\":\"spec.template.spec.containers[?(@.name==\"php-fpm\")].image\",\"pause\":\"false\"}]",
 		}
+		currentobject.Annotations["alpha.image.policy.openshift.io/resolve-names"] = "*"
 		currentobject.Spec.Template.ObjectMeta.Annotations = map[string]string{
 			"php-configmap-version":   "1",
 			"nginx-configmap-version": "1",
@@ -722,10 +732,12 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string
 		MatchLabels: ls,
 	}
 	currentobject.Spec.Template.ObjectMeta.Labels = ls
+	// Add an annotation to be able to verify what version of pod is running. Did not use labels, as it will affect the labelselector for the deployment and might cause downtime
+	currentobject.Spec.Template.ObjectMeta.Annotations["drupalVersion"] = drupalVersion
 
 	currentobject.Spec.Template.Spec = corev1.PodSpec{
 		Containers: []corev1.Container{{
-			Image:           "nginx-" + d.Name + ":" + drupalVersion,
+			Image:           "image-registry.openshift-image-registry.svc:5000/" + d.Namespace + "/nginx-" + d.Name + ":" + d.Spec.DrupalVersion,
 			Name:            "nginx",
 			ImagePullPolicy: "IfNotPresent",
 			Ports: []corev1.ContainerPort{{
@@ -765,7 +777,7 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string
 			},
 		},
 			{
-				Image:           "php-" + d.Name + ":" + drupalVersion,
+				Image:           "image-registry.openshift-image-registry.svc:5000/" + d.Namespace + "/php-" + d.Name + ":" + d.Spec.DrupalVersion,
 				Name:            "php-fpm",
 				ImagePullPolicy: "IfNotPresent",
 				Ports: []corev1.ContainerPort{{
@@ -960,7 +972,7 @@ func jobForDrupalSiteDrush(currentobject *batchv1.Job, dbodSecret string, d *web
 			}},
 			RestartPolicy: "Never",
 			Containers: []corev1.Container{{
-				Image:           "php-" + d.Name + ":" + d.Spec.DrupalVersion,
+				Image:           "image-registry.openshift-image-registry.svc:5000/" + d.Namespace + "/php-" + d.Name + ":" + d.Spec.DrupalVersion,
 				Name:            "drush",
 				ImagePullPolicy: "Always",
 				Command:         siteInstallJobForDrupalSite(),
@@ -1145,7 +1157,7 @@ func enableSiteMaintenanceModeCommandForDrupalSite() []string {
 // disableSiteMaintenanceModeCommandForDrupalSite outputs the command needed for jobForDrupalSiteMaintenanceMode
 func disableSiteMaintenanceModeCommandForDrupalSite() []string {
 	return []string{"sh", "-c",
-		"drush state:set system.maintenance_mode 0 --input-format=integer && drush cache:rebuild",
+		"drush state:set system.maintenance_mode 0 --input-format=integer && drush cache:rebuild 2>/dev/null",
 	}
 }
 
@@ -1158,3 +1170,8 @@ func checkUpdbStatus() []string {
 func checkSiteMaitenanceStatus() []string {
 	return []string{"sh", "-c", "drush state:get system.maintenance_mode | grep -q '1'; if [[ $? -eq 0 ]] ; then echo 'true'; else echo 'false'; fi"}
 }
+
+func runUpDBCommand() []string {
+	return []string{"sh", "-c",
+		"drush updatedb --format=json 2>/dev/null | jq '. | length'"}
+}
diff --git a/controllers/error_types.go b/controllers/error_types.go
index 37303fcb54d2dfbc2b69dd630e56f8112541c8d1..bf50f77b35f3b3dd9a2989de41b0e885bf7cd3e0 100644
--- a/controllers/error_types.go
+++ b/controllers/error_types.go
@@ -13,12 +13,13 @@ var (
 	ErrInvalidSpec = errors.New("InvalidSpec")
 	// ErrFunctionDomain can be returned by a function that was passed invalid arguments, such as the default case of a switch.
 	// Consider constraining the arg type.
-	ErrFunctionDomain = errors.New("FunctionDomainError")
-	ErrClientK8s      = errors.New("k8sAPIClientError")
-	ErrPodExec        = errors.New("ExecInPodError")
-	ErrFilesystemIO   = errors.New("FilesystemIOError")
-	ErrDBOD           = errors.New("DBODError")
-	ErrBuildFailed    = errors.New("BuildError")
+	ErrFunctionDomain         = errors.New("FunctionDomainError")
+	ErrClientK8s              = errors.New("k8sAPIClientError")
+	ErrPodExec                = errors.New("ExecInPodError")
+	ErrFilesystemIO           = errors.New("FilesystemIOError")
+	ErrDBOD                   = errors.New("DBODError")
+	ErrBuildFailed            = errors.New("BuildError")
+	ErrDeploymentUpdateFailed = errors.New("DeploymentUpdateError")
 )
 
 type reconcileError interface {
diff --git a/state.md b/state.md
new file mode 100644
index 0000000000000000000000000000000000000000..e527f7c9851b9b83455e7785802285b1215ad3d8
--- /dev/null
+++ b/state.md
@@ -0,0 +1,34 @@
+## Reconcilation
+```mermaid
+graph TD;
+    Reconcile-->FetchCR["Fetch drupalSite CR"];
+    FetchCR--FetchCRerror-->ReturnError1["Return Error"];
+    FetchCR--FetchCRsuccess-->GetDeletionTimeStamp;
+    GetDeletionTimeStamp--TimeStampError-->ReturnError2["Return Error"];
+    GetDeletionTimeStamp--TimeStampsuccess-->CleanupDrupalSite;
+    GetDeletionTimeStamp--NoTimeStamp-->ensureSpecFinalizer;
+    ensureSpecFinalizer--NeedsUpdate-->Return&Reconcile["Update, Return and reconcile"];
+    ensureSpecFinalizer--NoUpdate-->ValidateSpec;
+    ValidateSpec--Fail-->Return&Reconcile1["Set error and reconcile"];
+    ValidateSpec--Success-->Update["set update=false"];
+    Update-->CheckSiteReady;
+    CheckSiteReady--NotReady-->SetNotReady["Set update=setnotready"];
+    CheckSiteReady--Ready-->SetReady["Set update=setready"];
+    SetNotReady-->CheckInstallJob;
+    SetReady-->CheckInstallJob;
+    CheckInstallJob--Installed-->SetInstalled["Set update=setinstalled"];
+    CheckInstallJob--NotInstalled-->SetNotInstalled["Set update=setnotinstalled"];
+    SetInstalled-->CheckUpdateNeeded;
+    SetNotInstalled-->CheckUpdateNeeded;
+    CheckUpdateNeeded--err-->SetUpdateNeededTrueButStatusUnknown;
+    CheckUpdateNeeded--true-->SetUpdateNeededTrue["update=SetUpdateNeededTrue"];
+    CheckUpdateNeeded--false-->SetUpdateNeededFalse["update=SetUpdateNeededFalse"];
+    SetUpdateNeededTrueButStatusUnknown-->CheckUpdateVariable;
+    SetUpdateNeededTrue-->CheckUpdateVariable;
+    SetUpdateNeededFalse-->CheckUpdateVariable;
+    CheckUpdateVariable--true-->Return&Reconcile2["Update status and reconcile"];
+    CheckUpdateVariable--false-->EnsureResources;
+    EnsureResources--Err-->SetNotReadyReconcile["Set status as not ready and reconcile"];
+    EnsureResources--NoErr-->CheckUpdateNeededTrue&CodeUpdatingFalse;
+
+```