Skip to content

Commit d817e09

Browse files
Merge pull request #374 from grokspawn/master
OLM-2726, OCPBUGS-643: downstreaming `opm serve` changes from operator-registry
2 parents 11644a5 + aec6a49 commit d817e09

File tree

17 files changed

+1140
-394
lines changed

17 files changed

+1140
-394
lines changed

staging/operator-registry/alpha/action/generate_dockerfile.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ FROM {{.BaseImage}}
4545
4646
# Configure the entrypoint and command
4747
ENTRYPOINT ["/bin/opm"]
48-
CMD ["serve", "/configs"]
48+
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
4949
50-
# Copy declarative config root into image at /configs
50+
# Copy declarative config root into image at /configs and pre-populate serve cache
5151
ADD {{.IndexDir}} /configs
52+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
5253
5354
# Set DC-specific label for the location of the DC root directory
5455
# in the image

staging/operator-registry/alpha/action/generate_dockerfile_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ FROM foo
5050
5151
# Configure the entrypoint and command
5252
ENTRYPOINT ["/bin/opm"]
53-
CMD ["serve", "/configs"]
53+
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
5454
55-
# Copy declarative config root into image at /configs
55+
# Copy declarative config root into image at /configs and pre-populate serve cache
5656
ADD bar /configs
57+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
5758
5859
# Set DC-specific label for the location of the DC root directory
5960
# in the image
@@ -76,10 +77,11 @@ FROM foo
7677
7778
# Configure the entrypoint and command
7879
ENTRYPOINT ["/bin/opm"]
79-
CMD ["serve", "/configs"]
80+
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
8081
81-
# Copy declarative config root into image at /configs
82+
# Copy declarative config root into image at /configs and pre-populate serve cache
8283
ADD bar /configs
84+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
8385
8486
# Set DC-specific label for the location of the DC root directory
8587
# in the image

staging/operator-registry/cmd/opm/registry/serve.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func serveFunc(cmd *cobra.Command, _ []string) error {
115115

116116
lis, err := net.Listen("tcp", ":"+port)
117117
if err != nil {
118-
logger.Fatalf("failed to listen: %s", err)
118+
return fmt.Errorf("failed to listen: %s", err)
119119
}
120120

121121
timeout, err := cmd.Flags().GetString("timeout-seconds")

staging/operator-registry/cmd/opm/serve/serve.go

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,17 @@ import (
66
"errors"
77
"fmt"
88
"net"
9-
"os"
10-
"sync"
11-
129
"net/http"
1310
endpoint "net/http/pprof"
11+
"os"
1412
"runtime/pprof"
13+
"sync"
1514

1615
"github.com/sirupsen/logrus"
1716
"github.com/spf13/cobra"
1817
"google.golang.org/grpc"
1918
"google.golang.org/grpc/reflection"
2019

21-
"github.com/operator-framework/operator-registry/alpha/declcfg"
2220
"github.com/operator-framework/operator-registry/pkg/api"
2321
health "github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1"
2422
"github.com/operator-framework/operator-registry/pkg/lib/dns"
@@ -30,6 +28,8 @@ import (
3028

3129
type serve struct {
3230
configDir string
31+
cacheDir string
32+
cacheOnly bool
3333

3434
port string
3535
terminationLog string
@@ -75,12 +75,16 @@ will not be reflected in the served content.
7575
cmd.Flags().StringVarP(&s.terminationLog, "termination-log", "t", "/dev/termination-log", "path to a container termination log file")
7676
cmd.Flags().StringVarP(&s.port, "port", "p", "50051", "port number to serve on")
7777
cmd.Flags().StringVar(&s.pprofAddr, "pprof-addr", "", "address of startup profiling endpoint (addr:port format)")
78+
cmd.Flags().StringVar(&s.cacheDir, "cache-dir", "", "if set, sync and persist server cache directory")
79+
cmd.Flags().BoolVar(&s.cacheOnly, "cache-only", false, "sync the serve cache and exit without serving")
7880
return cmd
7981
}
8082

8183
func (s *serve) run(ctx context.Context) error {
8284
p := newProfilerInterface(s.pprofAddr, s.logger)
83-
p.startEndpoint()
85+
if err := p.startEndpoint(); err != nil {
86+
return fmt.Errorf("could not start pprof endpoint: %v", err)
87+
}
8488
if err := p.startCpuProfileCache(); err != nil {
8589
return fmt.Errorf("could not start CPU profile: %v", err)
8690
}
@@ -98,24 +102,18 @@ func (s *serve) run(ctx context.Context) error {
98102

99103
s.logger = s.logger.WithFields(logrus.Fields{"configs": s.configDir, "port": s.port})
100104

101-
cfg, err := declcfg.LoadFS(os.DirFS(s.configDir))
102-
if err != nil {
103-
return fmt.Errorf("load declarative config directory: %v", err)
104-
}
105-
106-
m, err := declcfg.ConvertToModel(*cfg)
107-
if err != nil {
108-
return fmt.Errorf("could not build index model from declarative config: %v", err)
109-
}
110-
store, err := registry.NewQuerier(m)
105+
store, err := registry.NewQuerierFromFS(os.DirFS(s.configDir), s.cacheDir)
111106
defer store.Close()
112107
if err != nil {
113108
return err
114109
}
110+
if s.cacheOnly {
111+
return nil
112+
}
115113

116114
lis, err := net.Listen("tcp", ":"+s.port)
117115
if err != nil {
118-
s.logger.Fatalf("failed to listen: %s", err)
116+
return fmt.Errorf("failed to listen: %s", err)
119117
}
120118

121119
grpcServer := grpc.NewServer()
@@ -129,7 +127,9 @@ func (s *serve) run(ctx context.Context) error {
129127
return grpcServer.Serve(lis)
130128
}, func() {
131129
grpcServer.GracefulStop()
132-
p.stopEndpoint(p.logger.Context)
130+
if err := p.stopEndpoint(ctx); err != nil {
131+
s.logger.Warnf("error shutting down pprof server: %v", err)
132+
}
133133
})
134134

135135
}
@@ -147,7 +147,8 @@ type profilerInterface struct {
147147
cacheReady bool
148148
cacheLock sync.RWMutex
149149

150-
logger *logrus.Entry
150+
logger *logrus.Entry
151+
closeErr chan error
151152
}
152153

153154
func newProfilerInterface(a string, log *logrus.Entry) *profilerInterface {
@@ -162,10 +163,10 @@ func (p *profilerInterface) isEnabled() bool {
162163
return p.addr != ""
163164
}
164165

165-
func (p *profilerInterface) startEndpoint() {
166+
func (p *profilerInterface) startEndpoint() error {
166167
// short-circuit if not enabled
167168
if !p.isEnabled() {
168-
return
169+
return nil
169170
}
170171

171172
mux := http.NewServeMux()
@@ -181,14 +182,22 @@ func (p *profilerInterface) startEndpoint() {
181182
Handler: mux,
182183
}
183184

184-
// goroutine exits with main
185-
go func() {
185+
lis, err := net.Listen("tcp", p.addr)
186+
if err != nil {
187+
return err
188+
}
186189

187-
p.logger.Info("starting pprof endpoint")
188-
if err := p.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
189-
p.logger.Fatal(err)
190-
}
190+
p.closeErr = make(chan error)
191+
go func() {
192+
p.closeErr <- func() error {
193+
p.logger.Info("starting pprof endpoint")
194+
if err := p.server.Serve(lis); err != nil && !errors.Is(err, http.ErrServerClosed) {
195+
return err
196+
}
197+
return nil
198+
}()
191199
}()
200+
return nil
192201
}
193202

194203
func (p *profilerInterface) startCpuProfileCache() error {
@@ -222,10 +231,14 @@ func (p *profilerInterface) httpHandler(w http.ResponseWriter, r *http.Request)
222231
w.Write(p.cache.Bytes())
223232
}
224233

225-
func (p *profilerInterface) stopEndpoint(ctx context.Context) {
234+
func (p *profilerInterface) stopEndpoint(ctx context.Context) error {
235+
if !p.isEnabled() {
236+
return nil
237+
}
226238
if err := p.server.Shutdown(ctx); err != nil {
227-
p.logger.Fatal(err)
239+
return err
228240
}
241+
return <-p.closeErr
229242
}
230243

231244
func (p *profilerInterface) isCacheReady() bool {

staging/operator-registry/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ require (
3535
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
3636
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3
3737
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
38+
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
3839
google.golang.org/grpc v1.45.0
3940
google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200709232328-d8193ee9cc3e
4041
google.golang.org/protobuf v1.28.0
@@ -148,7 +149,6 @@ require (
148149
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
149150
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect
150151
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
151-
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
152152
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
153153
golang.org/x/text v0.3.7 // indirect
154154
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect

0 commit comments

Comments
 (0)