// put stores the manifest in the repository, if not already present. Any // updated signatures will be stored, as well. func (rs *revisionStore) put(ctx context.Context, sm *manifest.SignedManifest) (distribution.Descriptor, error) { // Resolve the payload in the manifest. payload, err := sm.Payload() if err != nil { return distribution.Descriptor{}, err } // Digest and store the manifest payload in the blob store. revision, err := rs.blobStore.Put(ctx, manifest.ManifestMediaType, payload) if err != nil { context.GetLogger(ctx).Errorf("error putting payload into blobstore: %v", err) return distribution.Descriptor{}, err } // Link the revision into the repository. if err := rs.blobStore.linkBlob(ctx, revision); err != nil { return distribution.Descriptor{}, err } // Grab each json signature and store them. signatures, err := sm.Signatures() if err != nil { return distribution.Descriptor{}, err } if err := rs.repository.Signatures().Put(revision.Digest, signatures...); err != nil { return distribution.Descriptor{}, err } return revision, nil }
// put stores the manifest in the repository, if not already present. Any // updated signatures will be stored, as well. func (rs *revisionStore) put(sm *manifest.SignedManifest) (digest.Digest, error) { // Resolve the payload in the manifest. payload, err := sm.Payload() if err != nil { return "", err } // Digest and store the manifest payload in the blob store. revision, err := rs.blobStore.put(payload) if err != nil { logrus.Errorf("error putting payload into blobstore: %v", err) return "", err } // Link the revision into the repository. if err := rs.link(revision); err != nil { return "", err } // Grab each json signature and store them. signatures, err := sm.Signatures() if err != nil { return "", err } if err := rs.Signatures().Put(revision, signatures...); err != nil { return "", err } return revision, nil }
// Put creates or updates the named manifest. func (r *repository) Put(ctx context.Context, manifest *manifest.SignedManifest) error { // Resolve the payload in the manifest. payload, err := manifest.Payload() if err != nil { return err } // Calculate digest dgst, err := digest.FromBytes(payload) if err != nil { return err } // Upload to openshift ism := imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{ Namespace: r.namespace, Name: r.name, }, Tag: manifest.Tag, Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: dgst.String(), Annotations: map[string]string{ imageapi.ManagedByOpenShiftAnnotation: "true", }, }, DockerImageReference: fmt.Sprintf("%s/%s/%s@%s", r.registryAddr, r.namespace, r.name, dgst.String()), DockerImageManifest: string(payload), }, } if err := r.registryClient.ImageStreamMappings(r.namespace).Create(&ism); err != nil { // if the error was that the image stream wasn't found, try to auto provision it statusErr, ok := err.(*kerrors.StatusError) if !ok { log.Errorf("Error creating ImageStreamMapping: %s", err) return err } status := statusErr.ErrStatus if status.Code != http.StatusNotFound || status.Details.Kind != "imageStream" || status.Details.ID != r.name { log.Errorf("Error creating ImageStreamMapping: %s", err) return err } stream := imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: r.name, }, } client, ok := UserClientFrom(ctx) if !ok { log.Errorf("Error creating user client to auto provision ImageStream: OpenShift user client unavailable") return statusErr } if _, err := client.ImageStreams(r.namespace).Create(&stream); err != nil { log.Errorf("Error auto provisioning ImageStream: %s", err) return statusErr } // try to create the ISM again if err := r.registryClient.ImageStreamMappings(r.namespace).Create(&ism); err != nil { log.Errorf("Error creating ImageStreamMapping: %s", err) return err } } // Grab each json signature and store them. signatures, err := manifest.Signatures() if err != nil { return err } for _, signature := range signatures { if err := r.Signatures().Put(dgst, signature); err != nil { log.Errorf("Error storing signature: %s", err) return err } } return nil }