Switch from a Deployment to a Job and create permanent nginx Deployment

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
Dimitris Karakasilis
2022-12-07 15:58:47 +02:00
parent 658b816c1d
commit 44a48d7890
10 changed files with 92 additions and 114 deletions

View File

@@ -20,13 +20,13 @@ import (
"fmt"
buildv1alpha1 "github.com/kairos-io/osbuilder/api/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func genDeploymentLabel(s string) map[string]string {
func genJobLabel(s string) map[string]string {
return map[string]string{
"osbuild": "workload" + s,
}
@@ -64,7 +64,7 @@ func createImageContainer(containerImage string, pushOptions buildv1alpha1.Push)
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"tar -czvpf test.tar -C /rootfs . && luet util pack %s test.tar image.tar && mv image.tar /public",
"tar -czvpf test.tar -C /rootfs . && luet util pack %s test.tar image.tar && mv image.tar /artifacts",
pushOptions.ImageName,
),
},
@@ -74,8 +74,8 @@ func createImageContainer(containerImage string, pushOptions buildv1alpha1.Push)
MountPath: "/rootfs",
},
{
Name: "public",
MountPath: "/public",
Name: "artifacts",
MountPath: "/artifacts",
},
},
}
@@ -104,8 +104,7 @@ func osReleaseContainer(containerImage string) v1.Container {
}
}
func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact, svc *v1.Service) *appsv1.Deployment {
// TODO: svc is unused, but could be used in the future to generate the Netboot URL
func (r *OSArtifactReconciler) genJob(artifact buildv1alpha1.OSArtifact) *batchv1.Job {
objMeta := metav1.ObjectMeta{
Name: artifact.Name,
Namespace: artifact.Namespace,
@@ -118,14 +117,14 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
serviceAccount := false
cmd := fmt.Sprintf(
"/entrypoint.sh --debug --name %s build-iso --date=false --output /public dir:/rootfs",
"/entrypoint.sh --debug --name %s build-iso --date=false --output /artifacts dir:/rootfs",
artifact.Name,
)
volumeMounts := []v1.VolumeMount{
{
Name: "public",
MountPath: "/public",
Name: "artifacts",
MountPath: "/artifacts",
},
{
Name: "rootfs",
@@ -142,7 +141,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
}
cloudImgCmd := fmt.Sprintf(
"/raw-images.sh /rootfs /public/%s.raw",
"/raw-images.sh /rootfs /artifacts/%s.raw",
artifact.Name,
)
@@ -158,7 +157,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
if artifact.Spec.CloudConfig != "" || artifact.Spec.GRUBConfig != "" {
cmd = fmt.Sprintf(
"/entrypoint.sh --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay --output /public dir:/rootfs",
"/entrypoint.sh --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay --output /artifacts dir:/rootfs",
artifact.Name,
)
}
@@ -207,7 +206,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
}},
Args: []string{
fmt.Sprintf(
"/netboot.sh /public/%s.iso /public/%s",
"/netboot.sh /artifacts/%s.iso /artifacts/%s",
artifact.Name,
artifact.Name,
),
@@ -223,7 +222,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/azure.sh /public/%s.raw /public/%s.vhd",
"/azure.sh /artifacts/%s.raw /artifacts/%s.vhd",
artifact.Name,
artifact.Name,
),
@@ -239,7 +238,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/gce.sh /public/%s.raw /public/%s.gce.raw",
"/gce.sh /artifacts/%s.raw /artifacts/%s.gce.raw",
artifact.Name,
artifact.Name,
),
@@ -247,20 +246,6 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
VolumeMounts: volumeMounts,
}
servingContainer := v1.Container{
ImagePullPolicy: v1.PullAlways,
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
Name: "serve",
Ports: []v1.ContainerPort{v1.ContainerPort{Name: "http", ContainerPort: 80}},
Image: r.ServingImage,
VolumeMounts: []v1.VolumeMount{
{
Name: "public",
MountPath: "/usr/share/nginx/html",
},
},
}
pod := v1.PodSpec{
AutomountServiceAccountToken: &serviceAccount,
Volumes: []v1.Volume{
@@ -313,26 +298,25 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
}
if pushImage {
pod.InitContainers = append(pod.InitContainers, createImageContainer(r.ToolImage, artifact.Spec.PushOptions))
pod.Containers = []v1.Container{
createImageContainer(r.ToolImage, artifact.Spec.PushOptions),
}
}
pod.Containers = []v1.Container{servingContainer}
jobLabels := genJobLabel(artifact.Name)
deploymentLabels := genDeploymentLabel(artifact.Name)
replicas := int32(1)
return &appsv1.Deployment{
job := batchv1.Job{
ObjectMeta: objMeta,
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{MatchLabels: deploymentLabels},
Replicas: &replicas,
Spec: batchv1.JobSpec{
Selector: &metav1.LabelSelector{MatchLabels: jobLabels},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: deploymentLabels,
Labels: jobLabels,
},
Spec: pod,
},
},
}
return &job
}

View File

@@ -98,34 +98,16 @@ func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{Requeue: true}, err
}
desiredService := genService(osbuild)
logger.Info(fmt.Sprintf("Checking service %v", osbuild))
svc, err := r.clientSet.CoreV1().Services(req.Namespace).Get(ctx, desiredService.Name, v1.GetOptions{})
if svc == nil || apierrors.IsNotFound(err) {
logger.Info(fmt.Sprintf("Creating service %v", desiredService))
svc, err = r.clientSet.CoreV1().Services(req.Namespace).Create(ctx, desiredService, v1.CreateOptions{})
if err != nil {
logger.Error(err, "Failed while creating svc")
return ctrl.Result{}, err
}
return ctrl.Result{Requeue: true}, err
}
if err != nil {
return ctrl.Result{Requeue: true}, err
}
logger.Info(fmt.Sprintf("Checking deployment %v", osbuild))
desiredDeployment := r.genDeployment(osbuild, svc)
deployment, err := r.clientSet.AppsV1().Deployments(req.Namespace).Get(ctx, desiredDeployment.Name, v1.GetOptions{})
if deployment == nil || apierrors.IsNotFound(err) {
logger.Info(fmt.Sprintf("Creating Deployment %v", deployment))
desiredJob := r.genJob(osbuild)
job, err := r.clientSet.BatchV1().Jobs(req.Namespace).Get(ctx, desiredJob.Name, v1.GetOptions{})
if job == nil || apierrors.IsNotFound(err) {
logger.Info(fmt.Sprintf("Creating Job %v", job))
deployment, err = r.clientSet.AppsV1().Deployments(req.Namespace).Create(ctx, desiredDeployment, v1.CreateOptions{})
job, err = r.clientSet.BatchV1().Jobs(req.Namespace).Create(ctx, desiredJob, v1.CreateOptions{})
if err != nil {
logger.Error(err, "Failed while creating deployment")
logger.Error(err, "Failed while creating job")
return ctrl.Result{}, nil
}
@@ -143,7 +125,7 @@ func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request)
if err != nil {
return ctrl.Result{}, err
}
if deployment.Status.ReadyReplicas == deployment.Status.Replicas {
if job.Status.Succeeded > 0 {
copy.Status.Phase = "Ready"
} else if copy.Status.Phase != "Building" {
copy.Status.Phase = "Building"

View File

@@ -1,39 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers
import (
buildv1alpha1 "github.com/kairos-io/osbuilder/api/v1alpha1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func genService(artifact buildv1alpha1.OSArtifact) *v1.Service {
objMeta := metav1.ObjectMeta{
Name: artifact.Name,
Namespace: artifact.Namespace,
OwnerReferences: genOwner(artifact),
}
return &v1.Service{
ObjectMeta: objMeta,
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
Ports: []v1.ServicePort{{Name: "http", Port: int32(80)}},
Selector: genDeploymentLabel(artifact.Name),
},
}
}