github.com/docker/compose-on-kubernetes@v0.5.0/internal/controller/stacklistener.go (about)

     1  package controller
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/docker/compose-on-kubernetes/api/client/clientset"
     7  	"github.com/docker/compose-on-kubernetes/api/client/informers/compose/v1alpha3"
     8  	"github.com/docker/compose-on-kubernetes/api/compose/latest"
     9  	"github.com/pkg/errors"
    10  	log "github.com/sirupsen/logrus"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/client-go/tools/cache"
    13  )
    14  
    15  // StackListener listen for changes in stacks from the API
    16  type StackListener struct {
    17  	stacks                 stackIndexer
    18  	reconcileQueue         chan<- string
    19  	reconcileDeletionQueue chan<- *latest.Stack
    20  	ownerCache             StackOwnerCacher
    21  }
    22  
    23  type stackIndexer interface {
    24  	GetStore() cache.Store
    25  	Run(<-chan struct{})
    26  }
    27  
    28  func (s *StackListener) onAdd(obj interface{}) {
    29  	n, err := extractStackNameAndNamespace(obj)
    30  	if err != nil {
    31  		log.Warnf("StackListener: onAdd: %s", err)
    32  		return
    33  	}
    34  	objKey := n.objKey()
    35  	s.ownerCache.setDirty(objKey)
    36  	log.Debugf("Sending stack reconciliation request: %s", objKey)
    37  	s.reconcileQueue <- objKey
    38  }
    39  
    40  func (s *StackListener) onUpdate(_, newObj interface{}) {
    41  	n, err := extractStackNameAndNamespace(newObj)
    42  	if err != nil {
    43  		log.Warnf("StackListener: onUpdate: %s", err)
    44  		return
    45  	}
    46  	objKey := n.objKey()
    47  	s.ownerCache.setDirty(objKey)
    48  	log.Debugf("Sending stack reconciliation request: %s", objKey)
    49  	s.reconcileQueue <- objKey
    50  }
    51  
    52  func (s *StackListener) onDelete(obj interface{}) {
    53  	if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
    54  		obj = tombstone.Obj
    55  	}
    56  	stack, ok := obj.(*latest.Stack)
    57  	if !ok {
    58  		log.Warnf("StackListener: onDelete: unable to retrive deleted stack")
    59  		return
    60  	}
    61  	log.Debugf("Sending stack deletion request: %s/%s", stack.Namespace, stack.Name)
    62  	s.reconcileDeletionQueue <- stack
    63  }
    64  
    65  func (s *StackListener) get(key string) (*latest.Stack, error) {
    66  	res, exists, err := s.stacks.GetStore().GetByKey(key)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	if !exists {
    71  		return nil, errors.Errorf("not found: %s", key)
    72  	}
    73  	stack, ok := res.(*latest.Stack)
    74  	if !ok {
    75  		return nil, errors.Errorf("object with key %s is not a stack: %T", key, res)
    76  	}
    77  	return stack, nil
    78  }
    79  
    80  // Start starts the underlying informer
    81  func (s *StackListener) Start(stop chan struct{}) {
    82  	go s.stacks.Run(stop)
    83  }
    84  
    85  // NewStackListener creates a StackListener
    86  func NewStackListener(clientSet clientset.Interface,
    87  	reconciliationInterval time.Duration,
    88  	reconcileQueue chan<- string,
    89  	reconcileDeletionQueue chan<- *latest.Stack,
    90  	ownerCache StackOwnerCacher) *StackListener {
    91  	stacksInformer := v1alpha3.NewFilteredStackInformer(clientSet, reconciliationInterval, func(o *metav1.ListOptions) {})
    92  	result := &StackListener{
    93  		stacks:                 stacksInformer,
    94  		reconcileQueue:         reconcileQueue,
    95  		reconcileDeletionQueue: reconcileDeletionQueue,
    96  		ownerCache:             ownerCache,
    97  	}
    98  	stacksInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    99  		AddFunc:    result.onAdd,
   100  		UpdateFunc: result.onUpdate,
   101  		DeleteFunc: result.onDelete,
   102  	})
   103  	return result
   104  }