Skip to content

Commit

Permalink
Serve stored FBC content
Browse files Browse the repository at this point in the history
Signed-off-by: Anik <anikbhattacharya93@gmail.com>
  • Loading branch information
anik120 committed Aug 12, 2023
1 parent f48e8e9 commit 7610d7c
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 5 deletions.
12 changes: 10 additions & 2 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (

"github.com/operator-framework/catalogd/internal/source"
"github.com/operator-framework/catalogd/internal/version"
catlaogserver "github.com/operator-framework/catalogd/pkg/catalogserver"
corecontrollers "github.com/operator-framework/catalogd/pkg/controllers/core"
"github.com/operator-framework/catalogd/pkg/features"
"github.com/operator-framework/catalogd/pkg/profile"
Expand Down Expand Up @@ -67,6 +68,7 @@ func main() {
catalogdVersion bool
systemNamespace string
storageDir string
serverPort string
)
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
Expand All @@ -77,6 +79,7 @@ func main() {
flag.StringVar(&unpackImage, "unpack-image", "quay.io/operator-framework/rukpak:v0.12.0", "The unpack image to use when unpacking catalog images")
flag.StringVar(&systemNamespace, "system-namespace", "", "The namespace catalogd uses for internal state, configuration, and workloads")
flag.StringVar(&storageDir, "catalogs-storage-dir", "/var/cache", "The directory in the filesystem where unpacked catalog content will be stored and served from")
flag.StringVar(&serverPort, "catalogs-server-port", ":8083", "The port where the unpacked catalogs' content will be accessible")
flag.BoolVar(&profiling, "profiling", false, "enable profiling endpoints to allow for using pprof")
flag.BoolVar(&catalogdVersion, "version", false, "print the catalogd version and exit")
opts := zap.Options{
Expand Down Expand Up @@ -119,10 +122,16 @@ func main() {
os.Exit(1)
}

catalogServer := catlaogserver.NewServer(storageDir, serverPort)
if err := mgr.Add(catalogServer); err != nil {
setupLog.Error(err, "unable to start catalog server")
os.Exit(1)
}

if err = (&corecontrollers.CatalogReconciler{
Client: mgr.GetClient(),
Unpacker: unpacker,
Storage: storage.NewStorage(storageDir),
Storage: storage.NewStorage(storageDir, catalogServer.Mux),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Catalog")
os.Exit(1)
Expand All @@ -145,7 +154,6 @@ func main() {
os.Exit(1)
}
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
Expand Down
12 changes: 12 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,17 @@ spec:
- "./manager"
args:
- --leader-elect
- "--catalogs-storage-dir=/var/cache"
- "--catalogs-server-port=:8083"
image: controller:latest
name: manager
ports:
- containerPort: 8083
protocol: TCP
name: https
volumeMounts:
- name: catalog-cache
mountPath: /var/cache/
securityContext:
allowPrivilegeEscalation: false
capabilities:
Expand All @@ -73,3 +82,6 @@ spec:
imagePullPolicy: IfNotPresent
serviceAccountName: controller-manager
terminationGracePeriodSeconds: 10
volumes:
- name: catalog-cache
emptyDir: {}
50 changes: 50 additions & 0 deletions pkg/catalogserver/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package catalogserver

import (
"context"
"fmt"
"net/http"
"os"
"path/filepath"
"time"
)

// Server is a manager.Runnable Server, that serves the FBC
// content of the extension catalogs added to the cluster
type Server struct {
Dir string
Port string
Mux *http.ServeMux
}

// NewServer takes directory and port number, and returns
// a Server that serves the FBC content stored in the
// directory on the given port number.
func NewServer(dir, port string) Server {
return Server{
Dir: dir,
Port: port,
Mux: &http.ServeMux{},
}
}

func (s Server) Start(_ context.Context) error {
s.Mux.HandleFunc("/catalogs", func(w http.ResponseWriter, r *http.Request) {
files, err := os.ReadDir(s.Dir)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "error reading catalog store directory: %v", err)
return
}
for _, file := range files {
name := file.Name()
fmt.Fprintf(w, "%v\n", name[:len(name)-len(filepath.Ext(name))])
}
})
server := &http.Server{
Handler: s.Mux,
Addr: s.Port,
ReadHeaderTimeout: 3 * time.Second,
}
return server.ListenAndServe()
}
4 changes: 2 additions & 2 deletions pkg/controllers/core/catalog_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ func (r *CatalogReconciler) reconcile(ctx context.Context, catalog *v1alpha1.Cat
// of the unpacking steps.

fbc, err := declcfg.LoadFS(unpackResult.FS)
if err := r.Storage.Store(ctx, catalog, fbc); err != nil {
return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("storing fbc: %v", err))
if err := r.Storage.Store(catalog.Name, fbc); err != nil {
return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("error storing fbc: %v", err))

Check warning on line 150 in pkg/controllers/core/catalog_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/core/catalog_controller.go#L150

Added line #L150 was not covered by tests
}
if err != nil {
return ctrl.Result{}, updateStatusUnpackFailing(&catalog.Status, fmt.Errorf("load FBC from filesystem: %v", err))
Expand Down
5 changes: 5 additions & 0 deletions pkg/controllers/core/catalog_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"os"
"testing/fstest"

Expand All @@ -22,6 +23,7 @@ import (
"github.com/operator-framework/catalogd/internal/source"
"github.com/operator-framework/catalogd/pkg/controllers/core"
"github.com/operator-framework/catalogd/pkg/features"
"github.com/operator-framework/catalogd/pkg/storage"
)

var _ source.Unpacker = &MockSource{}
Expand Down Expand Up @@ -51,6 +53,8 @@ var _ = Describe("Catalogd Controller Test", func() {
mockSource *MockSource
)
BeforeEach(func() {
tmpDir, err := os.MkdirTemp(GinkgoT().TempDir(), "cache")
Expect(err).To(BeNil())

Check failure on line 57 in pkg/controllers/core/catalog_controller_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong error assertion; consider using `Expect(err).ToNot(HaveOccurred())` instead (ginkgolinter)
ctx = context.Background()
mockSource = &MockSource{}
reconciler = &core.CatalogReconciler{
Expand All @@ -60,6 +64,7 @@ var _ = Describe("Catalogd Controller Test", func() {
v1alpha1.SourceTypeImage: mockSource,
},
),
Storage: storage.NewStorage(tmpDir, http.NewServeMux()),
}
})

Expand Down
12 changes: 11 additions & 1 deletion pkg/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package storage
import (
"errors"
"fmt"
"net/http"
"os"
"path/filepath"

Expand All @@ -13,11 +14,13 @@ import (
// It can be used to Store or Delete FBC in the host's filesystem
type Storage struct {
RootDirectory string
ServerMux *http.ServeMux
}

func NewStorage(rootDir string) Storage {
func NewStorage(rootDir string, mux *http.ServeMux) Storage {
return Storage{
RootDirectory: rootDir,
ServerMux: mux,
}
}

Expand All @@ -31,13 +34,20 @@ func (s *Storage) Store(owner string, fbc *declcfg.DeclarativeConfig) error {
if err := declcfg.WriteJSON(*fbc, fbcFile); err != nil {
return err
}
s.registerFileForServing(s.ServerMux, owner)
return nil
}

func (s *Storage) Delete(owner string) error {
return ignoreNotExist(os.Remove(s.fbcPath(owner)))
}

func (s *Storage) registerFileForServing(mux *http.ServeMux, name string) {
mux.HandleFunc(fmt.Sprintf("/catalogs/%s", name), func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filepath.Join(s.RootDirectory, fmt.Sprintf("%s.json", name)))
})
}

func (s *Storage) fbcPath(catalogName string) string {
return filepath.Join(s.RootDirectory, fmt.Sprintf("%s.json", catalogName))
}
Expand Down

0 comments on commit 7610d7c

Please sign in to comment.