github.com/damirazo/docker@v1.9.0/integration-cli/registry.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "os/exec" 9 "path/filepath" 10 11 "github.com/docker/distribution/digest" 12 "github.com/go-check/check" 13 ) 14 15 const v2binary = "registry-v2" 16 17 type testRegistryV2 struct { 18 cmd *exec.Cmd 19 dir string 20 } 21 22 func newTestRegistryV2(c *check.C) (*testRegistryV2, error) { 23 template := `version: 0.1 24 loglevel: debug 25 storage: 26 filesystem: 27 rootdirectory: %s 28 http: 29 addr: %s` 30 tmp, err := ioutil.TempDir("", "registry-test-") 31 if err != nil { 32 return nil, err 33 } 34 confPath := filepath.Join(tmp, "config.yaml") 35 config, err := os.Create(confPath) 36 if err != nil { 37 return nil, err 38 } 39 if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL); err != nil { 40 os.RemoveAll(tmp) 41 return nil, err 42 } 43 44 cmd := exec.Command(v2binary, confPath) 45 if err := cmd.Start(); err != nil { 46 os.RemoveAll(tmp) 47 if os.IsNotExist(err) { 48 c.Skip(err.Error()) 49 } 50 return nil, err 51 } 52 return &testRegistryV2{ 53 cmd: cmd, 54 dir: tmp, 55 }, nil 56 } 57 58 func (t *testRegistryV2) Ping() error { 59 // We always ping through HTTP for our test registry. 60 resp, err := http.Get(fmt.Sprintf("http://%s/v2/", privateRegistryURL)) 61 if err != nil { 62 return err 63 } 64 if resp.StatusCode != 200 { 65 return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode) 66 } 67 return nil 68 } 69 70 func (t *testRegistryV2) Close() { 71 t.cmd.Process.Kill() 72 os.RemoveAll(t.dir) 73 } 74 75 func (t *testRegistryV2) getBlobFilename(blobDigest digest.Digest) string { 76 // Split the digest into it's algorithm and hex components. 77 dgstAlg, dgstHex := blobDigest.Algorithm(), blobDigest.Hex() 78 79 // The path to the target blob data looks something like: 80 // baseDir + "docker/registry/v2/blobs/sha256/a3/a3ed...46d4/data" 81 return fmt.Sprintf("%s/docker/registry/v2/blobs/%s/%s/%s/data", t.dir, dgstAlg, dgstHex[:2], dgstHex) 82 } 83 84 func (t *testRegistryV2) readBlobContents(c *check.C, blobDigest digest.Digest) []byte { 85 // Load the target manifest blob. 86 manifestBlob, err := ioutil.ReadFile(t.getBlobFilename(blobDigest)) 87 if err != nil { 88 c.Fatalf("unable to read blob: %s", err) 89 } 90 91 return manifestBlob 92 } 93 94 func (t *testRegistryV2) writeBlobContents(c *check.C, blobDigest digest.Digest, data []byte) { 95 if err := ioutil.WriteFile(t.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil { 96 c.Fatalf("unable to write malicious data blob: %s", err) 97 } 98 } 99 100 func (t *testRegistryV2) tempMoveBlobData(c *check.C, blobDigest digest.Digest) (undo func()) { 101 tempFile, err := ioutil.TempFile("", "registry-temp-blob-") 102 if err != nil { 103 c.Fatalf("unable to get temporary blob file: %s", err) 104 } 105 tempFile.Close() 106 107 blobFilename := t.getBlobFilename(blobDigest) 108 109 // Move the existing data file aside, so that we can replace it with a 110 // another blob of data. 111 if err := os.Rename(blobFilename, tempFile.Name()); err != nil { 112 os.Remove(tempFile.Name()) 113 c.Fatalf("unable to move data blob: %s", err) 114 } 115 116 return func() { 117 os.Rename(tempFile.Name(), blobFilename) 118 os.Remove(tempFile.Name()) 119 } 120 }