Resolve docker.NewResolver race condition

Signed-off-by: Jin Dong <djdongjin95@gmail.com>
This commit is contained in:
Jin Dong 2023-06-27 12:22:01 +00:00 committed by Jin Dong
parent 3c250cb508
commit cdb153ec92
2 changed files with 28 additions and 1 deletions

View File

@ -148,7 +148,11 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
if options.Headers == nil { if options.Headers == nil {
options.Headers = make(http.Header) options.Headers = make(http.Header)
} else {
// make a copy of the headers to avoid race due to concurrent map write
options.Headers = options.Headers.Clone()
} }
if _, ok := options.Headers["User-Agent"]; !ok { if _, ok := options.Headers["User-Agent"]; !ok {
options.Headers.Set("User-Agent", "containerd/"+version.Version) options.Headers.Set("User-Agent", "containerd/"+version.Version)
} }

View File

@ -46,7 +46,6 @@ func TestHTTPResolver(t *testing.T) {
base := s.URL[7:] // strip "http://" base := s.URL[7:] // strip "http://"
return base, options, s.Close return base, options, s.Close
} }
runBasicTest(t, "testname", s) runBasicTest(t, "testname", s)
} }
@ -54,6 +53,30 @@ func TestHTTPSResolver(t *testing.T) {
runBasicTest(t, "testname", tlsServer) runBasicTest(t, "testname", tlsServer)
} }
func TestResolverOptionsRace(t *testing.T) {
header := http.Header{}
header.Set("X-Test", "test")
s := func(h http.Handler) (string, ResolverOptions, func()) {
s := httptest.NewServer(h)
options := ResolverOptions{
Headers: header,
}
base := s.URL[7:] // strip "http://"
return base, options, s.Close
}
for i := 0; i < 5; i++ {
t.Run(fmt.Sprintf("test ResolverOptions race %d", i), func(t *testing.T) {
// parallel sub tests so the race condition (if not handled) can be caught
// by race detector
t.Parallel()
runBasicTest(t, "testname", s)
})
}
}
func TestBasicResolver(t *testing.T) { func TestBasicResolver(t *testing.T) {
basicAuth := func(h http.Handler) (string, ResolverOptions, func()) { basicAuth := func(h http.Handler) (string, ResolverOptions, func()) {
// Wrap with basic auth // Wrap with basic auth