func translatePullError(err error, ref reference.Named) error { switch v := err.(type) { case errcode.Errors: if len(v) != 0 { for _, extra := range v[1:] { logrus.Infof("Ignoring extra error returned from registry: %v", extra) } return translatePullError(v[0], ref) } case errcode.Error: var newErr error switch v.Code { case errcode.ErrorCodeDenied: // ErrorCodeDenied is used when access to the repository was denied newErr = errors.Errorf("repository %s not found: does not exist or no read access", ref.Name()) case v2.ErrorCodeManifestUnknown: newErr = errors.Errorf("manifest for %s not found", ref.String()) case v2.ErrorCodeNameUnknown: newErr = errors.Errorf("repository %s not found", ref.Name()) } if newErr != nil { logrus.Infof("Translating %q to %q", err, newErr) return newErr } case xfer.DoNotRetry: return translatePullError(v.Err, ref) } return err }
// ReferencesByName returns the references for a given repository name. // If there are no references known for this repository name, // ReferencesByName returns nil. func (store *repoCache) ReferencesByName(ref reference.Named) []Association { defer trace.End(trace.Begin("")) store.mu.RLock() defer store.mu.RUnlock() repository, exists := store.Repositories[ref.Name()] if !exists { return nil } var associations []Association for refStr, refID := range repository { ref, err := reference.ParseNamed(refStr) if err != nil { // Should never happen return nil } associations = append(associations, Association{ Ref: ref, ImageID: refID, }) } sort.Sort(lexicalAssociations(associations)) return associations }
// Looks up image by reference.Named func (c *ImageCache) GetImageByNamed(named reference.Named) (*metadata.ImageConfig, error) { c.m.RLock() defer c.m.RUnlock() if CacheNotUpdated { return nil, ErrCacheNotUpdated } var config *metadata.ImageConfig if tagged, ok := named.(reference.NamedTagged); ok { taggedName := tagged.Name() + ":" + tagged.Tag() config = c.cacheByName[taggedName] } else { // First try just the name. config = c.cacheByName[named.Name()] if config == nil { // try with the default docker tag taggedName := named.Name() + ":" + reference.DefaultTag config = c.cacheByName[taggedName] } } return config, nil }
// newRepositoryInfo validates and breaks down a repository name into a RepositoryInfo func newRepositoryInfo(config *serviceConfig, name reference.Named) (*RepositoryInfo, error) { index, err := newIndexInfo(config, name.Hostname()) if err != nil { return nil, err } official := !strings.ContainsRune(name.Name(), '/') return &RepositoryInfo{name, index, official}, nil }
func (pm *Manager) newPlugin(ref reference.Named, id string) *plugin { p := &plugin{ PluginObj: types.Plugin{ Name: ref.Name(), ID: id, }, runtimeSourcePath: filepath.Join(pm.runRoot, id), } if ref, ok := ref.(reference.NamedTagged); ok { p.PluginObj.Tag = ref.Tag() } return p }
func digestFromManifest(m *schema1.SignedManifest, name reference.Named) (digest.Digest, int, error) { payload, err := m.Payload() if err != nil { // If this failed, the signatures section was corrupted // or missing. Treat the entire manifest as the payload. payload = m.Raw } manifestDigest, err := digest.FromBytes(payload) if err != nil { logrus.Infof("Could not compute manifest digest for %s:%s : %v", name.Name(), m.Tag, err) } return manifestDigest, len(payload), nil }
// Looks up image by reference.Named func (ic *ICache) getImageByNamed(named reference.Named) (*metadata.ImageConfig, error) { var config *metadata.ImageConfig if tagged, ok := named.(reference.NamedTagged); ok { taggedName := tagged.Name() + ":" + tagged.Tag() config = ic.cacheByName[taggedName] } else { // First try just the name. if config, ok = ic.cacheByName[named.Name()]; !ok { // try with the default docker tag taggedName := named.Name() + ":" + reference.DefaultTag config = ic.cacheByName[taggedName] } } return copyImageConfig(config), nil }
// Get returns the imageID for a parsed reference func (store *repoCache) Get(ref reference.Named) (string, error) { defer trace.End(trace.Begin("")) ref = reference.WithDefaultTag(ref) store.mu.RLock() defer store.mu.RUnlock() repository, exists := store.Repositories[ref.Name()] if !exists || repository == nil { return "", ErrDoesNotExist } imageID, exists := repository[ref.String()] if !exists { return "", ErrDoesNotExist } return imageID, nil }
// Delete deletes a reference from the store. It returns true if a deletion // happened, or false otherwise. func (store *repoCache) Delete(ref reference.Named, save bool) (bool, error) { defer trace.End(trace.Begin("")) ref = reference.WithDefaultTag(ref) store.mu.Lock() defer store.mu.Unlock() var err error // return code -- assume success rtc := true repoName := ref.Name() repository, exists := store.Repositories[repoName] if !exists { return false, ErrDoesNotExist } refStr := ref.String() if imageID, exists := repository[refStr]; exists { delete(repository, refStr) if len(repository) == 0 { delete(store.Repositories, repoName) } if store.referencesByIDCache[imageID] != nil { delete(store.referencesByIDCache[imageID], refStr) if len(store.referencesByIDCache[imageID]) == 0 { delete(store.referencesByIDCache, imageID) } } if layer, exists := store.images[imageID]; exists { delete(store.Layers, imageID) delete(store.images, layer) } if save { err = store.Save() if err != nil { rtc = false } } return rtc, err } return false, ErrDoesNotExist }
// isSingleReference returns true when all references are from one repository // and there is at most one tag. Returns false for empty input. func isSingleReference(repoRefs []reference.Named) bool { if len(repoRefs) <= 1 { return len(repoRefs) == 1 } var singleRef reference.Named canonicalRefs := map[string]struct{}{} for _, repoRef := range repoRefs { if _, isCanonical := repoRef.(reference.Canonical); isCanonical { canonicalRefs[repoRef.Name()] = struct{}{} } else if singleRef == nil { singleRef = repoRef } else { return false } } if singleRef == nil { // Just use first canonical ref singleRef = repoRefs[0] } _, ok := canonicalRefs[singleRef.Name()] return len(canonicalRefs) == 1 && ok }
func (pm *Manager) pull(ref reference.Named, metaHeader http.Header, authConfig *types.AuthConfig, pluginID string) (types.PluginPrivileges, error) { pd, err := distribution.Pull(ref, pm.registryService, metaHeader, authConfig) if err != nil { logrus.Debugf("error in distribution.Pull(): %v", err) return nil, err } if err := distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true); err != nil { logrus.Debugf("error in distribution.WritePullData(): %v", err) return nil, err } tag := distribution.GetTag(ref) p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, pm.libRoot, tag) if err := p.InitPlugin(); err != nil { return nil, err } pm.pluginStore.Add(p) pm.pluginEventLogger(pluginID, ref.String(), "pull") return p.ComputePrivileges(), nil }
func (store *repoCache) AddReference(ref reference.Named, imageID string, force bool, layerID string, save bool) error { defer trace.End(trace.Begin("")) if ref.Name() == string(digest.Canonical) { return errors.New("refusing to create an ambiguous tag using digest algorithm as name") } var err error store.mu.Lock() defer store.mu.Unlock() // does this repo (i.e. busybox) exist? repository, exists := store.Repositories[ref.Name()] if !exists || repository == nil { repository = make(map[string]string) store.Repositories[ref.Name()] = repository } refStr := ref.String() oldID, exists := repository[refStr] if exists { if oldID == imageID { log.Debugf("Image %s is already tagged as %s", oldID, ref.String()) return nil } // force only works for tags if digested, isDigest := ref.(reference.Canonical); isDigest { log.Debugf("Unable to overwrite %s with digest %s", oldID, digested.Digest().String()) return fmt.Errorf("Cannot overwrite digest %s", digested.Digest().String()) } if !force { log.Debugf("Refusing to overwrite %s with %s unless force is specified", oldID, ref.String()) return fmt.Errorf("Conflict: Tag %s is already set to image %s, if you want to replace it, please use -f option", ref.String(), oldID) } if store.referencesByIDCache[oldID] != nil { delete(store.referencesByIDCache[oldID], refStr) if len(store.referencesByIDCache[oldID]) == 0 { delete(store.referencesByIDCache, oldID) } } } repository[refStr] = imageID if store.referencesByIDCache[imageID] == nil { store.referencesByIDCache[imageID] = make(map[string]reference.Named) } store.referencesByIDCache[imageID][refStr] = ref store.Layers[layerID] = imageID store.images[imageID] = layerID // should we save this input? if save { err = store.Save() } return err }