Skip to content

Commit c61c383

Browse files
Andreea-Lupurchincha
authored andcommitted
implement scrub to check manifest/blob integrity
Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
1 parent 914cf5c commit c61c383

6 files changed

Lines changed: 841 additions & 49 deletions

File tree

pkg/api/controller.go

Lines changed: 57 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func DefaultHeaders() mux.MiddlewareFunc {
6969
}
7070
}
7171

72-
// nolint: gocyclo
7372
func (c *Controller) Run() error {
7473
// validate configuration
7574
if err := c.Config.Validate(c.Log); err != nil {
@@ -102,6 +101,62 @@ func (c *Controller) Run() error {
102101
}
103102

104103
c.Metrics = monitoring.NewMetricsServer(enabled, c.Log)
104+
105+
if err := c.InitImageStore(); err != nil {
106+
return err
107+
}
108+
109+
monitoring.SetServerInfo(c.Metrics, c.Config.Commit, c.Config.BinaryType, c.Config.GoVersion, c.Config.Version)
110+
_ = NewRouteHandler(c)
111+
112+
addr := fmt.Sprintf("%s:%s", c.Config.HTTP.Address, c.Config.HTTP.Port)
113+
server := &http.Server{
114+
Addr: addr,
115+
Handler: c.Router,
116+
IdleTimeout: idleTimeout,
117+
}
118+
c.Server = server
119+
120+
// Create the listener
121+
l, err := net.Listen("tcp", addr)
122+
if err != nil {
123+
return err
124+
}
125+
126+
if c.Config.HTTP.TLS != nil && c.Config.HTTP.TLS.Key != "" && c.Config.HTTP.TLS.Cert != "" {
127+
if c.Config.HTTP.TLS.CACert != "" {
128+
clientAuth := tls.VerifyClientCertIfGiven
129+
if (c.Config.HTTP.Auth == nil || c.Config.HTTP.Auth.HTPasswd.Path == "") && !c.Config.HTTP.AllowReadAccess {
130+
clientAuth = tls.RequireAndVerifyClientCert
131+
}
132+
133+
caCert, err := ioutil.ReadFile(c.Config.HTTP.TLS.CACert)
134+
if err != nil {
135+
panic(err)
136+
}
137+
138+
caCertPool := x509.NewCertPool()
139+
140+
if !caCertPool.AppendCertsFromPEM(caCert) {
141+
panic(errors.ErrBadCACert)
142+
}
143+
144+
server.TLSConfig = &tls.Config{
145+
ClientAuth: clientAuth,
146+
ClientCAs: caCertPool,
147+
PreferServerCipherSuites: true,
148+
MinVersion: tls.VersionTLS12,
149+
}
150+
server.TLSConfig.BuildNameToCertificate() // nolint: staticcheck
151+
}
152+
153+
return server.ServeTLS(l, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
154+
}
155+
156+
return server.Serve(l)
157+
}
158+
159+
func (c *Controller) InitImageStore() error {
105160
c.StoreController = storage.StoreController{}
106161

107162
if c.Config.Storage.RootDirectory != "" {
@@ -202,54 +257,7 @@ func (c *Controller) Run() error {
202257
ext.EnableSyncExtension(c.Config, c.wgShutDown, c.StoreController, c.Log)
203258
}
204259

205-
monitoring.SetServerInfo(c.Metrics, c.Config.Commit, c.Config.BinaryType, c.Config.GoVersion, c.Config.Version)
206-
_ = NewRouteHandler(c)
207-
208-
addr := fmt.Sprintf("%s:%s", c.Config.HTTP.Address, c.Config.HTTP.Port)
209-
server := &http.Server{
210-
Addr: addr,
211-
Handler: c.Router,
212-
IdleTimeout: idleTimeout,
213-
}
214-
c.Server = server
215-
216-
// Create the listener
217-
l, err := net.Listen("tcp", addr)
218-
if err != nil {
219-
return err
220-
}
221-
222-
if c.Config.HTTP.TLS != nil && c.Config.HTTP.TLS.Key != "" && c.Config.HTTP.TLS.Cert != "" {
223-
if c.Config.HTTP.TLS.CACert != "" {
224-
clientAuth := tls.VerifyClientCertIfGiven
225-
if (c.Config.HTTP.Auth == nil || c.Config.HTTP.Auth.HTPasswd.Path == "") && !c.Config.HTTP.AllowReadAccess {
226-
clientAuth = tls.RequireAndVerifyClientCert
227-
}
228-
229-
caCert, err := ioutil.ReadFile(c.Config.HTTP.TLS.CACert)
230-
if err != nil {
231-
panic(err)
232-
}
233-
234-
caCertPool := x509.NewCertPool()
235-
236-
if !caCertPool.AppendCertsFromPEM(caCert) {
237-
panic(errors.ErrBadCACert)
238-
}
239-
240-
server.TLSConfig = &tls.Config{
241-
ClientAuth: clientAuth,
242-
ClientCAs: caCertPool,
243-
PreferServerCipherSuites: true,
244-
MinVersion: tls.VersionTLS12,
245-
}
246-
server.TLSConfig.BuildNameToCertificate() // nolint: staticcheck
247-
}
248-
249-
return server.ServeTLS(l, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
250-
}
251-
252-
return server.Serve(l)
260+
return nil
253261
}
254262

255263
func (c *Controller) Shutdown() {

pkg/api/controller_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,48 @@ func TestNew(t *testing.T) {
9595
})
9696
}
9797

98+
func TestRunAlreadyRunningServer(t *testing.T) {
99+
Convey("Run server on unavailable port", t, func() {
100+
port := GetFreePort()
101+
baseURL := GetBaseURL(port)
102+
conf := config.New()
103+
conf.HTTP.Port = port
104+
105+
c := api.NewController(conf)
106+
107+
globalDir, err := ioutil.TempDir("", "oci-repo-test")
108+
if err != nil {
109+
panic(err)
110+
}
111+
defer os.RemoveAll(globalDir)
112+
113+
c.Config.Storage.RootDirectory = globalDir
114+
115+
go func() {
116+
if err := c.Run(); err != nil {
117+
return
118+
}
119+
}()
120+
121+
// wait till ready
122+
for {
123+
_, err := resty.R().Get(baseURL)
124+
if err == nil {
125+
break
126+
}
127+
128+
time.Sleep(100 * time.Millisecond)
129+
}
130+
defer func() {
131+
ctx := context.Background()
132+
_ = c.Server.Shutdown(ctx)
133+
}()
134+
135+
err = c.Run()
136+
So(err, ShouldNotBeNil)
137+
})
138+
}
139+
98140
func TestObjectStorageController(t *testing.T) {
99141
skipIt(t)
100142
Convey("Negative make a new object storage controller", t, func() {

pkg/cli/root.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package cli
22

33
import (
4+
"fmt"
5+
"net/http"
6+
47
glob "github.com/bmatcuk/doublestar/v4"
58
"github.com/fsnotify/fsnotify"
69
"github.com/mitchellh/mapstructure"
@@ -80,6 +83,49 @@ func NewRootCmd() *cobra.Command {
8083
},
8184
}
8285

86+
// "scrub"
87+
scrubCmd := &cobra.Command{
88+
Use: "scrub <config>",
89+
Aliases: []string{"scrub"},
90+
Short: "`scrub` checks manifest/blob integrity",
91+
Long: "`scrub` checks manifest/blob integrity",
92+
Run: func(cmd *cobra.Command, args []string) {
93+
configuration := config.New()
94+
95+
if len(args) > 0 {
96+
LoadConfiguration(configuration, args[0])
97+
} else {
98+
if err := cmd.Usage(); err != nil {
99+
panic(err)
100+
}
101+
return
102+
}
103+
104+
// checking if the server is already running
105+
response, err := http.Get(fmt.Sprintf("http://%s:%s/v2", configuration.HTTP.Address, configuration.HTTP.Port))
106+
107+
if err == nil {
108+
response.Body.Close()
109+
log.Info().Msg("The server is running, in order to perform the scrub command the server should be shut down")
110+
panic("Error: server is running")
111+
} else {
112+
// server is down
113+
c := api.NewController(configuration)
114+
115+
if err := c.InitImageStore(); err != nil {
116+
panic(err)
117+
}
118+
119+
result, err := c.StoreController.CheckAllBlobsIntegrity()
120+
if err != nil {
121+
panic(err)
122+
}
123+
124+
result.PrintScrubResults(cmd.OutOrStdout())
125+
}
126+
},
127+
}
128+
83129
verifyCmd := &cobra.Command{
84130
Use: "verify <config>",
85131
Aliases: []string{"verify"},
@@ -137,6 +183,7 @@ func NewRootCmd() *cobra.Command {
137183
}
138184

139185
rootCmd.AddCommand(serveCmd)
186+
rootCmd.AddCommand(scrubCmd)
140187
rootCmd.AddCommand(gcCmd)
141188
rootCmd.AddCommand(verifyCmd)
142189

0 commit comments

Comments
 (0)