mirror of
https://github.com/crazy-max/diun.git
synced 2025-12-21 13:23:09 +01:00
Initial commit
This commit is contained in:
71
pkg/registry/client.go
Normal file
71
pkg/registry/client.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/docker"
|
||||
"github.com/containers/image/types"
|
||||
)
|
||||
|
||||
// Client represents an active registry object
|
||||
type Client struct{}
|
||||
|
||||
type Options struct {
|
||||
Image Image
|
||||
Username string
|
||||
Password string
|
||||
InsecureTLS bool
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// New creates new registry instance
|
||||
func New() (*Client, error) {
|
||||
return &Client{}, nil
|
||||
}
|
||||
|
||||
func (c *Client) timeoutContext(timeout time.Duration) (context.Context, context.CancelFunc) {
|
||||
ctx := context.Background()
|
||||
var cancel context.CancelFunc = func() {}
|
||||
if timeout > 0 {
|
||||
ctx, cancel = context.WithTimeout(ctx, timeout)
|
||||
} else {
|
||||
ctx, cancel = context.WithTimeout(ctx, 5*time.Second)
|
||||
}
|
||||
return ctx, cancel
|
||||
}
|
||||
|
||||
func (c *Client) newImage(ctx context.Context, opts *Options) (types.ImageCloser, *types.SystemContext, error) {
|
||||
image := opts.Image.String()
|
||||
if !strings.HasPrefix(opts.Image.String(), "//") {
|
||||
image = fmt.Sprintf("//%s", opts.Image.String())
|
||||
}
|
||||
|
||||
ref, err := docker.ParseReference(image)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("invalid image name %s: %v", image, err)
|
||||
}
|
||||
|
||||
auth := &types.DockerAuthConfig{}
|
||||
if opts.Username != "" {
|
||||
auth = &types.DockerAuthConfig{
|
||||
Username: opts.Username,
|
||||
Password: opts.Password,
|
||||
}
|
||||
}
|
||||
|
||||
sys := &types.SystemContext{
|
||||
DockerAuthConfig: auth,
|
||||
DockerDaemonInsecureSkipTLSVerify: opts.InsecureTLS,
|
||||
DockerInsecureSkipTLSVerify: types.NewOptionalBool(opts.InsecureTLS),
|
||||
}
|
||||
|
||||
img, err := ref.NewImage(ctx, sys)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return img, sys, nil
|
||||
}
|
||||
69
pkg/registry/image.go
Normal file
69
pkg/registry/image.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// Source: https://github.com/genuinetools/reg/blob/master/registry/image.go
|
||||
|
||||
package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/image/docker/reference"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// Image holds information about an image.
|
||||
type Image struct {
|
||||
Domain string
|
||||
Path string
|
||||
Tag string
|
||||
Digest digest.Digest
|
||||
named reference.Named
|
||||
}
|
||||
|
||||
// String returns the string representation of an image.
|
||||
func (i Image) String() string {
|
||||
return i.named.String()
|
||||
}
|
||||
|
||||
// Reference returns either the digest if it is non-empty or the tag for the image.
|
||||
func (i Image) Reference() string {
|
||||
if len(i.Digest.String()) > 1 {
|
||||
return i.Digest.String()
|
||||
}
|
||||
|
||||
return i.Tag
|
||||
}
|
||||
|
||||
// WithDigest sets the digest for an image.
|
||||
func (i *Image) WithDigest(digest digest.Digest) (err error) {
|
||||
i.Digest = digest
|
||||
i.named, err = reference.WithDigest(i.named, digest)
|
||||
return err
|
||||
}
|
||||
|
||||
// ParseImage returns an Image struct with all the values filled in for a given image.
|
||||
func ParseImage(image string) (Image, error) {
|
||||
// Parse the image name and tag.
|
||||
named, err := reference.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
return Image{}, fmt.Errorf("parsing image %q failed: %v", image, err)
|
||||
}
|
||||
// Add the latest lag if they did not provide one.
|
||||
named = reference.TagNameOnly(named)
|
||||
|
||||
i := Image{
|
||||
named: named,
|
||||
Domain: reference.Domain(named),
|
||||
Path: reference.Path(named),
|
||||
}
|
||||
|
||||
// Add the tag if there was one.
|
||||
if tagged, ok := named.(reference.Tagged); ok {
|
||||
i.Tag = tagged.Tag()
|
||||
}
|
||||
|
||||
// Add the digest if there was one.
|
||||
if canonical, ok := named.(reference.Canonical); ok {
|
||||
i.Digest = canonical.Digest()
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
66
pkg/registry/inspect.go
Normal file
66
pkg/registry/inspect.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
type Inspect struct {
|
||||
Name string
|
||||
Tag string
|
||||
MIMEType string
|
||||
Digest digest.Digest
|
||||
Created *time.Time
|
||||
DockerVersion string
|
||||
Labels map[string]string
|
||||
Architecture string
|
||||
Os string
|
||||
Layers []string
|
||||
}
|
||||
|
||||
// Inspect inspects a Docker image
|
||||
func (c *Client) Inspect(opts *Options) (Inspect, error) {
|
||||
ctx, cancel := c.timeoutContext(opts.Timeout)
|
||||
defer cancel()
|
||||
|
||||
img, _, err := c.newImage(ctx, opts)
|
||||
if err != nil {
|
||||
return Inspect{}, err
|
||||
}
|
||||
defer img.Close()
|
||||
|
||||
rawManifest, _, err := img.Manifest(ctx)
|
||||
if err != nil {
|
||||
return Inspect{}, err
|
||||
}
|
||||
|
||||
imgInspect, err := img.Inspect(ctx)
|
||||
if err != nil {
|
||||
return Inspect{}, err
|
||||
}
|
||||
|
||||
imgDigest, err := manifest.Digest(rawManifest)
|
||||
if err != nil {
|
||||
return Inspect{}, err
|
||||
}
|
||||
|
||||
imgTag := imgInspect.Tag
|
||||
if imgTag == "" {
|
||||
imgTag = opts.Image.Tag
|
||||
}
|
||||
|
||||
return Inspect{
|
||||
Name: img.Reference().DockerReference().Name(),
|
||||
Tag: imgTag,
|
||||
MIMEType: manifest.GuessMIMEType(rawManifest),
|
||||
Digest: imgDigest,
|
||||
Created: imgInspect.Created,
|
||||
DockerVersion: imgInspect.DockerVersion,
|
||||
Labels: imgInspect.Labels,
|
||||
Architecture: imgInspect.Architecture,
|
||||
Os: imgInspect.Os,
|
||||
Layers: imgInspect.Layers,
|
||||
}, nil
|
||||
}
|
||||
26
pkg/registry/tags.go
Normal file
26
pkg/registry/tags.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"github.com/containers/image/docker"
|
||||
)
|
||||
|
||||
type Tags []string
|
||||
|
||||
// Tags returns tags of a Docker repository
|
||||
func (c *Client) Tags(opts *Options) (Tags, error) {
|
||||
ctx, cancel := c.timeoutContext(opts.Timeout)
|
||||
defer cancel()
|
||||
|
||||
img, sys, err := c.newImage(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer img.Close()
|
||||
|
||||
tags, err := docker.GetRepositoryTags(ctx, sys, img.Reference())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return Tags(tags), err
|
||||
}
|
||||
Reference in New Issue
Block a user