diff --git a/k8s-watcher/cache.go b/k8s-watcher/cache.go index d4a1c2c9..29a53273 100644 --- a/k8s-watcher/cache.go +++ b/k8s-watcher/cache.go @@ -174,3 +174,17 @@ func NewShipwrightBuildRunCacheFromConfig(ctx context.Context, config Config, na res = &Cache{informer: informer, lister: lister, namespace: namespace, userIDLabel: config.UserIDLabel} return } + +// NewShipwrightBuildCacheFromConfig generates a new server cache from a configuration and a specfic k8s namespace. +func NewShipwrightBuildCacheFromConfig(ctx context.Context, config Config, namespace string) (res *Cache, err error) { + k8sDynamicClient, err := initializeK8sDynamicClient() + if err != nil { + return + } + resource := schema.GroupVersionResource{Group: config.ShipwrightBuildGroup, Version: config.ShipwrightBuildVersion, Resource: config.ShipwrightBuildPlural} + factory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(k8sDynamicClient, time.Minute, namespace, nil) + informer := factory.ForResource(resource).Informer() + lister := factory.ForResource(resource).Lister() + res = &Cache{informer: informer, lister: lister, namespace: namespace, userIDLabel: config.UserIDLabel} + return +} diff --git a/k8s-watcher/cache_collection.go b/k8s-watcher/cache_collection.go index 4078ce60..3863b7c6 100644 --- a/k8s-watcher/cache_collection.go +++ b/k8s-watcher/cache_collection.go @@ -179,3 +179,18 @@ func NewShipwrightBuildRunCacheCollectionFromConfigOrDie(ctx context.Context, co } return &caches } + +// NewShipwrightBuildCacheCollectionFromConfigOrDie generates a new cache map from a configuration. If it cannot +// do this successfully it will terminate the program because the server cannot run at all if this +// step fails in any way and the program cannot recover from errors that occur here. +func NewShipwrightBuildCacheCollectionFromConfigOrDie(ctx context.Context, config Config) *CacheCollection { + caches := CacheCollection{} + for _, namespace := range config.Namespaces { + cache, err := NewShipwrightBuildCacheFromConfig(ctx, config, namespace) + if err != nil { + log.Fatalf("Cannot create cache collection: %v\n", err) + } + caches[namespace] = cache + } + return &caches +} diff --git a/k8s-watcher/config.go b/k8s-watcher/config.go index 0647ace5..4827e01b 100644 --- a/k8s-watcher/config.go +++ b/k8s-watcher/config.go @@ -31,6 +31,12 @@ type Config struct { ShipwrightBuildRunVersion string // The plural name of the ShipwrightBuildRun resource that shoud be cached. ShipwrightBuildRunPlural string + // The group of the ShipwrightBuild resource that shoud be cached. + ShipwrightBuildGroup string + // The version of the ShipwrightBuild resource that shoud be cached. + ShipwrightBuildVersion string + // The plural name of the ShipwrightBuild resource that shoud be cached. + ShipwrightBuildPlural string // The port where the server will listen to for providing responses to requests // about listing the cached resources or for returning specific resources. Port int diff --git a/k8s-watcher/server.go b/k8s-watcher/server.go index 920047c7..11521cad 100644 --- a/k8s-watcher/server.go +++ b/k8s-watcher/server.go @@ -13,11 +13,12 @@ import ( // Server represents the http server and associated components that do cachcing // of k8s resources. type Server struct { - cachesJS CacheCollection - cachesAS CacheCollection - cachesIB CacheCollection - config Config - router *httprouter.Router + cachesJS CacheCollection + cachesAS CacheCollection + cachesIBr CacheCollection + cachesIB CacheCollection + config Config + router *httprouter.Router *http.Server } @@ -50,9 +51,11 @@ func (s *Server) Initialize(ctx context.Context) { s.Handler = s go s.cachesJS.run(ctx) go s.cachesAS.run(ctx) + go s.cachesIBr.run(ctx) go s.cachesIB.run(ctx) s.cachesJS.synchronize(ctx, s.config.CacheSyncTimeout) s.cachesAS.synchronize(ctx, s.config.CacheSyncTimeout) + s.cachesIBr.synchronize(ctx, s.config.CacheSyncTimeout) s.cachesIB.synchronize(ctx, s.config.CacheSyncTimeout) } @@ -75,13 +78,15 @@ func (s *Server) respond(w http.ResponseWriter, req *http.Request, data interfac func NewServerFromConfigOrDie(ctx context.Context, config Config) *Server { cacheCollectionJS := NewJupyterServerCacheCollectionFromConfigOrDie(ctx, config) cacheCollectionAS := NewAmaltheaSessionCacheCollectionFromConfigOrDie(ctx, config) - cacheCollectionIB := NewShipwrightBuildRunCacheCollectionFromConfigOrDie(ctx, config) + cacheCollectionIBr := NewShipwrightBuildRunCacheCollectionFromConfigOrDie(ctx, config) + cacheCollectionIB := NewShipwrightBuildCacheCollectionFromConfigOrDie(ctx, config) return &Server{ - config: config, - cachesJS: *cacheCollectionJS, - cachesAS: *cacheCollectionAS, - cachesIB: *cacheCollectionIB, - router: httprouter.New(), + config: config, + cachesJS: *cacheCollectionJS, + cachesAS: *cacheCollectionAS, + cachesIBr: *cacheCollectionIBr, + cachesIB: *cacheCollectionIB, + router: httprouter.New(), Server: &http.Server{ Addr: fmt.Sprintf(":%d", config.Port), }, diff --git a/k8s-watcher/server_routes.go b/k8s-watcher/server_routes.go index cad627da..8c959038 100644 --- a/k8s-watcher/server_routes.go +++ b/k8s-watcher/server_routes.go @@ -20,8 +20,10 @@ func (s *Server) registerRoutes() { s.router.HandlerFunc("GET", "/users/:userID/sessions", s.asUserID) s.router.HandlerFunc("GET", "/users/:userID/sessions/:serverID", s.asUserIDServerID) // Used for the shipwright operator in charge of image build custom resources - s.router.HandlerFunc("GET", "/buildruns", s.ibGetAll) - s.router.HandlerFunc("GET", "/buildruns/:buildID", s.ibGetOne) + s.router.HandlerFunc("GET", "/buildruns", s.ibrGetAll) + s.router.HandlerFunc("GET", "/buildruns/:buildRunID", s.ibrGetOne) + s.router.HandlerFunc("GET", "/build", s.ibGetAll) + s.router.HandlerFunc("GET", "/build/:buildID", s.ibGetOne) } func (s *Server) jsGetAll(w http.ResponseWriter, req *http.Request) { @@ -70,6 +72,16 @@ func (s *Server) asUserIDServerID(w http.ResponseWriter, req *http.Request) { s.respond(w, req, output, err) } +func (s *Server) ibrGetAll(w http.ResponseWriter, req *http.Request) { + output, err := s.cachesIBr.getAll() + s.respond(w, req, output, err) +} + +func (s *Server) ibrGetOne(w http.ResponseWriter, req *http.Request) { + params := httprouter.ParamsFromContext(req.Context()) + output, err := s.cachesIBr.getByName(params.ByName("buildRunID")) + s.respond(w, req, output, err) +} func (s *Server) ibGetAll(w http.ResponseWriter, req *http.Request) { output, err := s.cachesIB.getAll() s.respond(w, req, output, err)