Review of platform detection (#56)

* Leave default image platform empty for static provider (see FAQ doc)
* Handle platform variant
* Add database migration process
* Switch to Open Container Specification labels as label-schema.org ones are deprecated
* Remove unneeded `diun.os` and `diun.arch` docker labels

Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2020-03-31 23:27:10 +02:00
committed by GitHub
parent 2893414f59
commit 9c797f1616
28 changed files with 661 additions and 221 deletions

View File

@@ -1,6 +1,7 @@
package registry
import (
"fmt"
"time"
"github.com/containers/image/v5/manifest"
@@ -16,9 +17,8 @@ type Manifest struct {
Created *time.Time
DockerVersion string
Labels map[string]string
Architecture string
Os string
Layers []string
Platform string `json:"-"`
}
// Manifest returns the manifest for a specific image
@@ -26,18 +26,18 @@ func (c *Client) Manifest(image Image) (Manifest, error) {
ctx, cancel := c.timeoutContext()
defer cancel()
imgCls, err := c.newImage(ctx, image.String())
imgCloser, err := c.newImage(ctx, image.String())
if err != nil {
return Manifest{}, err
}
defer imgCls.Close()
defer imgCloser.Close()
rawManifest, _, err := imgCls.Manifest(ctx)
rawManifest, _, err := imgCloser.Manifest(ctx)
if err != nil {
return Manifest{}, err
}
imgInspect, err := imgCls.Inspect(ctx)
imgInspect, err := imgCloser.Inspect(ctx)
if err != nil {
return Manifest{}, err
}
@@ -52,16 +52,20 @@ func (c *Client) Manifest(image Image) (Manifest, error) {
imgTag = image.Tag
}
imgPlatform := fmt.Sprintf("%s/%s", imgInspect.Os, imgInspect.Architecture)
if imgInspect.Variant != "" {
imgPlatform = fmt.Sprintf("%s/%s", imgPlatform, imgInspect.Variant)
}
return Manifest{
Name: imgCls.Reference().DockerReference().Name(),
Name: imgCloser.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,
Platform: imgPlatform,
}, nil
}

View File

@@ -0,0 +1,37 @@
package registry_test
import (
"encoding/json"
"fmt"
"testing"
"github.com/crazy-max/diun/pkg/registry"
"github.com/stretchr/testify/assert"
)
func TestManifestVariant(t *testing.T) {
rc, err := registry.New(registry.Options{
ImageOs: "linux",
ImageArch: "arm",
ImageVariant: "v7",
})
if err != nil {
panic(err.Error())
}
img, err := registry.ParseImage("crazymax/diun:2.5.0")
if err != nil {
t.Error(err)
}
manifest, err := rc.Manifest(img)
b, _ := json.MarshalIndent(manifest, "", " ")
fmt.Println(string(b))
assert.NoError(t, err)
assert.Equal(t, "docker.io/crazymax/diun", manifest.Name)
assert.Equal(t, "2.5.0", manifest.Tag)
assert.Equal(t, "application/vnd.docker.distribution.manifest.list.v2+json", manifest.MIMEType)
assert.Equal(t, "linux/arm/v7", manifest.Platform)
assert.Empty(t, manifest.DockerVersion)
}

View File

@@ -18,13 +18,14 @@ type Client struct {
// Options holds docker registry object options
type Options struct {
Os string
Arch string
Username string
Password string
InsecureTLS bool
Timeout time.Duration
UserAgent string
Username string
Password string
InsecureTLS bool
Timeout time.Duration
UserAgent string
ImageOs string
ImageArch string
ImageVariant string
}
// New creates new docker registry client instance
@@ -40,12 +41,13 @@ func New(opts Options) (*Client, error) {
// Sys context
sysCtx := &types.SystemContext{
OSChoice: opts.Os,
ArchitectureChoice: opts.Arch,
DockerAuthConfig: auth,
DockerDaemonInsecureSkipTLSVerify: opts.InsecureTLS,
DockerInsecureSkipTLSVerify: types.NewOptionalBool(opts.InsecureTLS),
DockerRegistryUserAgent: opts.UserAgent,
OSChoice: opts.ImageOs,
ArchitectureChoice: opts.ImageArch,
VariantChoice: opts.ImageVariant,
}
return &Client{

View File

@@ -0,0 +1,28 @@
package registry_test
import (
"os"
"testing"
"github.com/crazy-max/diun/pkg/registry"
"github.com/stretchr/testify/assert"
)
var (
rc *registry.Client
)
func TestMain(m *testing.M) {
var err error
rc, err = registry.New(registry.Options{})
if err != nil {
panic(err.Error())
}
os.Exit(m.Run())
}
func TestNew(t *testing.T) {
assert.NotNil(t, rc)
}