experimental/manifest.go (79 lines of code) (raw):

package experimental import ( "encoding/json" "fmt" "path/filepath" "sync" "github.com/Sirupsen/logrus" "github.com/docker/distribution" "github.com/docker/distribution/manifest" "github.com/docker/distribution/manifest/manifestlist" "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" ) type manifestData struct { digest digest layers []digest loaded bool loadErr error loadLock sync.Mutex } func deserializeManifest(data []byte) (distribution.Manifest, error) { var versioned manifest.Versioned if err := json.Unmarshal(data, &versioned); err != nil { return nil, err } switch versioned.SchemaVersion { case 1: var sm schema1.SignedManifest err := json.Unmarshal(data, &sm) return sm, err case 2: // This can be an image manifest or a manifest list switch versioned.MediaType { case schema2.MediaTypeManifest: var m schema2.DeserializedManifest err := json.Unmarshal(data, &m) return m, err case manifestlist.MediaTypeManifestList: var m manifestlist.DeserializedManifestList err := json.Unmarshal(data, &m) return m, err default: return nil, distribution.ErrManifestVerification{fmt.Errorf("unrecognized manifest content type %s", versioned.MediaType)} } } return nil, fmt.Errorf("unrecognized manifest schema version %d", versioned.SchemaVersion) } func (m *manifestData) path() string { return filepath.Join("blobs", m.digest.scopedPath(), "data") } func (m *manifestData) load(blobs blobsData) error { logrus.Println("MANIFEST:", m.path(), ": loading...") data, err := currentStorage.Read(m.path(), blobs.etag(m.digest)) if err != nil { return err } manifest, err := deserializeManifest(data) if err != nil { return err } for _, reference := range manifest.References() { digest, err := newDigestFromReference([]byte(reference.Digest)) if err != nil { return err } m.layers = append(m.layers, digest) } return nil } func (m *manifestData) ensureLoaded(blobs blobsData) error { if !m.loaded { m.loadLock.Lock() defer m.loadLock.Unlock() if !m.loaded { m.loadErr = m.load(blobs) m.loaded = true } } return m.loadErr }