@@ -31,8 +31,9 @@ import (
3131// done so that clients accessing the content stored in RootDir/catalogName have
3232// atomic view of the content for a catalog.
3333type LocalDirV1 struct {
34- RootDir string
35- RootURL * url.URL
34+ RootDir string
35+ RootURL * url.URL
36+ EnableQueryHandler bool
3637
3738 m sync.RWMutex
3839 sf singleflight.Group
@@ -42,7 +43,7 @@ func (s *LocalDirV1) Store(ctx context.Context, catalog string, fsys fs.FS) erro
4243 s .m .Lock ()
4344 defer s .m .Unlock ()
4445
45- if features . CatalogdFeatureGate . Enabled ( features . APIV1QueryHandler ) {
46+ if s . EnableQueryHandler {
4647 return s .storeCatalogFileAndIndex (ctx , catalog , fsys )
4748 }
4849 return s .storeCatalogFile (ctx , catalog , fsys )
@@ -88,30 +89,33 @@ func (s *LocalDirV1) storeCatalogFileAndIndex(ctx context.Context, catalog strin
8889 }
8990 defer os .Remove (tmpIndexFile .Name ())
9091
91- pr , pw := io .Pipe ()
92- mw := io .MultiWriter (tmpCatalogFile , pw )
92+ metasChan := make (chan * declcfg.Meta )
9393 eg , egCtx := errgroup .WithContext (ctx )
9494 eg .Go (func () error {
95+ defer close (metasChan )
9596 if err := declcfg .WalkMetasFS (egCtx , fsys , func (path string , meta * declcfg.Meta , err error ) error {
9697 if err != nil {
9798 return err
9899 }
99- _ , err = mw .Write (meta .Blob )
100+ _ , err = tmpCatalogFile .Write (meta .Blob )
100101 if err != nil {
101- return pw . CloseWithError ( err )
102+ return err
102103 }
104+ select {
105+ case <- egCtx .Done ():
106+ return egCtx .Err ()
107+ case metasChan <- meta :
108+ }
109+
103110 return nil
104111 }, declcfg .WithConcurrency (1 )); err != nil {
105112 return fmt .Errorf ("error walking FBC root: %w" , err )
106113 }
107- return pw . CloseWithError ( tmpCatalogFile .Close () )
114+ return tmpCatalogFile .Close ()
108115 })
109116 eg .Go (func () error {
110- idx , err := newIndex (pr )
117+ idx , err := newIndex (metasChan )
111118 if err != nil {
112- return pr .CloseWithError (err )
113- }
114- if err := pr .Close (); err != nil {
115119 return err
116120 }
117121 enc := json .NewEncoder (tmpIndexFile )
@@ -142,7 +146,7 @@ func (s *LocalDirV1) Delete(catalog string) error {
142146 var errs []error
143147 errs = append (errs , os .RemoveAll (filepath .Join (s .RootDir , fmt .Sprintf ("%s.jsonl" , catalog ))))
144148
145- if features . CatalogdFeatureGate . Enabled ( features . APIV1QueryHandler ) {
149+ if s . EnableQueryHandler {
146150 errs = append (errs , os .RemoveAll (filepath .Join (s .RootDir , fmt .Sprintf ("%s.index.json" , catalog ))))
147151 }
148152 return errors .Join (errs ... )
@@ -158,7 +162,7 @@ func (s *LocalDirV1) StorageServerHandler() http.Handler {
158162 v1AllPath := s .RootURL .JoinPath ("{catalog}" , "api" , "v1" , "all" ).Path
159163 mux .Handle (v1AllPath , s .v1AllHandler ())
160164
161- if features . CatalogdFeatureGate . Enabled ( features . APIV1QueryHandler ) {
165+ if s . EnableQueryHandler {
162166 v1QueryPath := s .RootURL .JoinPath ("{catalog}" , "api" , "v1" , "query" ).Path
163167 mux .Handle (v1QueryPath , s .v1QueryHandler ())
164168 }
@@ -171,16 +175,11 @@ func (s *LocalDirV1) v1AllHandler() http.Handler {
171175 defer s .m .RUnlock ()
172176
173177 catalog := r .PathValue ("catalog" )
178+ w .Header ().Add ("Content-Type" , "application/jsonl" )
174179 http .ServeFile (w , r , filepath .Join (s .RootDir , fmt .Sprintf ("%s.jsonl" , catalog )))
175180 })
176181 gzHandler := gzhttp .GzipHandler (catalogHandler )
177-
178- typeHandler := http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
179- w .Header ().Add ("Content-Type" , "application/jsonl" )
180- gzHandler .ServeHTTP (w , r )
181- })
182-
183- return newLoggingMiddleware (typeHandler )
182+ return newLoggingMiddleware (gzHandler )
184183}
185184
186185func (s * LocalDirV1 ) v1QueryHandler () http.Handler {
@@ -193,6 +192,13 @@ func (s *LocalDirV1) v1QueryHandler() http.Handler {
193192 pkg := r .URL .Query ().Get ("package" )
194193 name := r .URL .Query ().Get ("name" )
195194
195+ // If no parameters are provided, return the entire catalog (this is the same as /api/v1/all)
196+ if schema == "" && pkg == "" && name == "" {
197+ w .Header ().Add ("Content-Type" , "application/jsonl" )
198+ http .ServeFile (w , r , filepath .Join (s .RootDir , fmt .Sprintf ("%s.jsonl" , catalog )))
199+ return
200+ }
201+
196202 catalogFilePath := filepath .Join (s .RootDir , fmt .Sprintf ("%s.jsonl" , catalog ))
197203 catalogFileStat , err := os .Stat (catalogFilePath )
198204 if err != nil {
0 commit comments