update controller

This commit is contained in:
Lukasz Zajaczkowski
2025-01-20 11:38:59 +01:00
parent 7c34046e54
commit 744baa9f1d
12 changed files with 3546 additions and 1330 deletions

View File

@@ -90,6 +90,12 @@ const (
type OSArtifactStatus struct {
// +kubebuilder:default=Pending
Phase ArtifactPhase `json:"phase,omitempty"`
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}
//+kubebuilder:object:root=true

View File

@@ -23,6 +23,7 @@ package v1alpha2
import (
batchv1 "k8s.io/api/batch/v1"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -32,7 +33,7 @@ func (in *OSArtifact) DeepCopyInto(out *OSArtifact) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSArtifact.
@@ -147,6 +148,13 @@ func (in *OSArtifactSpec) DeepCopy() *OSArtifactSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OSArtifactStatus) DeepCopyInto(out *OSArtifactStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSArtifactStatus.

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,7 @@ spec:
securityContext:
allowPrivilegeEscalation: false
- args:
- --pvc-storage-size={{ .Values.pvcStorageSize }}
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect

View File

@@ -15,6 +15,9 @@ image:
# tag of the controller image. Leave empty to use chart's AppVersion
tag:
# The PVC storage size for the build process
pvcStorageSize: "20Gi"
toolsImage:
repository: "quay.io/kairos/auroraboot"
tag: "latest"

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,7 @@ stringData:
local_file: true
plural:
token:
token: abc
url: https://console.plrl-dev-aws.onplural.sh
---
kind: OSArtifact

View File

@@ -151,9 +151,9 @@ func (r *OSArtifactReconciler) newArtifactPVC(artifact *osbuilder.OSArtifact) *c
AccessModes: []corev1.PersistentVolumeAccessMode{
corev1.ReadWriteOnce,
},
Resources: corev1.ResourceRequirements{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
"storage": resource.MustParse("20Gi"),
"storage": resource.MustParse(r.PVCStorage),
},
},
}

View File

@@ -19,6 +19,11 @@ package controllers
import (
"context"
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/errors"
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
batchv1 "k8s.io/api/batch/v1"
@@ -26,6 +31,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -35,25 +41,25 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)
const (
requeueAfter = 5 * time.Second
FinalizerName = "build.kairos.io/osbuilder-finalizer"
artifactLabel = "build.kairos.io/artifact"
artifactExporterIndexAnnotation = "build.kairos.io/export-index"
ready = "Ready"
)
var (
requeue = ctrl.Result{RequeueAfter: requeueAfter}
)
// OSArtifactReconciler reconciles a OSArtifact object
type OSArtifactReconciler struct {
client.Client
ServingImage, ToolImage, CopierImage string
}
func (r *OSArtifactReconciler) InjectClient(c client.Client) error {
r.Client = c
return nil
Scheme *runtime.Scheme
ServingImage, ToolImage, CopierImage, PVCStorage string
}
//+kubebuilder:rbac:groups=build.kairos.io,resources=osartifacts,verbs=get;list;watch;create;update;patch;delete
@@ -68,22 +74,33 @@ func (r *OSArtifactReconciler) InjectClient(c client.Client) error {
func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)
var artifact osbuilder.OSArtifact
if err := r.Get(ctx, req.NamespacedName, &artifact); err != nil {
artifact := new(osbuilder.OSArtifact)
if err := r.Get(ctx, req.NamespacedName, artifact); err != nil {
if apierrors.IsNotFound(err) {
return ctrl.Result{}, nil
}
return ctrl.Result{Requeue: true}, err
}
if artifact.DeletionTimestamp != nil {
controllerutil.RemoveFinalizer(&artifact, FinalizerName)
return ctrl.Result{}, r.Update(ctx, &artifact)
if len(artifact.Status.Conditions) == 0 {
artifact.Status.Conditions = []metav1.Condition{}
meta.SetStatusCondition(&artifact.Status.Conditions, metav1.Condition{
Type: ready,
Reason: ready,
Status: metav1.ConditionFalse,
})
if err := r.Status().Update(ctx, artifact); err != nil {
return ctrl.Result{Requeue: true}, err
}
}
if !controllerutil.ContainsFinalizer(&artifact, FinalizerName) {
controllerutil.AddFinalizer(&artifact, FinalizerName)
if err := r.Update(ctx, &artifact); err != nil {
if artifact.DeletionTimestamp != nil {
controllerutil.RemoveFinalizer(artifact, FinalizerName)
return ctrl.Result{}, r.Update(ctx, artifact)
}
if !controllerutil.ContainsFinalizer(artifact, FinalizerName) {
controllerutil.AddFinalizer(artifact, FinalizerName)
if err := r.Update(ctx, artifact); err != nil {
return ctrl.Result{Requeue: true}, err
}
}
@@ -92,11 +109,23 @@ func (r *OSArtifactReconciler) Reconcile(ctx context.Context, req ctrl.Request)
switch artifact.Status.Phase {
case osbuilder.Exporting:
return r.checkExport(ctx, &artifact)
case osbuilder.Ready, osbuilder.Error:
return ctrl.Result{}, nil
return r.checkExport(ctx, artifact)
case osbuilder.Ready:
meta.SetStatusCondition(&artifact.Status.Conditions, metav1.Condition{
Type: ready,
Reason: ready,
Status: metav1.ConditionTrue,
})
return ctrl.Result{}, r.Status().Update(ctx, artifact)
case osbuilder.Error:
meta.SetStatusCondition(&artifact.Status.Conditions, metav1.Condition{
Type: "Ready",
Status: metav1.ConditionFalse,
Reason: "Error",
})
return ctrl.Result{}, r.Status().Update(ctx, artifact)
default:
return r.checkBuild(ctx, &artifact)
return r.checkBuild(ctx, artifact)
}
}
@@ -108,7 +137,7 @@ func (r *OSArtifactReconciler) CreateConfigMap(ctx context.Context, artifact *os
cm.Labels = map[string]string{}
}
cm.Labels[artifactLabel] = artifact.Name
if err := controllerutil.SetOwnerReference(artifact, cm, r.Scheme()); err != nil {
if err := controllerutil.SetOwnerReference(artifact, cm, r.Scheme); err != nil {
return err
}
if err := r.Create(ctx, cm); err != nil && !apierrors.IsAlreadyExists(err) {
@@ -124,7 +153,7 @@ func (r *OSArtifactReconciler) createPVC(ctx context.Context, artifact *osbuilde
pvc.Labels = map[string]string{}
}
pvc.Labels[artifactLabel] = artifact.Name
if err := controllerutil.SetOwnerReference(artifact, pvc, r.Scheme()); err != nil {
if err := controllerutil.SetOwnerReference(artifact, pvc, r.Scheme); err != nil {
return pvc, err
}
if err := r.Create(ctx, pvc); err != nil {
@@ -140,7 +169,7 @@ func (r *OSArtifactReconciler) createBuilderPod(ctx context.Context, artifact *o
pod.Labels = map[string]string{}
}
pod.Labels[artifactLabel] = artifact.Name
if err := controllerutil.SetOwnerReference(artifact, pod, r.Scheme()); err != nil {
if err := controllerutil.SetOwnerReference(artifact, pod, r.Scheme); err != nil {
return pod, err
}
@@ -152,6 +181,17 @@ func (r *OSArtifactReconciler) createBuilderPod(ctx context.Context, artifact *o
}
func (r *OSArtifactReconciler) startBuild(ctx context.Context, artifact *osbuilder.OSArtifact) (ctrl.Result, error) {
logger := log.FromContext(ctx)
if artifact.Spec.CloudConfigRef != nil {
if err := r.Get(ctx, client.ObjectKey{Namespace: artifact.Namespace, Name: artifact.Spec.CloudConfigRef.Name}, &corev1.Secret{}); err != nil {
if errors.IsNotFound(err) {
logger.Info(fmt.Sprintf("Secret %s/%s not found", artifact.Namespace, artifact.Spec.CloudConfigRef.Name))
return requeue, nil
}
return ctrl.Result{}, err
}
}
err := r.CreateConfigMap(ctx, artifact)
if err != nil {
return ctrl.Result{Requeue: true}, err
@@ -266,7 +306,7 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
},
})
if err := controllerutil.SetOwnerReference(artifact, job, r.Scheme()); err != nil {
if err := controllerutil.SetOwnerReference(artifact, job, r.Scheme); err != nil {
return ctrl.Result{Requeue: true}, err
}
@@ -303,19 +343,19 @@ func (r *OSArtifactReconciler) SetupWithManager(mgr ctrl.Manager) error {
For(&osbuilder.OSArtifact{}).
Owns(&osbuilder.OSArtifact{}).
Watches(
&source.Kind{Type: &corev1.Pod{}},
&corev1.Pod{},
handler.EnqueueRequestsFromMapFunc(r.findOwningArtifact),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
).
Watches(
&source.Kind{Type: &batchv1.Job{}},
&batchv1.Job{},
handler.EnqueueRequestsFromMapFunc(r.findOwningArtifact),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
).
Complete(r)
}
func (r *OSArtifactReconciler) findOwningArtifact(obj client.Object) []reconcile.Request {
func (r *OSArtifactReconciler) findOwningArtifact(_ context.Context, obj client.Object) []reconcile.Request {
if obj.GetLabels() == nil {
return nil
}

109
go.mod
View File

@@ -3,83 +3,74 @@ module github.com/kairos-io/osbuilder
go 1.23.4
require (
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
k8s.io/api v0.24.0
k8s.io/apimachinery v0.24.0
k8s.io/client-go v0.24.0
sigs.k8s.io/controller-runtime v0.12.1
github.com/samber/lo v1.47.0
k8s.io/api v0.32.1
k8s.io/apimachinery v0.32.1
k8s.io/client-go v0.32.1
sigs.k8s.io/cluster-api v1.9.3
sigs.k8s.io/controller-runtime v0.20.0
)
require (
cloud.google.com/go v0.93.3 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful v2.16.0+incompatible // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/zapr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.34.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.28.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.36.1 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.24.0 // indirect
k8s.io/component-base v0.24.0 // indirect
k8s.io/klog/v2 v2.60.1 // indirect
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
k8s.io/apiextensions-apiserver v0.32.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

1157
go.sum

File diff suppressed because it is too large Load Diff

12
main.go
View File

@@ -20,6 +20,8 @@ import (
"flag"
"os"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
@@ -52,7 +54,9 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
var serveImage, toolImage, copierImage string
var serveImage, toolImage, copierImage, pvcStorage string
flag.StringVar(&pvcStorage, "pvc-storage-size", "20Gi", "The PVC storage size for building process")
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
@@ -73,8 +77,7 @@ func main() {
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
Metrics: metricsserver.Options{BindAddress: metricsAddr},
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "98ca89ca.kairos.io",
@@ -96,9 +99,12 @@ func main() {
}
if err = (&controllers.OSArtifactReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ServingImage: serveImage,
ToolImage: toolImage,
CopierImage: copierImage,
PVCStorage: pvcStorage,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "OSArtifact")
os.Exit(1)