| ... | ... |
@@ -27,7 +27,7 @@ func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hos |
| 27 | 27 |
if daemon.Graph().IsNotExist(err, config.Image) {
|
| 28 | 28 |
_, tag := parsers.ParseRepositoryTag(config.Image) |
| 29 | 29 |
if tag == "" {
|
| 30 |
- tag = graph.DEFAULTTAG |
|
| 30 |
+ tag = graph.DefaultTag |
|
| 31 | 31 |
} |
| 32 | 32 |
return "", warnings, fmt.Errorf("No such image: %s (tag: %s)", config.Image, tag)
|
| 33 | 33 |
} |
| ... | ... |
@@ -36,7 +36,7 @@ func (daemon *Daemon) imgDeleteHelper(name string, list *[]types.ImageDelete, fi |
| 36 | 36 |
// FIXME: please respect DRY and centralize repo+tag parsing in a single central place! -- shykes |
| 37 | 37 |
repoName, tag = parsers.ParseRepositoryTag(name) |
| 38 | 38 |
if tag == "" {
|
| 39 |
- tag = graph.DEFAULTTAG |
|
| 39 |
+ tag = graph.DefaultTag |
|
| 40 | 40 |
} |
| 41 | 41 |
|
| 42 | 42 |
if name == "" {
|
| ... | ... |
@@ -13,16 +13,19 @@ import ( |
| 13 | 13 |
"github.com/docker/docker/registry" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-// CmdImageExport exports all images with the given tag. All versions |
|
| 16 |
+// ImageExportConfig holds list of names to be exported to a output stream. |
|
| 17 |
+// All images with the given tag and all versions |
|
| 17 | 18 |
// containing the same tag are exported. The resulting output is an |
| 18 | 19 |
// uncompressed tar ball. |
| 19 |
-// name is the set of tags to export. |
|
| 20 |
-// out is the writer where the images are written to. |
|
| 21 | 20 |
type ImageExportConfig struct {
|
| 22 |
- Names []string |
|
| 21 |
+ // Names is the set of tags to export. |
|
| 22 |
+ Names []string |
|
| 23 |
+ // OutStream is the writer where the images are written to. |
|
| 23 | 24 |
Outstream io.Writer |
| 24 | 25 |
} |
| 25 | 26 |
|
| 27 |
+// ImageExport exports list of images to a output stream specified in the config. |
|
| 28 |
+// The exported images are archived into a tar when written to the output stream. |
|
| 26 | 29 |
func (s *TagStore) ImageExport(imageExportConfig *ImageExportConfig) error {
|
| 27 | 30 |
|
| 28 | 31 |
// get image json |
| ... | ... |
@@ -135,7 +138,7 @@ func (s *TagStore) exportImage(name, tempdir string) error {
|
| 135 | 135 |
if err != nil {
|
| 136 | 136 |
return err |
| 137 | 137 |
} |
| 138 |
- imageInspectRaw, err := s.LookupRaw(n) |
|
| 138 |
+ imageInspectRaw, err := s.lookupRaw(n) |
|
| 139 | 139 |
if err != nil {
|
| 140 | 140 |
return err |
| 141 | 141 |
} |
| ... | ... |
@@ -152,6 +152,7 @@ func (graph *Graph) restore() error {
|
| 152 | 152 |
return nil |
| 153 | 153 |
} |
| 154 | 154 |
|
| 155 |
+// IsNotExist detects whether an image exists by parsing the incoming error message. |
|
| 155 | 156 |
// FIXME: Implement error subclass instead of looking at the error text |
| 156 | 157 |
// Note: This is the way golang implements os.IsNotExists on Plan9 |
| 157 | 158 |
func (graph *Graph) IsNotExist(err error, id string) bool {
|
| ... | ... |
@@ -414,7 +415,7 @@ func (graph *Graph) ByParent() map[string][]*image.Image {
|
| 414 | 414 |
return byParent |
| 415 | 415 |
} |
| 416 | 416 |
|
| 417 |
-// If the images and layers are in pulling chain, retain them. |
|
| 417 |
+// Retain keeps the images and layers that are in pulling chain so that they are not deleted. |
|
| 418 | 418 |
// If not, they may be deleted by rmi with dangling condition. |
| 419 | 419 |
func (graph *Graph) Retain(sessionID string, layerIDs ...string) {
|
| 420 | 420 |
graph.retained.Add(sessionID, layerIDs) |
| ... | ... |
@@ -16,10 +16,9 @@ import ( |
| 16 | 16 |
"github.com/docker/docker/pkg/system" |
| 17 | 17 |
) |
| 18 | 18 |
|
| 19 |
-// setupInitLayer populates a directory with mountpoints suitable |
|
| 19 |
+// SetupInitLayer populates a directory with mountpoints suitable |
|
| 20 | 20 |
// for bind-mounting dockerinit into the container. The mountpoint is simply an |
| 21 | 21 |
// empty file at /.dockerinit |
| 22 |
-// |
|
| 23 | 22 |
// This extra layer is used by all containers as the top-most ro layer. It protects |
| 24 | 23 |
// the container from unwanted side-effects on the rw layer. |
| 25 | 24 |
func SetupInitLayer(initLayer string) error {
|
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
"github.com/docker/docker/pkg/archive" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-// setupInitLayer populates a directory with mountpoints suitable |
|
| 16 |
+// SetupInitLayer populates a directory with mountpoints suitable |
|
| 17 | 17 |
// for bind-mounting dockerinit into the container. T |
| 18 | 18 |
func SetupInitLayer(initLayer string) error {
|
| 19 | 19 |
return nil |
| ... | ... |
@@ -107,32 +107,31 @@ func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader |
| 107 | 107 |
defer f.Close() |
| 108 | 108 |
|
| 109 | 109 |
return json.NewEncoder(f).Encode(img) |
| 110 |
- } else {
|
|
| 111 |
- // We keep this functionality here so that we can still work with the |
|
| 112 |
- // VFS driver during development. This will not be used for actual running |
|
| 113 |
- // of Windows containers. Without this code, it would not be possible to |
|
| 114 |
- // docker pull using the VFS driver. |
|
| 115 |
- |
|
| 116 |
- // Store the layer. If layerData is not nil, unpack it into the new layer |
|
| 117 |
- if layerData != nil {
|
|
| 118 |
- if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil {
|
|
| 119 |
- return err |
|
| 120 |
- } |
|
| 121 |
- } |
|
| 122 |
- |
|
| 123 |
- if err := graph.saveSize(root, int(img.Size)); err != nil {
|
|
| 124 |
- return err |
|
| 125 |
- } |
|
| 126 |
- |
|
| 127 |
- f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600)) |
|
| 128 |
- if err != nil {
|
|
| 110 |
+ } |
|
| 111 |
+ // We keep this functionality here so that we can still work with the |
|
| 112 |
+ // VFS driver during development. This will not be used for actual running |
|
| 113 |
+ // of Windows containers. Without this code, it would not be possible to |
|
| 114 |
+ // docker pull using the VFS driver. |
|
| 115 |
+ |
|
| 116 |
+ // Store the layer. If layerData is not nil, unpack it into the new layer |
|
| 117 |
+ if layerData != nil {
|
|
| 118 |
+ if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil {
|
|
| 129 | 119 |
return err |
| 130 | 120 |
} |
| 121 |
+ } |
|
| 131 | 122 |
|
| 132 |
- defer f.Close() |
|
| 123 |
+ if err := graph.saveSize(root, int(img.Size)); err != nil {
|
|
| 124 |
+ return err |
|
| 125 |
+ } |
|
| 133 | 126 |
|
| 134 |
- return json.NewEncoder(f).Encode(img) |
|
| 127 |
+ f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600)) |
|
| 128 |
+ if err != nil {
|
|
| 129 |
+ return err |
|
| 135 | 130 |
} |
| 131 |
+ |
|
| 132 |
+ defer f.Close() |
|
| 133 |
+ |
|
| 134 |
+ return json.NewEncoder(f).Encode(img) |
|
| 136 | 135 |
} |
| 137 | 136 |
|
| 138 | 137 |
// TarLayer returns a tar archive of the image's filesystem layer. |
| ... | ... |
@@ -152,15 +151,14 @@ func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 | 154 |
return wd.Export(img.ID, wd.LayerIdsToPaths(ids)) |
| 155 |
- } else {
|
|
| 156 |
- // We keep this functionality here so that we can still work with the VFS |
|
| 157 |
- // driver during development. VFS is not supported (and just will not work) |
|
| 158 |
- // for Windows containers. |
|
| 159 |
- rdr, err := graph.assembleTarLayer(img) |
|
| 160 |
- if err != nil {
|
|
| 161 |
- logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID)
|
|
| 162 |
- return graph.driver.Diff(img.ID, img.Parent) |
|
| 163 |
- } |
|
| 164 |
- return rdr, nil |
|
| 165 | 155 |
} |
| 156 |
+ // We keep this functionality here so that we can still work with the VFS |
|
| 157 |
+ // driver during development. VFS is not supported (and just will not work) |
|
| 158 |
+ // for Windows containers. |
|
| 159 |
+ rdr, err := graph.assembleTarLayer(img) |
|
| 160 |
+ if err != nil {
|
|
| 161 |
+ logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID)
|
|
| 162 |
+ return graph.driver.Diff(img.ID, img.Parent) |
|
| 163 |
+ } |
|
| 164 |
+ return rdr, nil |
|
| 166 | 165 |
} |
| ... | ... |
@@ -67,6 +67,7 @@ func (graph *Graph) CheckDepth(img *image.Image) error {
|
| 67 | 67 |
return nil |
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 |
+// History returns a list of ImageHistory for the specified image name by walking the image lineage. |
|
| 70 | 71 |
func (s *TagStore) History(name string) ([]*types.ImageHistory, error) {
|
| 71 | 72 |
foundImage, err := s.LookupImage(name) |
| 72 | 73 |
if err != nil {
|
| ... | ... |
@@ -101,6 +102,7 @@ func (s *TagStore) History(name string) ([]*types.ImageHistory, error) {
|
| 101 | 101 |
return history, err |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 |
+// GetParent returns the parent image. |
|
| 104 | 105 |
func (graph *Graph) GetParent(img *image.Image) (*image.Image, error) {
|
| 105 | 106 |
if img.Parent == "" {
|
| 106 | 107 |
return nil, nil |
| ... | ... |
@@ -108,6 +110,7 @@ func (graph *Graph) GetParent(img *image.Image) (*image.Image, error) {
|
| 108 | 108 |
return graph.Get(img.Parent) |
| 109 | 109 |
} |
| 110 | 110 |
|
| 111 |
+// GetParentsSize returns the size of the parent. |
|
| 111 | 112 |
func (graph *Graph) GetParentsSize(img *image.Image, size int64) int64 {
|
| 112 | 113 |
parentImage, err := graph.GetParent(img) |
| 113 | 114 |
if err != nil || parentImage == nil {
|
| ... | ... |
@@ -13,13 +13,21 @@ import ( |
| 13 | 13 |
"github.com/docker/docker/utils" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
+// ImageImportConfig holds configuration to import a image. |
|
| 16 | 17 |
type ImageImportConfig struct {
|
| 17 |
- Changes []string |
|
| 18 |
- InConfig io.ReadCloser |
|
| 19 |
- OutStream io.Writer |
|
| 18 |
+ // Changes are the container changes written to top layer. |
|
| 19 |
+ Changes []string |
|
| 20 |
+ // InConfig is the input stream containers layered data. |
|
| 21 |
+ InConfig io.ReadCloser |
|
| 22 |
+ // OutStream is the output stream where the image is written. |
|
| 23 |
+ OutStream io.Writer |
|
| 24 |
+ // ContainerConfig is the configuration of commit container. |
|
| 20 | 25 |
ContainerConfig *runconfig.Config |
| 21 | 26 |
} |
| 22 | 27 |
|
| 28 |
+// Import allows to download image from a archive. |
|
| 29 |
+// If the src is a URL, the content is downloaded from the archive. If the source is '-' then the imageImportConfig.InConfig |
|
| 30 |
+// reader will be used to load the image. Once all the layers required are loaded locally, image is then tagged using the tag specified. |
|
| 23 | 31 |
func (s *TagStore) Import(src string, repo string, tag string, imageImportConfig *ImageImportConfig) error {
|
| 24 | 32 |
var ( |
| 25 | 33 |
sf = streamformatter.NewJSONStreamFormatter() |
| ... | ... |
@@ -18,18 +18,24 @@ var acceptedImageFilterTags = map[string]struct{}{
|
| 18 | 18 |
"label": {},
|
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 |
+// ImagesConfig defines the criteria to obtain a list of images. |
|
| 21 | 22 |
type ImagesConfig struct {
|
| 23 |
+ // Filters is supported list of filters used to get list of images. |
|
| 22 | 24 |
Filters string |
| 23 |
- Filter string |
|
| 24 |
- All bool |
|
| 25 |
+ // Filter the list of images by name. |
|
| 26 |
+ Filter string |
|
| 27 |
+ // All inditest that all the images will be returned in the list, if set to true. |
|
| 28 |
+ All bool |
|
| 25 | 29 |
} |
| 26 | 30 |
|
| 27 |
-type ByCreated []*types.Image |
|
| 31 |
+// byCreated is a temporary type used to sort list of images on their field 'Created'. |
|
| 32 |
+type byCreated []*types.Image |
|
| 28 | 33 |
|
| 29 |
-func (r ByCreated) Len() int { return len(r) }
|
|
| 30 |
-func (r ByCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
|
| 31 |
-func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
|
|
| 34 |
+func (r byCreated) Len() int { return len(r) }
|
|
| 35 |
+func (r byCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
|
| 36 |
+func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
|
|
| 32 | 37 |
|
| 38 |
+// Images provide list of images based on selection criteria. |
|
| 33 | 39 |
func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
|
| 34 | 40 |
var ( |
| 35 | 41 |
allImages map[string]*image.Image |
| ... | ... |
@@ -144,7 +150,7 @@ func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
|
| 144 | 144 |
} |
| 145 | 145 |
} |
| 146 | 146 |
|
| 147 |
- sort.Sort(sort.Reverse(ByCreated(images))) |
|
| 147 |
+ sort.Sort(sort.Reverse(byCreated(images))) |
|
| 148 | 148 |
|
| 149 | 149 |
return images, nil |
| 150 | 150 |
} |
| ... | ... |
@@ -15,7 +15,7 @@ import ( |
| 15 | 15 |
"github.com/docker/docker/pkg/chrootarchive" |
| 16 | 16 |
) |
| 17 | 17 |
|
| 18 |
-// Loads a set of images into the repository. This is the complementary of ImageExport. |
|
| 18 |
+// Load uploads a set of images into the repository. This is the complementary of ImageExport. |
|
| 19 | 19 |
// The input stream is an uncompressed tar ball containing images and metadata. |
| 20 | 20 |
func (s *TagStore) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
| 21 | 21 |
tmpImageDir, err := ioutil.TempDir("", "docker-import-")
|
| ... | ... |
@@ -84,7 +84,7 @@ func (s *TagStore) recursiveLoad(address, tmpImageDir string) error {
|
| 84 | 84 |
if _, err := s.LookupImage(address); err != nil {
|
| 85 | 85 |
logrus.Debugf("Loading %s", address)
|
| 86 | 86 |
|
| 87 |
- imageJson, err := ioutil.ReadFile(filepath.Join(tmpImageDir, "repo", address, "json")) |
|
| 87 |
+ imageJSON, err := ioutil.ReadFile(filepath.Join(tmpImageDir, "repo", address, "json")) |
|
| 88 | 88 |
if err != nil {
|
| 89 | 89 |
logrus.Debugf("Error reading json: %v", err)
|
| 90 | 90 |
return err |
| ... | ... |
@@ -95,7 +95,7 @@ func (s *TagStore) recursiveLoad(address, tmpImageDir string) error {
|
| 95 | 95 |
logrus.Debugf("Error reading embedded tar: %v", err)
|
| 96 | 96 |
return err |
| 97 | 97 |
} |
| 98 |
- img, err := image.NewImgJSON(imageJson) |
|
| 98 |
+ img, err := image.NewImgJSON(imageJSON) |
|
| 99 | 99 |
if err != nil {
|
| 100 | 100 |
logrus.Debugf("Error unmarshalling json: %v", err)
|
| 101 | 101 |
return err |
| ... | ... |
@@ -7,6 +7,8 @@ import ( |
| 7 | 7 |
"io" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
+// Load method is implemented here for non-linux and non-windows platforms and |
|
| 11 |
+// may return an error indicating that image load is not supported on other platforms. |
|
| 10 | 12 |
func (s *TagStore) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
| 11 | 13 |
return fmt.Errorf("Load is not supported on this platform")
|
| 12 | 14 |
} |
| ... | ... |
@@ -11,12 +11,17 @@ import ( |
| 11 | 11 |
"github.com/docker/docker/utils" |
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 |
+// ImagePullConfig stores pull configuration. |
|
| 14 | 15 |
type ImagePullConfig struct {
|
| 16 |
+ // MetaHeaders store meta data about the image (DockerHeaders with prefix X-Meta- in the request). |
|
| 15 | 17 |
MetaHeaders map[string][]string |
| 16 |
- AuthConfig *cliconfig.AuthConfig |
|
| 17 |
- OutStream io.Writer |
|
| 18 |
+ // AuthConfig holds authentication information for authorizing with the registry. |
|
| 19 |
+ AuthConfig *cliconfig.AuthConfig |
|
| 20 |
+ // OutStream is the output writer for showing the status of the pull operation. |
|
| 21 |
+ OutStream io.Writer |
|
| 18 | 22 |
} |
| 19 | 23 |
|
| 24 |
+// Puller is an interface to define Pull behavior. |
|
| 20 | 25 |
type Puller interface {
|
| 21 | 26 |
// Pull tries to pull the image referenced by `tag` |
| 22 | 27 |
// Pull returns an error if any, as well as a boolean that determines whether to retry Pull on the next configured endpoint. |
| ... | ... |
@@ -25,6 +30,7 @@ type Puller interface {
|
| 25 | 25 |
Pull(tag string) (fallback bool, err error) |
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 |
+// NewPuller returns a new instance of an implementation conforming to Puller interface. |
|
| 28 | 29 |
func NewPuller(s *TagStore, endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo, imagePullConfig *ImagePullConfig, sf *streamformatter.StreamFormatter) (Puller, error) {
|
| 29 | 30 |
switch endpoint.Version {
|
| 30 | 31 |
case registry.APIVersion2: |
| ... | ... |
@@ -47,6 +53,7 @@ func NewPuller(s *TagStore, endpoint registry.APIEndpoint, repoInfo *registry.Re |
| 47 | 47 |
return nil, fmt.Errorf("unknown version %d for registry %s", endpoint.Version, endpoint.URL)
|
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
+// Pull downloads a image with specified name and tag from the repo. |
|
| 50 | 51 |
func (s *TagStore) Pull(image string, tag string, imagePullConfig *ImagePullConfig) error {
|
| 51 | 52 |
var sf = streamformatter.NewJSONStreamFormatter() |
| 52 | 53 |
|
| ... | ... |
@@ -126,7 +133,8 @@ func (s *TagStore) Pull(image string, tag string, imagePullConfig *ImagePullConf |
| 126 | 126 |
return lastErr |
| 127 | 127 |
} |
| 128 | 128 |
|
| 129 |
-func WriteStatus(requestedTag string, out io.Writer, sf *streamformatter.StreamFormatter, layersDownloaded bool) {
|
|
| 129 |
+// writeStatus shows status of the pull command. |
|
| 130 |
+func writeStatus(requestedTag string, out io.Writer, sf *streamformatter.StreamFormatter, layersDownloaded bool) {
|
|
| 130 | 131 |
if layersDownloaded {
|
| 131 | 132 |
out.Write(sf.FormatStatus("", "Status: Downloaded newer image for %s", requestedTag))
|
| 132 | 133 |
} else {
|
| ... | ... |
@@ -80,9 +80,9 @@ func (p *v1Puller) pullRepository(askedTag string) error {
|
| 80 | 80 |
if askedTag == "" {
|
| 81 | 81 |
tagsList, err = p.session.GetRemoteTags(repoData.Endpoints, p.repoInfo.RemoteName) |
| 82 | 82 |
} else {
|
| 83 |
- var tagId string |
|
| 84 |
- tagId, err = p.session.GetRemoteTag(repoData.Endpoints, p.repoInfo.RemoteName, askedTag) |
|
| 85 |
- tagsList[askedTag] = tagId |
|
| 83 |
+ var tagID string |
|
| 84 |
+ tagID, err = p.session.GetRemoteTag(repoData.Endpoints, p.repoInfo.RemoteName, askedTag) |
|
| 85 |
+ tagsList[askedTag] = tagID |
|
| 86 | 86 |
} |
| 87 | 87 |
if err != nil {
|
| 88 | 88 |
if err == registry.ErrRepoNotFound && askedTag != "" {
|
| ... | ... |
@@ -222,7 +222,7 @@ func (p *v1Puller) pullRepository(askedTag string) error {
|
| 222 | 222 |
if len(askedTag) > 0 {
|
| 223 | 223 |
requestedTag = utils.ImageReference(p.repoInfo.LocalName, askedTag) |
| 224 | 224 |
} |
| 225 |
- WriteStatus(requestedTag, out, p.sf, layersDownloaded) |
|
| 225 |
+ writeStatus(requestedTag, out, p.sf, layersDownloaded) |
|
| 226 | 226 |
return nil |
| 227 | 227 |
} |
| 228 | 228 |
|
| ... | ... |
@@ -95,7 +95,7 @@ func (p *v2Puller) pullV2Repository(tag string) (err error) {
|
| 95 | 95 |
layersDownloaded = layersDownloaded || pulledNew |
| 96 | 96 |
} |
| 97 | 97 |
|
| 98 |
- WriteStatus(taggedName, p.config.OutStream, p.sf, layersDownloaded) |
|
| 98 |
+ writeStatus(taggedName, p.config.OutStream, p.sf, layersDownloaded) |
|
| 99 | 99 |
|
| 100 | 100 |
return nil |
| 101 | 101 |
} |
| ... | ... |
@@ -10,13 +10,19 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/registry" |
| 11 | 11 |
) |
| 12 | 12 |
|
| 13 |
+// ImagePushConfig stores push configuration. |
|
| 13 | 14 |
type ImagePushConfig struct {
|
| 15 |
+ // MetaHeaders store meta data about the image (DockerHeaders with prefix X-Meta- in the request). |
|
| 14 | 16 |
MetaHeaders map[string][]string |
| 15 |
- AuthConfig *cliconfig.AuthConfig |
|
| 16 |
- Tag string |
|
| 17 |
- OutStream io.Writer |
|
| 17 |
+ // AuthConfig holds authentication information for authorizing with the registry. |
|
| 18 |
+ AuthConfig *cliconfig.AuthConfig |
|
| 19 |
+ // Tag is the specific variant of the image to be pushed, this tag used when image is pushed. If no tag is provided, all tags will be pushed. |
|
| 20 |
+ Tag string |
|
| 21 |
+ // OutStream is the output writer for showing the status of the push operation. |
|
| 22 |
+ OutStream io.Writer |
|
| 18 | 23 |
} |
| 19 | 24 |
|
| 25 |
+// Pusher is an interface to define Push behavior. |
|
| 20 | 26 |
type Pusher interface {
|
| 21 | 27 |
// Push tries to push the image configured at the creation of Pusher. |
| 22 | 28 |
// Push returns an error if any, as well as a boolean that determines whether to retry Push on the next configured endpoint. |
| ... | ... |
@@ -25,6 +31,7 @@ type Pusher interface {
|
| 25 | 25 |
Push() (fallback bool, err error) |
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 |
+// NewPusher returns a new instance of an implementation conforming to Pusher interface. |
|
| 28 | 29 |
func (s *TagStore) NewPusher(endpoint registry.APIEndpoint, localRepo Repository, repoInfo *registry.RepositoryInfo, imagePushConfig *ImagePushConfig, sf *streamformatter.StreamFormatter) (Pusher, error) {
|
| 29 | 30 |
switch endpoint.Version {
|
| 30 | 31 |
case registry.APIVersion2: |
| ... | ... |
@@ -51,6 +58,8 @@ func (s *TagStore) NewPusher(endpoint registry.APIEndpoint, localRepo Repository |
| 51 | 51 |
} |
| 52 | 52 |
|
| 53 | 53 |
// FIXME: Allow to interrupt current push when new push of same image is done. |
| 54 |
+ |
|
| 55 |
+// Push a image to the repo. |
|
| 54 | 56 |
func (s *TagStore) Push(localName string, imagePushConfig *ImagePushConfig) error {
|
| 55 | 57 |
var sf = streamformatter.NewJSONStreamFormatter() |
| 56 | 58 |
|
| ... | ... |
@@ -87,12 +87,12 @@ func (p *v2Pusher) pushV2Repository(tag string) error {
|
| 87 | 87 |
func (p *v2Pusher) pushV2Tag(tag string) error {
|
| 88 | 88 |
logrus.Debugf("Pushing repository: %s:%s", p.repo.Name(), tag)
|
| 89 | 89 |
|
| 90 |
- layerId, exists := p.localRepo[tag] |
|
| 90 |
+ layerID, exists := p.localRepo[tag] |
|
| 91 | 91 |
if !exists {
|
| 92 | 92 |
return fmt.Errorf("tag does not exist: %s", tag)
|
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
- layer, err := p.graph.Get(layerId) |
|
| 95 |
+ layer, err := p.graph.Get(layerID) |
|
| 96 | 96 |
if err != nil {
|
| 97 | 97 |
return err |
| 98 | 98 |
} |
| ... | ... |
@@ -27,7 +27,7 @@ func (dcs dumbCredentialStore) Basic(*url.URL) (string, string) {
|
| 27 | 27 |
return dcs.auth.Username, dcs.auth.Password |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
-// v2 only |
|
| 30 |
+// NewV2Repository creates a v2 only repository. |
|
| 31 | 31 |
func NewV2Repository(repoInfo *registry.RepositoryInfo, endpoint registry.APIEndpoint, metaHeaders http.Header, authConfig *cliconfig.AuthConfig) (distribution.Repository, error) {
|
| 32 | 32 |
ctx := context.Background() |
| 33 | 33 |
|
| ... | ... |
@@ -10,7 +10,7 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/api/types" |
| 11 | 11 |
) |
| 12 | 12 |
|
| 13 |
-func (s *TagStore) LookupRaw(name string) ([]byte, error) {
|
|
| 13 |
+func (s *TagStore) lookupRaw(name string) ([]byte, error) {
|
|
| 14 | 14 |
image, err := s.LookupImage(name) |
| 15 | 15 |
if err != nil || image == nil {
|
| 16 | 16 |
return nil, fmt.Errorf("No such image %s", name)
|
| ... | ... |
@@ -24,8 +24,10 @@ import ( |
| 24 | 24 |
"github.com/docker/libtrust" |
| 25 | 25 |
) |
| 26 | 26 |
|
| 27 |
-const DEFAULTTAG = "latest" |
|
| 27 |
+// DefaultTag defines the default tag used when performing images related actions and no tag string is specified |
|
| 28 |
+const DefaultTag = "latest" |
|
| 28 | 29 |
|
| 30 |
+// TagStore contains information to push and pull to the repo. |
|
| 29 | 31 |
type TagStore struct {
|
| 30 | 32 |
path string |
| 31 | 33 |
graph *Graph |
| ... | ... |
@@ -41,16 +43,17 @@ type TagStore struct {
|
| 41 | 41 |
trustService *trust.TrustStore |
| 42 | 42 |
} |
| 43 | 43 |
|
| 44 |
+// Repository maps image id to image tag. |
|
| 44 | 45 |
type Repository map[string]string |
| 45 | 46 |
|
| 46 |
-// update Repository mapping with content of u |
|
| 47 |
+// Update updates repository mapping with content of repository 'u'. |
|
| 47 | 48 |
func (r Repository) Update(u Repository) {
|
| 48 | 49 |
for k, v := range u {
|
| 49 | 50 |
r[k] = v |
| 50 | 51 |
} |
| 51 | 52 |
} |
| 52 | 53 |
|
| 53 |
-// return true if the contents of u Repository, are wholly contained in r Repository |
|
| 54 |
+// Contains returns true if the contents of u Repository, are wholly contained in r Repository. |
|
| 54 | 55 |
func (r Repository) Contains(u Repository) bool {
|
| 55 | 56 |
for k, v := range u {
|
| 56 | 57 |
// if u's key is not present in r OR u's key is present, but not the same value |
| ... | ... |
@@ -61,6 +64,7 @@ func (r Repository) Contains(u Repository) bool {
|
| 61 | 61 |
return true |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
+// TagStoreConfig holds tag store configuration. |
|
| 64 | 65 |
type TagStoreConfig struct {
|
| 65 | 66 |
Graph *Graph |
| 66 | 67 |
Key libtrust.PrivateKey |
| ... | ... |
@@ -69,6 +73,7 @@ type TagStoreConfig struct {
|
| 69 | 69 |
Trust *trust.TrustStore |
| 70 | 70 |
} |
| 71 | 71 |
|
| 72 |
+// NewTagStore creates a tag store to specified path. |
|
| 72 | 73 |
func NewTagStore(path string, cfg *TagStoreConfig) (*TagStore, error) {
|
| 73 | 74 |
abspath, err := filepath.Abs(path) |
| 74 | 75 |
if err != nil {
|
| ... | ... |
@@ -121,12 +126,13 @@ func (store *TagStore) reload() error {
|
| 121 | 121 |
return nil |
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 |
+// LookupImage returns the image from the store. |
|
| 124 | 125 |
func (store *TagStore) LookupImage(name string) (*image.Image, error) {
|
| 125 | 126 |
// FIXME: standardize on returning nil when the image doesn't exist, and err for everything else |
| 126 | 127 |
// (so we can pass all errors here) |
| 127 | 128 |
repoName, ref := parsers.ParseRepositoryTag(name) |
| 128 | 129 |
if ref == "" {
|
| 129 |
- ref = DEFAULTTAG |
|
| 130 |
+ ref = DefaultTag |
|
| 130 | 131 |
} |
| 131 | 132 |
var ( |
| 132 | 133 |
err error |
| ... | ... |
@@ -152,7 +158,7 @@ func (store *TagStore) LookupImage(name string) (*image.Image, error) {
|
| 152 | 152 |
return img, nil |
| 153 | 153 |
} |
| 154 | 154 |
|
| 155 |
-// Return a reverse-lookup table of all the names which refer to each image |
|
| 155 |
+// ByID returns a reverse-lookup table of all the names which refer to each image. |
|
| 156 | 156 |
// Eg. {"43b5f19b10584": {"base:latest", "base:v1"}}
|
| 157 | 157 |
func (store *TagStore) ByID() map[string][]string {
|
| 158 | 158 |
store.Lock() |
| ... | ... |
@@ -172,6 +178,7 @@ func (store *TagStore) ByID() map[string][]string {
|
| 172 | 172 |
return byID |
| 173 | 173 |
} |
| 174 | 174 |
|
| 175 |
+// ImageName returns name of the image. |
|
| 175 | 176 |
func (store *TagStore) ImageName(id string) string {
|
| 176 | 177 |
if names, exists := store.ByID()[id]; exists && len(names) > 0 {
|
| 177 | 178 |
return names[0] |
| ... | ... |
@@ -179,6 +186,7 @@ func (store *TagStore) ImageName(id string) string {
|
| 179 | 179 |
return stringid.TruncateID(id) |
| 180 | 180 |
} |
| 181 | 181 |
|
| 182 |
+// DeleteAll removes images identified by a specific id from the store. |
|
| 182 | 183 |
func (store *TagStore) DeleteAll(id string) error {
|
| 183 | 184 |
names, exists := store.ByID()[id] |
| 184 | 185 |
if !exists || len(names) == 0 {
|
| ... | ... |
@@ -199,6 +207,7 @@ func (store *TagStore) DeleteAll(id string) error {
|
| 199 | 199 |
return nil |
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 |
+// Delete removes a repo identified by a given name from the store |
|
| 202 | 203 |
func (store *TagStore) Delete(repoName, ref string) (bool, error) {
|
| 203 | 204 |
store.Lock() |
| 204 | 205 |
defer store.Unlock() |
| ... | ... |
@@ -231,10 +240,13 @@ func (store *TagStore) Delete(repoName, ref string) (bool, error) {
|
| 231 | 231 |
return deleted, store.save() |
| 232 | 232 |
} |
| 233 | 233 |
|
| 234 |
+// Tag adds a new tag to an existing image. |
|
| 234 | 235 |
func (store *TagStore) Tag(repoName, tag, imageName string, force bool) error {
|
| 235 | 236 |
return store.SetLoad(repoName, tag, imageName, force, nil) |
| 236 | 237 |
} |
| 237 | 238 |
|
| 239 |
+// SetLoad stores the image to the store. |
|
| 240 |
+// If the imageName is already in the repo then a '-f' flag should be used to replace existing image. |
|
| 238 | 241 |
func (store *TagStore) SetLoad(repoName, tag, imageName string, force bool, out io.Writer) error {
|
| 239 | 242 |
img, err := store.LookupImage(imageName) |
| 240 | 243 |
store.Lock() |
| ... | ... |
@@ -319,6 +331,7 @@ func (store *TagStore) SetDigest(repoName, digest, imageName string) error {
|
| 319 | 319 |
return store.save() |
| 320 | 320 |
} |
| 321 | 321 |
|
| 322 |
+// Get returns a repo from the store. |
|
| 322 | 323 |
func (store *TagStore) Get(repoName string) (Repository, error) {
|
| 323 | 324 |
store.Lock() |
| 324 | 325 |
defer store.Unlock() |
| ... | ... |
@@ -332,6 +345,7 @@ func (store *TagStore) Get(repoName string) (Repository, error) {
|
| 332 | 332 |
return nil, nil |
| 333 | 333 |
} |
| 334 | 334 |
|
| 335 |
+// GetImage returns an image from a given repo from the store. |
|
| 335 | 336 |
func (store *TagStore) GetImage(repoName, refOrID string) (*image.Image, error) {
|
| 336 | 337 |
repo, err := store.Get(repoName) |
| 337 | 338 |
|
| ... | ... |
@@ -361,6 +375,7 @@ func (store *TagStore) GetImage(repoName, refOrID string) (*image.Image, error) |
| 361 | 361 |
return nil, nil |
| 362 | 362 |
} |
| 363 | 363 |
|
| 364 |
+// GetRepoRefs returns list of repos. |
|
| 364 | 365 |
func (store *TagStore) GetRepoRefs() map[string][]string {
|
| 365 | 366 |
store.Lock() |
| 366 | 367 |
reporefs := make(map[string][]string) |
| ... | ... |
@@ -375,7 +390,7 @@ func (store *TagStore) GetRepoRefs() map[string][]string {
|
| 375 | 375 |
return reporefs |
| 376 | 376 |
} |
| 377 | 377 |
|
| 378 |
-// Validate the name of a repository |
|
| 378 |
+// validateRepoName validates the name of a repository. |
|
| 379 | 379 |
func validateRepoName(name string) error {
|
| 380 | 380 |
if name == "" {
|
| 381 | 381 |
return fmt.Errorf("Repository name can't be empty")
|
| ... | ... |
@@ -119,17 +119,17 @@ func TestLookupImage(t *testing.T) {
|
| 119 | 119 |
testOfficialImageName + ":" + testOfficialImageID, |
| 120 | 120 |
testOfficialImageName + ":" + testOfficialImageIDShort, |
| 121 | 121 |
testOfficialImageName, |
| 122 |
- testOfficialImageName + ":" + DEFAULTTAG, |
|
| 122 |
+ testOfficialImageName + ":" + DefaultTag, |
|
| 123 | 123 |
"docker.io/" + testOfficialImageName, |
| 124 |
- "docker.io/" + testOfficialImageName + ":" + DEFAULTTAG, |
|
| 124 |
+ "docker.io/" + testOfficialImageName + ":" + DefaultTag, |
|
| 125 | 125 |
"index.docker.io/" + testOfficialImageName, |
| 126 |
- "index.docker.io/" + testOfficialImageName + ":" + DEFAULTTAG, |
|
| 126 |
+ "index.docker.io/" + testOfficialImageName + ":" + DefaultTag, |
|
| 127 | 127 |
"library/" + testOfficialImageName, |
| 128 |
- "library/" + testOfficialImageName + ":" + DEFAULTTAG, |
|
| 128 |
+ "library/" + testOfficialImageName + ":" + DefaultTag, |
|
| 129 | 129 |
"docker.io/library/" + testOfficialImageName, |
| 130 |
- "docker.io/library/" + testOfficialImageName + ":" + DEFAULTTAG, |
|
| 130 |
+ "docker.io/library/" + testOfficialImageName + ":" + DefaultTag, |
|
| 131 | 131 |
"index.docker.io/library/" + testOfficialImageName, |
| 132 |
- "index.docker.io/library/" + testOfficialImageName + ":" + DEFAULTTAG, |
|
| 132 |
+ "index.docker.io/library/" + testOfficialImageName + ":" + DefaultTag, |
|
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 | 135 |
privateLookups := []string{
|
| ... | ... |
@@ -138,7 +138,7 @@ func TestLookupImage(t *testing.T) {
|
| 138 | 138 |
testPrivateImageName + ":" + testPrivateImageID, |
| 139 | 139 |
testPrivateImageName + ":" + testPrivateImageIDShort, |
| 140 | 140 |
testPrivateImageName, |
| 141 |
- testPrivateImageName + ":" + DEFAULTTAG, |
|
| 141 |
+ testPrivateImageName + ":" + DefaultTag, |
|
| 142 | 142 |
} |
| 143 | 143 |
|
| 144 | 144 |
invalidLookups := []string{
|