mirror of
https://github.com/containers/skopeo.git
synced 2025-06-27 15:18:00 +00:00
add mimetypes
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
814a2a6f94
commit
7d12b66fb8
@ -54,7 +54,7 @@ func copyHandler(context *cli.Context) {
|
|||||||
}
|
}
|
||||||
signBy := context.String("sign-by")
|
signBy := context.String("sign-by")
|
||||||
|
|
||||||
manifest, err := src.GetManifest()
|
manifest, _, err := src.GetManifest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalf("Error reading manifest: %s", err.Error())
|
logrus.Fatalf("Error reading manifest: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,13 @@ func (s *dirImageSource) IntendedDockerReference() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dirImageSource) GetManifest() ([]byte, error) {
|
// it's up to the caller to determine the MIME type of the returned manifest's bytes
|
||||||
return ioutil.ReadFile(manifestPath(s.dir))
|
func (s *dirImageSource) GetManifest() ([]byte, string, error) {
|
||||||
|
m, err := ioutil.ReadFile(manifestPath(s.dir))
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
return m, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dirImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
func (s *dirImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
||||||
|
@ -44,7 +44,7 @@ func (i *dockerImage) IntendedDockerReference() string {
|
|||||||
// Manifest is like ImageSource.GetManifest, but the result is cached; it is OK to call this however often you need.
|
// Manifest is like ImageSource.GetManifest, but the result is cached; it is OK to call this however often you need.
|
||||||
func (i *dockerImage) Manifest() ([]byte, error) {
|
func (i *dockerImage) Manifest() ([]byte, error) {
|
||||||
if i.cachedManifest == nil {
|
if i.cachedManifest == nil {
|
||||||
m, err := i.src.GetManifest()
|
m, _, err := i.src.GetManifest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -55,24 +55,24 @@ func (s *dockerImageSource) IntendedDockerReference() string {
|
|||||||
return fmt.Sprintf("%s:%s", s.ref.Name(), s.tag)
|
return fmt.Sprintf("%s:%s", s.ref.Name(), s.tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) GetManifest() ([]byte, error) {
|
func (s *dockerImageSource) GetManifest() ([]byte, string, error) {
|
||||||
url := fmt.Sprintf(manifestURL, s.ref.RemoteName(), s.tag)
|
url := fmt.Sprintf(manifestURL, s.ref.RemoteName(), s.tag)
|
||||||
// TODO(runcom) set manifest version header! schema1 for now - then schema2 etc etc and v1
|
// TODO(runcom) set manifest version header! schema1 for now - then schema2 etc etc and v1
|
||||||
// TODO(runcom) NO, switch on the resulter manifest like Docker is doing
|
// TODO(runcom) NO, switch on the resulter manifest like Docker is doing
|
||||||
res, err := s.c.makeRequest("GET", url, nil, nil)
|
res, err := s.c.makeRequest("GET", url, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
manblob, err := ioutil.ReadAll(res.Body)
|
manblob, err := ioutil.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return nil, errFetchManifest{res.StatusCode, manblob}
|
return nil, "", errFetchManifest{res.StatusCode, manblob}
|
||||||
}
|
}
|
||||||
// We might validate manblob against the Docker-Content-Digest header here to protect against transport errors.
|
// We might validate manblob against the Docker-Content-Digest header here to protect against transport errors.
|
||||||
return manblob, nil
|
return manblob, res.Header.Get("Content-Type"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
func (s *dockerImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
||||||
|
56
docker/utils/fixtures/v2list.manifest.json
Normal file
56
docker/utils/fixtures/v2list.manifest.json
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 2,
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
|
||||||
|
"manifests": [
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
||||||
|
"size": 2094,
|
||||||
|
"digest": "sha256:7820f9a86d4ad15a2c4f0c0e5479298df2aa7c2f6871288e2ef8546f3e7b6783",
|
||||||
|
"platform": {
|
||||||
|
"architecture": "ppc64le",
|
||||||
|
"os": "linux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
||||||
|
"size": 1922,
|
||||||
|
"digest": "sha256:ae1b0e06e8ade3a11267564a26e750585ba2259c0ecab59ab165ad1af41d1bdd",
|
||||||
|
"platform": {
|
||||||
|
"architecture": "amd64",
|
||||||
|
"os": "linux",
|
||||||
|
"features": [
|
||||||
|
"sse"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
||||||
|
"size": 2084,
|
||||||
|
"digest": "sha256:e4c0df75810b953d6717b8f8f28298d73870e8aa2a0d5e77b8391f16fdfbbbe2",
|
||||||
|
"platform": {
|
||||||
|
"architecture": "s390x",
|
||||||
|
"os": "linux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
||||||
|
"size": 2084,
|
||||||
|
"digest": "sha256:07ebe243465ef4a667b78154ae6c3ea46fdb1582936aac3ac899ea311a701b40",
|
||||||
|
"platform": {
|
||||||
|
"architecture": "arm",
|
||||||
|
"os": "linux",
|
||||||
|
"variant": "armv7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
||||||
|
"size": 2090,
|
||||||
|
"digest": "sha256:fb2fc0707b86dafa9959fe3d29e66af8787aee4d9a23581714be65db4265ad8a",
|
||||||
|
"platform": {
|
||||||
|
"architecture": "arm64",
|
||||||
|
"os": "linux",
|
||||||
|
"variant": "armv8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -10,11 +10,22 @@ import (
|
|||||||
|
|
||||||
// FIXME: Should we just use docker/distribution and docker/docker implementations directly?
|
// FIXME: Should we just use docker/distribution and docker/docker implementations directly?
|
||||||
|
|
||||||
|
// ManifestMIMETypes returns a slice of supported MIME types
|
||||||
|
func ManifestMIMETypes() []string {
|
||||||
|
return []string{
|
||||||
|
DockerV2Schema1MIMEType,
|
||||||
|
DockerV2Schema2MIMEType,
|
||||||
|
DockerV2ListMIMEType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DockerV2Schema1MIMEType MIME type represents Docker manifest schema 1
|
// DockerV2Schema1MIMEType MIME type represents Docker manifest schema 1
|
||||||
DockerV2Schema1MIMEType = "application/vnd.docker.distribution.manifest.v1+json"
|
DockerV2Schema1MIMEType = "application/vnd.docker.distribution.manifest.v1+json"
|
||||||
// DockerV2Schema2MIMEType MIME type represents Docker manifest schema 2
|
// DockerV2Schema2MIMEType MIME type represents Docker manifest schema 2
|
||||||
DockerV2Schema2MIMEType = "application/vnd.docker.distribution.manifest.v2+json"
|
DockerV2Schema2MIMEType = "application/vnd.docker.distribution.manifest.v2+json"
|
||||||
|
// DockerV2ListMIMEType MIME type represents Docker manifest schema 2 list
|
||||||
|
DockerV2ListMIMEType = "application/vnd.docker.distribution.manifest.list.v2+json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GuessManifestMIMEType guesses MIME type of a manifest and returns it _if it is recognized_, or "" if unknown or unrecognized.
|
// GuessManifestMIMEType guesses MIME type of a manifest and returns it _if it is recognized_, or "" if unknown or unrecognized.
|
||||||
@ -32,7 +43,7 @@ func GuessManifestMIMEType(manifest []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch meta.MediaType {
|
switch meta.MediaType {
|
||||||
case DockerV2Schema2MIMEType: // A recognized type.
|
case DockerV2Schema2MIMEType, DockerV2ListMIMEType: // A recognized type.
|
||||||
return meta.MediaType
|
return meta.MediaType
|
||||||
}
|
}
|
||||||
switch meta.SchemaVersion {
|
switch meta.SchemaVersion {
|
||||||
|
@ -15,6 +15,7 @@ func TestGuessManifestMIMEType(t *testing.T) {
|
|||||||
mimeType string
|
mimeType string
|
||||||
}{
|
}{
|
||||||
{"v2s2.manifest.json", DockerV2Schema2MIMEType},
|
{"v2s2.manifest.json", DockerV2Schema2MIMEType},
|
||||||
|
{"v2list.manifest.json", DockerV2ListMIMEType},
|
||||||
{"v2s1.manifest.json", DockerV2Schema1MIMEType},
|
{"v2s1.manifest.json", DockerV2Schema1MIMEType},
|
||||||
{"v2s1-invalid-signatures.manifest.json", DockerV2Schema1MIMEType},
|
{"v2s1-invalid-signatures.manifest.json", DockerV2Schema1MIMEType},
|
||||||
{"v2s2nomime.manifest.json", DockerV2Schema2MIMEType}, // It is unclear whether this one is legal, but we should guess v2s2 if anything at all.
|
{"v2s2nomime.manifest.json", DockerV2Schema2MIMEType}, // It is unclear whether this one is legal, but we should guess v2s2 if anything at all.
|
||||||
|
@ -193,9 +193,9 @@ func (s *openshiftImageSource) IntendedDockerReference() string {
|
|||||||
return s.client.canonicalDockerReference()
|
return s.client.canonicalDockerReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *openshiftImageSource) GetManifest() ([]byte, error) {
|
func (s *openshiftImageSource) GetManifest() ([]byte, string, error) {
|
||||||
if err := s.ensureImageIsResolved(); err != nil {
|
if err := s.ensureImageIsResolved(); err != nil {
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
return s.docker.GetManifest()
|
return s.docker.GetManifest()
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,8 @@ type ImageSource interface {
|
|||||||
// (not as the image itself, or its underlying storage, claims). This can be used e.g. to determine which public keys are trusted for this image.
|
// (not as the image itself, or its underlying storage, claims). This can be used e.g. to determine which public keys are trusted for this image.
|
||||||
// May be "" if unknown.
|
// May be "" if unknown.
|
||||||
IntendedDockerReference() string
|
IntendedDockerReference() string
|
||||||
// GetManifest returns the image's manifest. It may use a remote (= slow) service.
|
// GetManifest returns the image's manifest along with its MIME type. The empty string is returned if the MIME type is unknown. It may use a remote (= slow) service.
|
||||||
// FIXME? This should also return a MIME type if known, to differentiate between schema versions.
|
GetManifest() ([]byte, string, error)
|
||||||
GetManifest() ([]byte, error)
|
|
||||||
// Note: Calling GetLayer() may have ordering dependencies WRT other methods of this type. FIXME: How does this work with (docker save) on stdin?
|
// Note: Calling GetLayer() may have ordering dependencies WRT other methods of this type. FIXME: How does this work with (docker save) on stdin?
|
||||||
GetLayer(digest string) (io.ReadCloser, error)
|
GetLayer(digest string) (io.ReadCloser, error)
|
||||||
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
|
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
|
||||||
|
Loading…
Reference in New Issue
Block a user