#13 Add node selector for Jenkins master pod
This commit is contained in:
parent
f842be89d9
commit
75c403b941
|
|
@ -20,6 +20,7 @@ type JenkinsSpec struct {
|
||||||
// every single change requires Jenkins master pod restart
|
// every single change requires Jenkins master pod restart
|
||||||
type JenkinsMaster struct {
|
type JenkinsMaster struct {
|
||||||
Image string `json:"image,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
|
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
|
||||||
Annotations map[string]string `json:"masterAnnotations,omitempty"`
|
Annotations map[string]string `json:"masterAnnotations,omitempty"`
|
||||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||||
// OperatorPlugins contains plugins required by operator
|
// OperatorPlugins contains plugins required by operator
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,13 @@ func (in *JenkinsList) DeepCopyObject() runtime.Object {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.NodeSelector != nil {
|
||||||
|
in, out := &in.NodeSelector, &out.NodeSelector
|
||||||
|
*out = make(map[string]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
(*out)[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
if in.Annotations != nil {
|
if in.Annotations != nil {
|
||||||
in, out := &in.Annotations, &out.Annotations
|
in, out := &in.Annotations, &out.Annotations
|
||||||
*out = make(map[string]string, len(*in))
|
*out = make(map[string]string, len(*in))
|
||||||
|
|
|
||||||
|
|
@ -338,40 +338,54 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O
|
||||||
return reconcile.Result{}, stackerr.WithStack(err)
|
return reconcile.Result{}, stackerr.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate pod
|
if currentJenkinsMasterPod != nil && isPodTerminating(*currentJenkinsMasterPod) {
|
||||||
|
return reconcile.Result{Requeue: true}, nil
|
||||||
|
}
|
||||||
|
if currentJenkinsMasterPod != nil && r.isRecreatePodNeeded(*currentJenkinsMasterPod) {
|
||||||
|
return reconcile.Result{Requeue: true}, r.restartJenkinsMasterPod(meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reconcile.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPodTerminating(pod corev1.Pod) bool {
|
||||||
|
return pod.ObjectMeta.DeletionTimestamp != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReconcileJenkinsBaseConfiguration) isRecreatePodNeeded(currentJenkinsMasterPod corev1.Pod) bool {
|
||||||
recreatePod := false
|
recreatePod := false
|
||||||
if currentJenkinsMasterPod != nil &&
|
|
||||||
(currentJenkinsMasterPod.Status.Phase == corev1.PodFailed ||
|
if currentJenkinsMasterPod.Status.Phase == corev1.PodFailed ||
|
||||||
currentJenkinsMasterPod.Status.Phase == corev1.PodSucceeded ||
|
currentJenkinsMasterPod.Status.Phase == corev1.PodSucceeded ||
|
||||||
currentJenkinsMasterPod.Status.Phase == corev1.PodUnknown) {
|
currentJenkinsMasterPod.Status.Phase == corev1.PodUnknown {
|
||||||
r.logger.Info(fmt.Sprintf("Invalid Jenkins pod phase '%+v', recreating pod", currentJenkinsMasterPod.Status.Phase))
|
r.logger.Info(fmt.Sprintf("Invalid Jenkins pod phase '%+v', recreating pod", currentJenkinsMasterPod.Status))
|
||||||
recreatePod = true
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentJenkinsMasterPod != nil &&
|
if r.jenkins.Spec.Master.Image != currentJenkinsMasterPod.Spec.Containers[0].Image {
|
||||||
r.jenkins.Spec.Master.Image != currentJenkinsMasterPod.Spec.Containers[0].Image {
|
|
||||||
r.logger.Info(fmt.Sprintf("Jenkins image has changed to '%+v', recreating pod", r.jenkins.Spec.Master.Image))
|
r.logger.Info(fmt.Sprintf("Jenkins image has changed to '%+v', recreating pod", r.jenkins.Spec.Master.Image))
|
||||||
recreatePod = true
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentJenkinsMasterPod != nil && len(r.jenkins.Spec.Master.Annotations) > 0 &&
|
if len(r.jenkins.Spec.Master.Annotations) > 0 &&
|
||||||
!reflect.DeepEqual(r.jenkins.Spec.Master.Annotations, currentJenkinsMasterPod.ObjectMeta.Annotations) {
|
!reflect.DeepEqual(r.jenkins.Spec.Master.Annotations, currentJenkinsMasterPod.ObjectMeta.Annotations) {
|
||||||
r.logger.Info(fmt.Sprintf("Jenkins pod annotations have changed to '%+v', recreating pod", r.jenkins.Spec.Master.Annotations))
|
r.logger.Info(fmt.Sprintf("Jenkins pod annotations have changed to '%+v', recreating pod", r.jenkins.Spec.Master.Annotations))
|
||||||
recreatePod = true
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentJenkinsMasterPod != nil &&
|
if !reflect.DeepEqual(r.jenkins.Spec.Master.Resources, currentJenkinsMasterPod.Spec.Containers[0].Resources) {
|
||||||
!reflect.DeepEqual(r.jenkins.Spec.Master.Resources, currentJenkinsMasterPod.Spec.Containers[0].Resources) {
|
|
||||||
r.logger.Info(fmt.Sprintf("Jenkins pod resources have changed, actual '%+v' required '%+v' - recreating pod",
|
r.logger.Info(fmt.Sprintf("Jenkins pod resources have changed, actual '%+v' required '%+v' - recreating pod",
|
||||||
currentJenkinsMasterPod.Spec.Containers[0].Resources, r.jenkins.Spec.Master.Resources))
|
currentJenkinsMasterPod.Spec.Containers[0].Resources, r.jenkins.Spec.Master.Resources))
|
||||||
recreatePod = true
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentJenkinsMasterPod != nil && recreatePod && currentJenkinsMasterPod.ObjectMeta.DeletionTimestamp == nil {
|
if !reflect.DeepEqual(r.jenkins.Spec.Master.NodeSelector, currentJenkinsMasterPod.Spec.NodeSelector) {
|
||||||
return reconcile.Result{Requeue: true}, r.restartJenkinsMasterPod(meta)
|
r.logger.Info(fmt.Sprintf("Jenkins pod node selector has changed, actual '%+v' required '%+v' - recreating pod",
|
||||||
|
r.jenkins.Spec.Master.NodeSelector, currentJenkinsMasterPod.Spec.NodeSelector))
|
||||||
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return reconcile.Result{}, nil
|
return recreatePod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) restartJenkinsMasterPod(meta metav1.ObjectMeta) error {
|
func (r *ReconcileJenkinsBaseConfiguration) restartJenkinsMasterPod(meta metav1.ObjectMeta) error {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ func NewJenkinsMasterPod(objectMeta metav1.ObjectMeta, jenkins *v1alpha1.Jenkins
|
||||||
RunAsUser: &runAsUser,
|
RunAsUser: &runAsUser,
|
||||||
RunAsGroup: &runAsUser,
|
RunAsGroup: &runAsUser,
|
||||||
},
|
},
|
||||||
|
NodeSelector: jenkins.Spec.Master.NodeSelector,
|
||||||
Containers: []corev1.Container{
|
Containers: []corev1.Container{
|
||||||
{
|
{
|
||||||
Name: "jenkins-master",
|
Name: "jenkins-master",
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,10 @@ func verifyJenkinsMasterPodAttributes(t *testing.T, jenkins *v1alpha1.Jenkins) {
|
||||||
t.Fatalf("Invalid jenkins pod continer resources expected '%+v', actual '%+v'", jenkins.Spec.Master.Resources, jenkinsPod.Spec.Containers[0].Resources)
|
t.Fatalf("Invalid jenkins pod continer resources expected '%+v', actual '%+v'", jenkins.Spec.Master.Resources, jenkinsPod.Spec.Containers[0].Resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(jenkinsPod.Spec.NodeSelector, jenkins.Spec.Master.NodeSelector) {
|
||||||
|
t.Fatalf("Invalid jenkins pod node selector expected '%+v', actual '%+v'", jenkins.Spec.Master.NodeSelector, jenkinsPod.Spec.NodeSelector)
|
||||||
|
}
|
||||||
|
|
||||||
t.Log("Jenkins pod attributes are valid")
|
t.Log("Jenkins pod attributes are valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ func createJenkinsCR(t *testing.T, name, namespace string) *v1alpha1.Jenkins {
|
||||||
"audit-trail:2.4": {},
|
"audit-trail:2.4": {},
|
||||||
"simple-theme-plugin:0.5.1": {},
|
"simple-theme-plugin:0.5.1": {},
|
||||||
},
|
},
|
||||||
|
NodeSelector: map[string]string{"kubernetes.io/hostname": "minikube"},
|
||||||
},
|
},
|
||||||
//TODO(bantoniak) add seed job with private key
|
//TODO(bantoniak) add seed job with private key
|
||||||
SeedJobs: []v1alpha1.SeedJob{
|
SeedJobs: []v1alpha1.SeedJob{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue