THIS IS ONLY A TEST INSTANCE. DON'T DO IMPORTANT WORK HERE!

Commit 9c629563 authored by Oleksandr Andriienko's avatar Oleksandr Andriienko
Browse files

Add ability configure host volume path.


Signed-off-by: default avatarOleksandr Andriienko <oandriie@redhat.com>
parent 2e47c333
......@@ -13,6 +13,12 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: che-operator
rules:
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- "*"
- apiGroups:
- oauth.openshift.io
resources:
......
......@@ -19,4 +19,4 @@ subjects:
roleRef:
kind: ClusterRole
name: che-operator
apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
apiGroup: rbac.authorization.k8s.io
......@@ -85,6 +85,8 @@ spec:
pvcJobsImage: ''
# keep blank unless you need to use a non default storage class for Postgres PVC
postgresPVCStorageClassName: ''
# Postgres volume path to store db in the node host
postgresPVCHostVolumePath: ''
# keep blank unless you need to use a non default storage class for workspace PVC(s)
workspacePVCStorageClassName: ''
......
......@@ -425,6 +425,9 @@ spec:
to the Postgres database. If omitted or left blank, default storage
class is used.
type: string
postgresPVCHostVolumePath:
description: Postgres volume path to store db in the node host
type: string
preCreateSubPaths:
description: Instructs the Che server to launch a special pod to
pre-create a subpath in the Persistent Volumes. Defaults to `false`,
......
......@@ -48,6 +48,7 @@ rules:
- serviceaccounts
- endpoints
- persistentvolumeclaims
- persistentVolumes
- events
- configmaps
- secrets
......
......@@ -343,6 +343,9 @@ type CheClusterSpecStorage struct {
// If omitted or left blank, default storage class is used.
// +optional
PostgresPVCStorageClassName string `json:"postgresPVCStorageClassName,omitempty"`
// Postgres volume path to store db in the node host
// +optional
PostgresPVCHostVolumePath string `json:"postgresPVCHostVolumePath,omitempty"`
// Storage class for the Persistent Volume Claims dedicated to the Che workspaces.
// If omitted or left blank, default storage class is used.
// +optional
......
......@@ -419,7 +419,6 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
return reconcile.Result{}, err
}
}
if err := r.GenerateAndSaveFields(instance, request); err != nil {
instance, _ = r.GetCR(request)
return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 1}, err
......@@ -427,7 +426,6 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
chePostgresPassword := instance.Spec.Database.ChePostgresPassword
keycloakPostgresPassword := instance.Spec.Auth.IdentityProviderPostgresPassword
keycloakAdminPassword := instance.Spec.Auth.IdentityProviderPassword
cheFlavor := util.GetValue(instance.Spec.Server.CheFlavor, deploy.DefaultCheFlavor)
// Create Postgres resources and provisioning unless an external DB is used
......@@ -439,17 +437,28 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
if err := r.CreateService(instance, postgresService, false); err != nil {
return reconcile.Result{}, err
}
// Create a new Postgres PVC object
// Create a new Postgres PersistentVolume object
if instance.Spec.Storage.PostgresPVCHostVolumePath != "" {
pv := deploy.NewPv(instance, "postgres-data", "1Gi", postgresLabels)
if err := r.CreatePV(instance, pv); err != nil {
return reconcile.Result{}, err
}
}
// Create a new Postgres PersistentVolumeClaim object
pvc := deploy.NewPvc(instance, "postgres-data", "1Gi", postgresLabels)
if err := r.CreatePVC(instance, pvc); err != nil {
return reconcile.Result{}, err
}
if !tests {
err = r.client.Get(context.TODO(), types.NamespacedName{Name: pvc.Name, Namespace: instance.Namespace}, pvc)
if pvc.Status.Phase != "Bound" {
k8sclient.GetPostgresStatus(pvc, instance.Namespace)
}
}
// Create a new Postgres deployment
postgresDeployment := deploy.NewPostgresDeployment(instance, chePostgresPassword, isOpenShift, cheFlavor)
......
......@@ -233,6 +233,29 @@ func (r *ReconcileChe) CreateService(cr *orgv1.CheCluster, service *corev1.Servi
return nil
}
func (r *ReconcileChe) CreatePV(instance *orgv1.CheCluster, pv *corev1.PersistentVolume) error {
// Set CheCluster instance as the owner and controller
if err := controllerutil.SetControllerReference(instance, pv, r.scheme); err != nil {
return err
}
pvFound := &corev1.PersistentVolume{}
err := r.client.Get(context.TODO(), types.NamespacedName{Name: pv.Name, Namespace: pv.Namespace}, pvFound)
if err != nil && errors.IsNotFound(err) {
logrus.Infof("Creating a new object %s, name: %s. Cause: %s", pv.Kind, pv.Name, err.Error())
err = r.client.Create(context.TODO(), pv)
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Errorf("Creating a new pv object %s, name: %s. Cause %s", pv.Kind, pv.Name, err.Error())
return err
}
return nil
} else if err != nil {
logrus.Errorf("No pvFound %s, name: %s", pv.Kind, pv.Name)
return err
}
return nil
}
func (r *ReconcileChe) CreatePVC(instance *orgv1.CheCluster, pvc *corev1.PersistentVolumeClaim) error {
// Set CheCluster instance as the owner and controller
if err := controllerutil.SetControllerReference(instance, pvc, r.scheme); err != nil {
......
......@@ -12,12 +12,57 @@
package deploy
import (
"github.com/sirupsen/logrus"
orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func NewPv(cr *orgv1.CheCluster, name string, pvClaimSize string, labels map[string]string) *corev1.PersistentVolume {
hostPathType := new(corev1.HostPathType)
*hostPathType = corev1.HostPathType(string(corev1.HostPathDirectoryOrCreate))
accessModes := []corev1.PersistentVolumeAccessMode{
// todo Make configurable
corev1.ReadWriteOnce,
}
Requests := corev1.ResourceList{
corev1.ResourceName(corev1.ResourceStorage): resource.MustParse(pvClaimSize),
}
pvSpec := corev1.PersistentVolumeSpec{
AccessModes: accessModes,
Capacity: Requests,
PersistentVolumeSource: corev1.PersistentVolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: cr.Spec.Storage.PostgresPVCHostVolumePath,
Type: hostPathType,
},
},
}
logrus.Info("Use postgres pv with storage class name: " + cr.Spec.Storage.PostgresPVCStorageClassName)
logrus.Info("Use postgres pv with host volume path: " + cr.Spec.Storage.PostgresPVCHostVolumePath)
if cr.Spec.Storage.PostgresPVCStorageClassName != "" {
pvSpec.StorageClassName = cr.Spec.Storage.PostgresPVCStorageClassName
}
return &corev1.PersistentVolume{
TypeMeta: metav1.TypeMeta{
Kind: "PersistentVolume",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: cr.Namespace,
Labels: labels,
},
Spec: pvSpec,
}
}
func NewPvc(cr *orgv1.CheCluster, name string, pvcClaimSize string, labels map[string]string) *corev1.PersistentVolumeClaim {
accessModes := []corev1.PersistentVolumeAccessMode{
......@@ -27,17 +72,18 @@ func NewPvc(cr *orgv1.CheCluster, name string, pvcClaimSize string, labels map[s
resources := corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceName(corev1.ResourceStorage): resource.MustParse(pvcClaimSize),
}}
},
}
pvcSpec := corev1.PersistentVolumeClaimSpec{
AccessModes: accessModes,
Resources: resources,
}
if len(cr.Spec.Storage.PostgresPVCStorageClassName) > 1 {
pvcSpec = corev1.PersistentVolumeClaimSpec{
AccessModes: accessModes,
StorageClassName: &cr.Spec.Storage.PostgresPVCStorageClassName,
Resources: resources,
}
if cr.Spec.Storage.PostgresPVCHostVolumePath != "" {
pvcSpec.VolumeName = name
}
if cr.Spec.Storage.PostgresPVCStorageClassName != "" {
pvcSpec.StorageClassName = &cr.Spec.Storage.PostgresPVCStorageClassName
}
return &corev1.PersistentVolumeClaim{
TypeMeta: metav1.TypeMeta{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment