github.com/uriddle/docker@v0.0.0-20210926094723-4072e6aeb013/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  }