Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
// 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
}
Ejemplo n.º 3
0
// 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
}
Ejemplo n.º 4
0
// 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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
// 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
}
Ejemplo n.º 8
0
// 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
}
Ejemplo n.º 9
0
// 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
}
Ejemplo n.º 10
0
// 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
}
Ejemplo n.º 11
0
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
}
Ejemplo n.º 12
0
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
}