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