@@ -23,10 +23,8 @@ import (
2323 "time"
2424
2525 v1 "k8s.io/api/core/v1"
26- apierrors "k8s.io/apimachinery/pkg/api/errors"
2726 "k8s.io/apimachinery/pkg/api/meta"
2827 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3028 "k8s.io/apimachinery/pkg/runtime"
3129 "k8s.io/apimachinery/pkg/types"
3230
@@ -37,10 +35,6 @@ import (
3735 "sigs.k8s.io/controller-runtime/pkg/log"
3836 "sigs.k8s.io/controller-runtime/pkg/reconcile"
3937
40- "sigs.k8s.io/kueue/pkg/controller/constants"
41- "sigs.k8s.io/kueue/pkg/podset"
42- utilmaps "sigs.k8s.io/kueue/pkg/util/maps"
43-
4438 workloadv1beta2 "github.com/project-codeflare/appwrapper/api/v1beta2"
4539 "github.com/project-codeflare/appwrapper/pkg/config"
4640 "github.com/project-codeflare/appwrapper/pkg/utils"
@@ -355,167 +349,6 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request)
355349 return ctrl.Result {}, nil
356350}
357351
358- // podMapFunc maps pods to appwrappers
359- func (r * AppWrapperReconciler ) podMapFunc (ctx context.Context , obj client.Object ) []reconcile.Request {
360- pod := obj .(* v1.Pod )
361- if name , ok := pod .Labels [AppWrapperLabel ]; ok {
362- if pod .Status .Phase == v1 .PodSucceeded {
363- return []reconcile.Request {{NamespacedName : types.NamespacedName {Namespace : pod .Namespace , Name : name }}}
364- }
365- }
366- return nil
367- }
368-
369- func parseComponent (aw * workloadv1beta2.AppWrapper , raw []byte ) (* unstructured.Unstructured , error ) {
370- obj := & unstructured.Unstructured {}
371- if _ , _ , err := unstructured .UnstructuredJSONScheme .Decode (raw , nil , obj ); err != nil {
372- return nil , err
373- }
374- namespace := obj .GetNamespace ()
375- if namespace == "" {
376- obj .SetNamespace (aw .Namespace )
377- } else if namespace != aw .Namespace {
378- // Should not happen, namespace equality checked by validateAppWrapperInvariants
379- return nil , fmt .Errorf ("component namespace \" %s\" is different from appwrapper namespace \" %s\" " , namespace , aw .Namespace )
380- }
381- return obj , nil
382- }
383-
384- func (r * AppWrapperReconciler ) createComponent (ctx context.Context , aw * workloadv1beta2.AppWrapper , componentIdx int ) (* unstructured.Unstructured , error , bool ) {
385- component := aw .Spec .Components [componentIdx ]
386- toMap := func (x interface {}) map [string ]string {
387- if x == nil {
388- return nil
389- } else {
390- if sm , ok := x .(map [string ]string ); ok {
391- return sm
392- } else if im , ok := x .(map [string ]interface {}); ok {
393- sm := make (map [string ]string , len (im ))
394- for k , v := range im {
395- str , ok := v .(string )
396- if ok {
397- sm [k ] = str
398- } else {
399- sm [k ] = fmt .Sprint (v )
400- }
401- }
402- return sm
403- } else {
404- return nil
405- }
406- }
407- }
408-
409- obj , err := parseComponent (aw , component .Template .Raw )
410- if err != nil {
411- return nil , err , true
412- }
413- if r .Config .StandaloneMode {
414- obj .SetLabels (utilmaps .MergeKeepFirst (obj .GetLabels (), map [string ]string {AppWrapperLabel : aw .Name }))
415- } else {
416- obj .SetLabels (utilmaps .MergeKeepFirst (obj .GetLabels (), map [string ]string {AppWrapperLabel : aw .Name , constants .QueueLabel : childJobQueueName }))
417- }
418-
419- awLabels := map [string ]string {AppWrapperLabel : aw .Name }
420- for podSetsIdx , podSet := range component .PodSets {
421- toInject := & workloadv1beta2.AppWrapperPodSetInfo {}
422- if ! r .Config .StandaloneMode {
423- toInject = & component .PodSetInfos [podSetsIdx ]
424- }
425-
426- p , err := utils .GetRawTemplate (obj .UnstructuredContent (), podSet .Path )
427- if err != nil {
428- return nil , err , true // Should not happen, path validity is enforced by validateAppWrapperInvariants
429- }
430- if md , ok := p ["metadata" ]; ! ok || md == nil {
431- p ["metadata" ] = make (map [string ]interface {})
432- }
433- metadata := p ["metadata" ].(map [string ]interface {})
434- spec := p ["spec" ].(map [string ]interface {}) // Must exist, enforced by validateAppWrapperInvariants
435-
436- // Annotations
437- if len (toInject .Annotations ) > 0 {
438- existing := toMap (metadata ["annotations" ])
439- if err := utilmaps .HaveConflict (existing , toInject .Annotations ); err != nil {
440- return nil , podset .BadPodSetsUpdateError ("annotations" , err ), true
441- }
442- metadata ["annotations" ] = utilmaps .MergeKeepFirst (existing , toInject .Annotations )
443- }
444-
445- // Labels
446- mergedLabels := utilmaps .MergeKeepFirst (toInject .Labels , awLabels )
447- existing := toMap (metadata ["labels" ])
448- if err := utilmaps .HaveConflict (existing , mergedLabels ); err != nil {
449- return nil , podset .BadPodSetsUpdateError ("labels" , err ), true
450- }
451- metadata ["labels" ] = utilmaps .MergeKeepFirst (existing , mergedLabels )
452-
453- // NodeSelectors
454- if len (toInject .NodeSelector ) > 0 {
455- existing := toMap (metadata ["nodeSelector" ])
456- if err := utilmaps .HaveConflict (existing , toInject .NodeSelector ); err != nil {
457- return nil , podset .BadPodSetsUpdateError ("nodeSelector" , err ), true
458- }
459- metadata ["nodeSelector" ] = utilmaps .MergeKeepFirst (existing , toInject .NodeSelector )
460- }
461-
462- // Tolerations
463- if len (toInject .Tolerations ) > 0 {
464- if _ , ok := spec ["tolerations" ]; ! ok {
465- spec ["tolerations" ] = []interface {}{}
466- }
467- tolerations := spec ["tolerations" ].([]interface {})
468- for _ , addition := range toInject .Tolerations {
469- tolerations = append (tolerations , addition )
470- }
471- spec ["tolerations" ] = tolerations
472- }
473- }
474-
475- if err := controllerutil .SetControllerReference (aw , obj , r .Scheme ); err != nil {
476- return nil , err , true
477- }
478-
479- if err := r .Create (ctx , obj ); err != nil {
480- if ! apierrors .IsAlreadyExists (err ) {
481- return nil , err , meta .IsNoMatchError (err ) || apierrors .IsInvalid (err ) // fatal
482- }
483- }
484-
485- return obj , nil , false
486- }
487-
488- func (r * AppWrapperReconciler ) createComponents (ctx context.Context , aw * workloadv1beta2.AppWrapper ) (error , bool ) {
489- for componentIdx := range aw .Spec .Components {
490- _ , err , fatal := r .createComponent (ctx , aw , componentIdx )
491- if err != nil {
492- return err , fatal
493- }
494- }
495- return nil , false
496- }
497-
498- func (r * AppWrapperReconciler ) deleteComponents (ctx context.Context , aw * workloadv1beta2.AppWrapper ) bool {
499- // TODO forceful deletion: See https://github.com/project-codeflare/appwrapper/issues/36
500- log := log .FromContext (ctx )
501- remaining := 0
502- for _ , component := range aw .Spec .Components {
503- obj , err := parseComponent (aw , component .Template .Raw )
504- if err != nil {
505- log .Error (err , "Parsing error" )
506- continue
507- }
508- if err := r .Delete (ctx , obj , client .PropagationPolicy (metav1 .DeletePropagationBackground )); err != nil {
509- if ! apierrors .IsNotFound (err ) {
510- log .Error (err , "Deletion error" )
511- }
512- continue
513- }
514- remaining ++ // no error deleting resource, resource therefore still exists
515- }
516- return remaining == 0
517- }
518-
519352func (r * AppWrapperReconciler ) updateStatus (ctx context.Context , aw * workloadv1beta2.AppWrapper , phase workloadv1beta2.AppWrapperPhase ) (ctrl.Result , error ) {
520353 aw .Status .Phase = phase
521354 if err := r .Status ().Update (ctx , aw ); err != nil {
@@ -615,6 +448,17 @@ func clearCondition(aw *workloadv1beta2.AppWrapper, condition workloadv1beta2.Ap
615448 }
616449}
617450
451+ // podMapFunc maps pods to appwrappers
452+ func (r * AppWrapperReconciler ) podMapFunc (ctx context.Context , obj client.Object ) []reconcile.Request {
453+ pod := obj .(* v1.Pod )
454+ if name , ok := pod .Labels [AppWrapperLabel ]; ok {
455+ if pod .Status .Phase == v1 .PodSucceeded {
456+ return []reconcile.Request {{NamespacedName : types.NamespacedName {Namespace : pod .Namespace , Name : name }}}
457+ }
458+ }
459+ return nil
460+ }
461+
618462// SetupWithManager sets up the controller with the Manager.
619463func (r * AppWrapperReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
620464 return ctrl .NewControllerManagedBy (mgr ).
0 commit comments