mirror of
https://github.com/kairos-io/osbuilder.git
synced 2025-05-31 11:05:10 +00:00
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:
parent
658b816c1d
commit
44a48d7890
@ -16,6 +16,7 @@ bases:
|
|||||||
- ../crd
|
- ../crd
|
||||||
- ../rbac
|
- ../rbac
|
||||||
- ../manager
|
- ../manager
|
||||||
|
- ../nginx
|
||||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
|
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
|
||||||
# crd/kustomization.yaml
|
# crd/kustomization.yaml
|
||||||
#- ../webhook
|
#- ../webhook
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
resources:
|
resources:
|
||||||
- manager.yaml
|
- manager.yaml
|
||||||
|
|
||||||
|
namespace: system
|
||||||
|
|
||||||
generatorOptions:
|
generatorOptions:
|
||||||
disableNameSuffixHash: true
|
disableNameSuffixHash: true
|
||||||
|
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
control-plane: controller-manager
|
|
||||||
name: system
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: controller-manager
|
name: controller-manager
|
||||||
namespace: system
|
|
||||||
labels:
|
labels:
|
||||||
control-plane: controller-manager
|
control-plane: controller-manager
|
||||||
spec:
|
spec:
|
||||||
|
41
config/nginx/deployment.yaml
Normal file
41
config/nginx/deployment.yaml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: nginx-public
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 3Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: osbuilder-nginx
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: osbuilder-nginx
|
||||||
|
replicas: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: osbuilder-nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: "/usr/share/nginx/html"
|
||||||
|
name: nginx-public
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
serviceAccountName: controller-manager
|
||||||
|
terminationGracePeriodSeconds: 10
|
||||||
|
volumes:
|
||||||
|
- name: nginx-public
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: nginx-public
|
3
config/nginx/kustomization.yaml
Normal file
3
config/nginx/kustomization.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
12
config/nginx/service.yaml
Normal file
12
config/nginx/service.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: osbuilder-nginx
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: osbuilder-nginx
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
@ -47,9 +47,9 @@ rules:
|
|||||||
- create
|
- create
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- "apps"
|
- "batch"
|
||||||
resources:
|
resources:
|
||||||
- deployments
|
- jobs
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- create
|
- create
|
||||||
|
@ -20,13 +20,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
buildv1alpha1 "github.com/kairos-io/osbuilder/api/v1alpha1"
|
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"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/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{
|
return map[string]string{
|
||||||
"osbuild": "workload" + s,
|
"osbuild": "workload" + s,
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ func createImageContainer(containerImage string, pushOptions buildv1alpha1.Push)
|
|||||||
Command: []string{"/bin/bash", "-cxe"},
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf(
|
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,
|
pushOptions.ImageName,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -74,8 +74,8 @@ func createImageContainer(containerImage string, pushOptions buildv1alpha1.Push)
|
|||||||
MountPath: "/rootfs",
|
MountPath: "/rootfs",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "public",
|
Name: "artifacts",
|
||||||
MountPath: "/public",
|
MountPath: "/artifacts",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -104,8 +104,7 @@ func osReleaseContainer(containerImage string) v1.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact, svc *v1.Service) *appsv1.Deployment {
|
func (r *OSArtifactReconciler) genJob(artifact buildv1alpha1.OSArtifact) *batchv1.Job {
|
||||||
// TODO: svc is unused, but could be used in the future to generate the Netboot URL
|
|
||||||
objMeta := metav1.ObjectMeta{
|
objMeta := metav1.ObjectMeta{
|
||||||
Name: artifact.Name,
|
Name: artifact.Name,
|
||||||
Namespace: artifact.Namespace,
|
Namespace: artifact.Namespace,
|
||||||
@ -118,14 +117,14 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
serviceAccount := false
|
serviceAccount := false
|
||||||
|
|
||||||
cmd := fmt.Sprintf(
|
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,
|
artifact.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
volumeMounts := []v1.VolumeMount{
|
volumeMounts := []v1.VolumeMount{
|
||||||
{
|
{
|
||||||
Name: "public",
|
Name: "artifacts",
|
||||||
MountPath: "/public",
|
MountPath: "/artifacts",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "rootfs",
|
Name: "rootfs",
|
||||||
@ -142,7 +141,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cloudImgCmd := fmt.Sprintf(
|
cloudImgCmd := fmt.Sprintf(
|
||||||
"/raw-images.sh /rootfs /public/%s.raw",
|
"/raw-images.sh /rootfs /artifacts/%s.raw",
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -158,7 +157,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
|
|
||||||
if artifact.Spec.CloudConfig != "" || artifact.Spec.GRUBConfig != "" {
|
if artifact.Spec.CloudConfig != "" || artifact.Spec.GRUBConfig != "" {
|
||||||
cmd = fmt.Sprintf(
|
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,
|
artifact.Name,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -207,7 +206,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
}},
|
}},
|
||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"/netboot.sh /public/%s.iso /public/%s",
|
"/netboot.sh /artifacts/%s.iso /artifacts/%s",
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
),
|
),
|
||||||
@ -223,7 +222,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
Command: []string{"/bin/bash", "-cxe"},
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"/azure.sh /public/%s.raw /public/%s.vhd",
|
"/azure.sh /artifacts/%s.raw /artifacts/%s.vhd",
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
),
|
),
|
||||||
@ -239,7 +238,7 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
Command: []string{"/bin/bash", "-cxe"},
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"/gce.sh /public/%s.raw /public/%s.gce.raw",
|
"/gce.sh /artifacts/%s.raw /artifacts/%s.gce.raw",
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
),
|
),
|
||||||
@ -247,20 +246,6 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
VolumeMounts: volumeMounts,
|
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{
|
pod := v1.PodSpec{
|
||||||
AutomountServiceAccountToken: &serviceAccount,
|
AutomountServiceAccountToken: &serviceAccount,
|
||||||
Volumes: []v1.Volume{
|
Volumes: []v1.Volume{
|
||||||
@ -313,26 +298,25 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pushImage {
|
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)
|
job := batchv1.Job{
|
||||||
replicas := int32(1)
|
|
||||||
|
|
||||||
return &appsv1.Deployment{
|
|
||||||
ObjectMeta: objMeta,
|
ObjectMeta: objMeta,
|
||||||
|
Spec: batchv1.JobSpec{
|
||||||
Spec: appsv1.DeploymentSpec{
|
Selector: &metav1.LabelSelector{MatchLabels: jobLabels},
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: deploymentLabels},
|
|
||||||
Replicas: &replicas,
|
|
||||||
Template: v1.PodTemplateSpec{
|
Template: v1.PodTemplateSpec{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Labels: deploymentLabels,
|
Labels: jobLabels,
|
||||||
},
|
},
|
||||||
Spec: pod,
|
Spec: pod,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &job
|
||||||
}
|
}
|
@ -98,34 +98,16 @@ func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
|||||||
return ctrl.Result{Requeue: true}, err
|
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))
|
logger.Info(fmt.Sprintf("Checking deployment %v", osbuild))
|
||||||
|
|
||||||
desiredDeployment := r.genDeployment(osbuild, svc)
|
desiredJob := r.genJob(osbuild)
|
||||||
deployment, err := r.clientSet.AppsV1().Deployments(req.Namespace).Get(ctx, desiredDeployment.Name, v1.GetOptions{})
|
job, err := r.clientSet.BatchV1().Jobs(req.Namespace).Get(ctx, desiredJob.Name, v1.GetOptions{})
|
||||||
if deployment == nil || apierrors.IsNotFound(err) {
|
if job == nil || apierrors.IsNotFound(err) {
|
||||||
logger.Info(fmt.Sprintf("Creating Deployment %v", deployment))
|
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 {
|
if err != nil {
|
||||||
logger.Error(err, "Failed while creating deployment")
|
logger.Error(err, "Failed while creating job")
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +125,7 @@ func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
if deployment.Status.ReadyReplicas == deployment.Status.Replicas {
|
if job.Status.Succeeded > 0 {
|
||||||
copy.Status.Phase = "Ready"
|
copy.Status.Phase = "Ready"
|
||||||
} else if copy.Status.Phase != "Building" {
|
} else if copy.Status.Phase != "Building" {
|
||||||
copy.Status.Phase = "Building"
|
copy.Status.Phase = "Building"
|
||||||
|
@ -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),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user