2016-07-20 09:46:01 +00:00
|
|
|
package docker
|
|
|
|
|
|
|
|
import (
|
2017-08-05 11:40:46 +00:00
|
|
|
"context"
|
2016-07-20 09:46:01 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2017-03-13 16:33:17 +00:00
|
|
|
"github.com/containers/image/docker/reference"
|
2016-07-20 09:46:01 +00:00
|
|
|
"github.com/containers/image/image"
|
|
|
|
"github.com/containers/image/types"
|
2016-10-17 13:53:40 +00:00
|
|
|
"github.com/pkg/errors"
|
2016-07-20 09:46:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Image is a Docker-specific implementation of types.Image with a few extra methods
|
|
|
|
// which are specific to Docker.
|
|
|
|
type Image struct {
|
|
|
|
types.Image
|
|
|
|
src *dockerImageSource
|
|
|
|
}
|
|
|
|
|
|
|
|
// newImage returns a new Image interface type after setting up
|
|
|
|
// a client to the registry hosting the given image.
|
2016-09-17 13:50:35 +00:00
|
|
|
// The caller must call .Close() on the returned Image.
|
|
|
|
func newImage(ctx *types.SystemContext, ref dockerReference) (types.Image, error) {
|
2017-09-13 17:01:06 +00:00
|
|
|
s, err := newImageSource(ctx, ref)
|
2016-07-20 09:46:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2016-11-22 19:32:10 +00:00
|
|
|
img, err := image.FromSource(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &Image{Image: img, src: s}, nil
|
2016-07-20 09:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SourceRefFullName returns a fully expanded name for the repository this image is in.
|
|
|
|
func (i *Image) SourceRefFullName() string {
|
2017-03-13 16:33:17 +00:00
|
|
|
return i.src.ref.ref.Name()
|
2016-07-20 09:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetRepositoryTags list all tags available in the repository. Note that this has no connection with the tag(s) used for this specific image, if any.
|
|
|
|
func (i *Image) GetRepositoryTags() ([]string, error) {
|
2017-04-03 07:22:44 +00:00
|
|
|
path := fmt.Sprintf(tagsPath, reference.Path(i.src.ref.ref))
|
2017-08-05 11:40:46 +00:00
|
|
|
// FIXME: Pass the context.Context
|
|
|
|
res, err := i.src.c.makeRequest(context.TODO(), "GET", path, nil, nil)
|
2016-07-20 09:46:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
// print url also
|
2016-10-17 13:53:40 +00:00
|
|
|
return nil, errors.Errorf("Invalid status code returned when fetching tags list %d", res.StatusCode)
|
2016-07-20 09:46:01 +00:00
|
|
|
}
|
|
|
|
type tagsRes struct {
|
|
|
|
Tags []string
|
|
|
|
}
|
|
|
|
tags := &tagsRes{}
|
|
|
|
if err := json.NewDecoder(res.Body).Decode(tags); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return tags.Tags, nil
|
|
|
|
}
|