#9 Allow mount pvc in Jenkins pod
This commit is contained in:
parent
a271078227
commit
f9ad157c8b
154
deploy/role.yaml
154
deploy/role.yaml
|
|
@ -4,77 +4,83 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- services
|
- services
|
||||||
- configmaps
|
- configmaps
|
||||||
- secrets
|
- secrets
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- create
|
- create
|
||||||
- update
|
- update
|
||||||
- list
|
- list
|
||||||
- watch
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- "extensions"
|
- "extensions"
|
||||||
resources:
|
resources:
|
||||||
- ingresses
|
- ingresses
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- serviceaccounts
|
- serviceaccounts
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- rbac.authorization.k8s.io
|
- rbac.authorization.k8s.io
|
||||||
resources:
|
resources:
|
||||||
- roles
|
- roles
|
||||||
- rolebindings
|
- rolebindings
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- pods/portforward
|
- pods/portforward
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- pods/log
|
- pods/log
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
- watch
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- pods
|
- pods
|
||||||
- pods/exec
|
- pods/exec
|
||||||
verbs:
|
verbs:
|
||||||
- "*"
|
- "*"
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- events
|
- events
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- apps
|
- apps
|
||||||
resourceNames:
|
resourceNames:
|
||||||
- jenkins-operator
|
- jenkins-operator
|
||||||
resources:
|
resources:
|
||||||
- deployments/finalizers
|
- deployments/finalizers
|
||||||
verbs:
|
verbs:
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- jenkins.io
|
- jenkins.io
|
||||||
resources:
|
resources:
|
||||||
- '*'
|
- '*'
|
||||||
verbs:
|
verbs:
|
||||||
- '*'
|
- '*'
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- persistentvolumeclaims
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
|
@ -63,8 +63,18 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reconcile.Result{}, nil, err
|
return reconcile.Result{}, nil, err
|
||||||
}
|
}
|
||||||
|
r.logger.V(log.VDebug).Info("Kubernetes resources are present")
|
||||||
|
|
||||||
result, err := r.ensureJenkinsMasterPod(metaObject)
|
result, err := r.waitForVolumes()
|
||||||
|
if err != nil {
|
||||||
|
return reconcile.Result{}, nil, err
|
||||||
|
}
|
||||||
|
if result.Requeue {
|
||||||
|
return result, nil, nil
|
||||||
|
}
|
||||||
|
r.logger.V(log.VDebug).Info("Jenkins master pod volumes are ready")
|
||||||
|
|
||||||
|
result, err = r.ensureJenkinsMasterPod(metaObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reconcile.Result{}, nil, err
|
return reconcile.Result{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +159,26 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ReconcileJenkinsBaseConfiguration) waitForVolumes() (reconcile.Result, error) {
|
||||||
|
for _, volume := range r.jenkins.Spec.Master.Volumes {
|
||||||
|
if volume.PersistentVolumeClaim != nil {
|
||||||
|
pvc := &corev1.PersistentVolumeClaim{}
|
||||||
|
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.PersistentVolumeClaim.ClaimName, Namespace: r.jenkins.ObjectMeta.Namespace}, pvc)
|
||||||
|
if err != nil {
|
||||||
|
return reconcile.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pvc.Status.Phase != corev1.ClaimBound {
|
||||||
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("PersistentVolumeClaim '%s' have invalid state '%s' - required '%s', volume '%v'",
|
||||||
|
volume.PersistentVolumeClaim.ClaimName, pvc.Status.Phase, corev1.ClaimBound, volume))
|
||||||
|
return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 5}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reconcile.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins, basePlugins map[string][]plugins.Plugin) (bool, error) {
|
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins, basePlugins map[string][]plugins.Plugin) (bool, error) {
|
||||||
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -427,7 +457,7 @@ func (r *ReconcileJenkinsBaseConfiguration) isRecreatePodNeeded(currentJenkinsMa
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r.compareVolumes(currentJenkinsMasterPod) {
|
if !r.compareVolumes(currentJenkinsMasterPod) {
|
||||||
r.logger.Info(fmt.Sprintf("Jenkins pod volumes have changed, actual '%+v' required '%+v', recreating pod",
|
r.logger.Info(fmt.Sprintf("Jenkins pod volumes have changed, actual '%v' required '%v', recreating pod",
|
||||||
currentJenkinsMasterPod.Spec.Volumes, r.jenkins.Spec.Master.Volumes))
|
currentJenkinsMasterPod.Spec.Volumes, r.jenkins.Spec.Master.Volumes))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,15 +69,34 @@ func (r *ReconcileJenkinsBaseConfiguration) validateVolumes() (bool, error) {
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
valid = false
|
valid = false
|
||||||
}
|
}
|
||||||
|
case volume.PersistentVolumeClaim != nil:
|
||||||
|
if ok, err := r.validatePersistentVolumeClaim(volume); err != nil {
|
||||||
|
return false, err
|
||||||
|
} else if !ok {
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
default: //TODO add support for rest of volumes
|
default: //TODO add support for rest of volumes
|
||||||
valid = false
|
valid = false
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Unsupported volume '%+v'", volume))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Unsupported volume '%v'", volume))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid, nil
|
return valid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ReconcileJenkinsBaseConfiguration) validatePersistentVolumeClaim(volume corev1.Volume) (bool, error) {
|
||||||
|
pvc := &corev1.PersistentVolumeClaim{}
|
||||||
|
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.PersistentVolumeClaim.ClaimName, Namespace: r.jenkins.ObjectMeta.Namespace}, pvc)
|
||||||
|
if err != nil && apierrors.IsNotFound(err) {
|
||||||
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("PersistentVolumeClaim '%s' not found for volume '%v'", volume.PersistentVolumeClaim.ClaimName, volume))
|
||||||
|
return false, nil
|
||||||
|
} else if err != nil && !apierrors.IsNotFound(err) {
|
||||||
|
return false, stackerr.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) validateConfigMapVolume(volume corev1.Volume) (bool, error) {
|
func (r *ReconcileJenkinsBaseConfiguration) validateConfigMapVolume(volume corev1.Volume) (bool, error) {
|
||||||
if volume.ConfigMap.Optional != nil && *volume.ConfigMap.Optional {
|
if volume.ConfigMap.Optional != nil && *volume.ConfigMap.Optional {
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
@ -86,7 +105,7 @@ func (r *ReconcileJenkinsBaseConfiguration) validateConfigMapVolume(volume corev
|
||||||
configMap := &corev1.ConfigMap{}
|
configMap := &corev1.ConfigMap{}
|
||||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.ConfigMap.Name, Namespace: r.jenkins.ObjectMeta.Namespace}, configMap)
|
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.ConfigMap.Name, Namespace: r.jenkins.ObjectMeta.Namespace}, configMap)
|
||||||
if err != nil && apierrors.IsNotFound(err) {
|
if err != nil && apierrors.IsNotFound(err) {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("ConfigMap '%s' not found for volume '%+v'", volume.ConfigMap.Name, volume))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("ConfigMap '%s' not found for volume '%v'", volume.ConfigMap.Name, volume))
|
||||||
return false, nil
|
return false, nil
|
||||||
} else if err != nil && !apierrors.IsNotFound(err) {
|
} else if err != nil && !apierrors.IsNotFound(err) {
|
||||||
return false, stackerr.WithStack(err)
|
return false, stackerr.WithStack(err)
|
||||||
|
|
@ -103,7 +122,7 @@ func (r *ReconcileJenkinsBaseConfiguration) validateSecretVolume(volume corev1.V
|
||||||
secret := &corev1.Secret{}
|
secret := &corev1.Secret{}
|
||||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.Secret.SecretName, Namespace: r.jenkins.ObjectMeta.Namespace}, secret)
|
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: volume.Secret.SecretName, Namespace: r.jenkins.ObjectMeta.Namespace}, secret)
|
||||||
if err != nil && apierrors.IsNotFound(err) {
|
if err != nil && apierrors.IsNotFound(err) {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' not found for volume '%+v'", volume.Secret.SecretName, volume))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' not found for volume '%v'", volume.Secret.SecretName, volume))
|
||||||
return false, nil
|
return false, nil
|
||||||
} else if err != nil && !apierrors.IsNotFound(err) {
|
} else if err != nil && !apierrors.IsNotFound(err) {
|
||||||
return false, stackerr.WithStack(err)
|
return false, stackerr.WithStack(err)
|
||||||
|
|
@ -158,7 +177,7 @@ func (r *ReconcileJenkinsBaseConfiguration) validateContainerVolumeMounts(contai
|
||||||
|
|
||||||
for _, volumeMount := range container.VolumeMounts {
|
for _, volumeMount := range container.VolumeMounts {
|
||||||
if len(volumeMount.MountPath) == 0 {
|
if len(volumeMount.MountPath) == 0 {
|
||||||
logger.V(log.VWarn).Info(fmt.Sprintf("mountPath not set for '%s' volume mount", volumeMount.Name))
|
logger.V(log.VWarn).Info(fmt.Sprintf("mountPath not set for '%s' volume mount in container '%s'", volumeMount.Name, container.Name))
|
||||||
valid = false
|
valid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +189,7 @@ func (r *ReconcileJenkinsBaseConfiguration) validateContainerVolumeMounts(contai
|
||||||
}
|
}
|
||||||
|
|
||||||
if !foundVolume {
|
if !foundVolume {
|
||||||
logger.V(log.VWarn).Info(fmt.Sprintf("Not found volume for '%s' volume mount", volumeMount.Name))
|
logger.V(log.VWarn).Info(fmt.Sprintf("Not found volume for '%s' volume mount in container '%s'", volumeMount.Name, container.Name))
|
||||||
valid = false
|
valid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue