mirror of
https://github.com/containers/skopeo.git
synced 2025-06-26 22:57:35 +00:00
refactor image manifest
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
50a2ed1124
commit
aa6d271975
99
docker.go
99
docker.go
@ -14,6 +14,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/pkg/homedir"
|
"github.com/docker/docker/pkg/homedir"
|
||||||
@ -32,11 +33,23 @@ const (
|
|||||||
dockerCfgObsolete = ".dockercfg"
|
dockerCfgObsolete = ".dockercfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)
|
var (
|
||||||
|
validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
type errFetchManifest struct {
|
||||||
|
statusCode int
|
||||||
|
body []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e errFetchManifest) Error() string {
|
||||||
|
return fmt.Sprintf("error fetching manifest: status code: %d, body: %s", e.statusCode, string(e.body))
|
||||||
|
}
|
||||||
|
|
||||||
type dockerImage struct {
|
type dockerImage struct {
|
||||||
ref reference.Named
|
ref reference.Named
|
||||||
tag string
|
tag string
|
||||||
|
digest string
|
||||||
registry string
|
registry string
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
@ -63,28 +76,75 @@ func (i *dockerImage) Manifest() (types.ImageManifest, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("error retrivieng manifest schema1")
|
return nil, fmt.Errorf("error retrivieng manifest schema1")
|
||||||
}
|
}
|
||||||
|
tags, err := i.getTags()
|
||||||
// TODO(runcom): get all tags, last argument, and digest
|
if err != nil {
|
||||||
return makeImageManifest(ms1, "", nil), nil
|
return nil, err
|
||||||
|
}
|
||||||
|
imgManifest, err := makeImageManifest(i.ref.FullName(), ms1, i.digest, tags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return imgManifest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeImageManifest(m *manifestSchema1, dgst string, tagList []string) types.ImageManifest {
|
func (i *dockerImage) getTags() ([]string, error) {
|
||||||
|
url := i.scheme + "://" + i.registry + "/v2/" + i.ref.RemoteName() + "/tags/list"
|
||||||
|
res, err := i.makeRequest("GET", url, i.WWWAuthenticate != "", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
// print url also
|
||||||
|
return nil, fmt.Errorf("Invalid status code returned when fetching tags list %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
type tagsRes struct {
|
||||||
|
Tags []string
|
||||||
|
}
|
||||||
|
tags := &tagsRes{}
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(tags); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tags.Tags, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
Labels map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type v1Image struct {
|
||||||
|
// Config is the configuration of the container received from the client
|
||||||
|
Config *config `json:"config,omitempty"`
|
||||||
|
// DockerVersion specifies version on which image is built
|
||||||
|
DockerVersion string `json:"docker_version,omitempty"`
|
||||||
|
// Created timestamp when image was created
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
// Architecture is the hardware that the image is build and runs on
|
||||||
|
Architecture string `json:"architecture,omitempty"`
|
||||||
|
// OS is the operating system used to build and run the image
|
||||||
|
OS string `json:"os,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeImageManifest(name string, m *manifestSchema1, dgst string, tagList []string) (types.ImageManifest, error) {
|
||||||
|
v1 := &v1Image{}
|
||||||
|
if err := json.Unmarshal([]byte(m.History[0].V1Compatibility), v1); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &types.DockerImageManifest{
|
return &types.DockerImageManifest{
|
||||||
|
Name: name,
|
||||||
Tag: m.Tag,
|
Tag: m.Tag,
|
||||||
Digest: dgst,
|
Digest: dgst,
|
||||||
RepoTags: tagList,
|
RepoTags: tagList,
|
||||||
Comment: "",
|
DockerVersion: v1.DockerVersion,
|
||||||
Created: "",
|
Created: v1.Created,
|
||||||
ContainerConfig: nil,
|
Labels: v1.Config.Labels,
|
||||||
DockerVersion: "",
|
Architecture: v1.Architecture,
|
||||||
Author: "",
|
Os: v1.OS,
|
||||||
Config: nil,
|
Layers: m.GetLayers(),
|
||||||
Architecture: "",
|
}, nil
|
||||||
Os: "",
|
|
||||||
Layers: nil,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(runcom)
|
||||||
func (i *dockerImage) DockerTar() ([]byte, error) {
|
func (i *dockerImage) DockerTar() ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -274,16 +334,15 @@ func (i *dockerImage) retrieveRawManifest() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
if res.StatusCode != http.StatusOK {
|
|
||||||
// print body also
|
|
||||||
return fmt.Errorf("Invalid status code returned when fetching manifest %d", res.StatusCode)
|
|
||||||
}
|
|
||||||
manblob, err := ioutil.ReadAll(res.Body)
|
manblob, err := ioutil.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return errFetchManifest{res.StatusCode, manblob}
|
||||||
|
}
|
||||||
i.rawManifest = manblob
|
i.rawManifest = manblob
|
||||||
|
i.digest = res.Header.Get("Docker-Content-Digest")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
containerTypes "github.com/docker/engine-api/types/container"
|
"fmt"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -34,30 +35,24 @@ type Image interface {
|
|||||||
// ImageManifest is the interesting subset of metadata about an Image.
|
// ImageManifest is the interesting subset of metadata about an Image.
|
||||||
// TODO(runcom)
|
// TODO(runcom)
|
||||||
type ImageManifest interface {
|
type ImageManifest interface {
|
||||||
Labels() map[string]string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// DockerImageManifest is a set of metadata describing Docker images and their manifest.json files.
|
// DockerImageManifest is a set of metadata describing Docker images and their manifest.json files.
|
||||||
// Note that this is not exactly manifest.json, e.g. some fields have been added.
|
// Note that this is not exactly manifest.json, e.g. some fields have been added.
|
||||||
type DockerImageManifest struct {
|
type DockerImageManifest struct {
|
||||||
|
Name string
|
||||||
Tag string
|
Tag string
|
||||||
Digest string
|
Digest string
|
||||||
RepoTags []string
|
RepoTags []string
|
||||||
Comment string
|
Created time.Time
|
||||||
Created string
|
|
||||||
ContainerConfig *containerTypes.Config // remove docker/docker code, this isn't needed
|
|
||||||
DockerVersion string
|
DockerVersion string
|
||||||
Author string
|
Labels map[string]string
|
||||||
Config *containerTypes.Config // remove docker/docker code, needs just Labels here for now, maybe Cmd? Hostname?
|
|
||||||
Architecture string
|
Architecture string
|
||||||
Os string
|
Os string
|
||||||
Layers []string // ???
|
Layers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Labels returns labels attached to this image.
|
func (m *DockerImageManifest) String() string {
|
||||||
func (m *DockerImageManifest) Labels() map[string]string {
|
return fmt.Sprintf("%s:%s", m.Name, m.Tag)
|
||||||
if m.Config == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return m.Config.Labels
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user