push to docker registry

This commit is contained in:
Quentin 2023-05-03 13:47:53 +02:00
parent 559506c170
commit 8de564e62e
Signed by: quentin
GPG key ID: E9602264D639FF68
4 changed files with 88 additions and 16 deletions

View file

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
"path/filepath"
@ -15,6 +16,13 @@ import (
"strings"
"time"
"github.com/docker/cli/cli/config"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/transports/alltransports"
@ -27,6 +35,27 @@ var pctx *signature.PolicyContext
const distributionPrefix = "v2"
//---
//--- vendored from crane
// headerTransport sets headers on outgoing requests.
type headerTransport struct {
httpHeaders map[string]string
inner http.RoundTripper
}
// RoundTrip implements http.RoundTripper.
func (ht *headerTransport) RoundTrip(in *http.Request) (*http.Response, error) {
for k, v := range ht.httpHeaders {
if http.CanonicalHeaderKey(k) == "User-Agent" {
// Docker sets this, which is annoying, since we're not docker.
// We might want to revisit completely ignoring this.
continue
}
in.Header.Set(k, v)
}
return ht.inner.RoundTrip(in)
}
//---
//--- Image converter
type OCIImageManifest struct {
@ -345,6 +374,40 @@ func (o *OCIMultiArch) MergeSystemImages() error {
return nil
}
func (o *OCIMultiArch) UploadImageRegistry(tag string) error {
fmt.Println("--- push to registry ---")
multiArchRoot := filepath.Join(o.path, "multi")
img, err := layout.ImageIndexFromPath(multiArchRoot)
if err != nil {
return fmt.Errorf("loading %s as OCI layout: %w", multiArchRoot, err)
}
ref, err := name.ParseReference(tag)
if err != nil {
return err
}
// Build transport
transport := remote.DefaultTransport.(*http.Transport).Clone()
var rt http.RoundTripper = transport
cf, err := config.Load(os.Getenv("DOCKER_CONFIG"))
if err != nil {
fmt.Printf("failed to read config file: %v", err)
} else if len(cf.HTTPHeaders) != 0 {
rt = &headerTransport{
inner: rt,
httpHeaders: cf.HTTPHeaders,
}
}
if err := remote.WriteIndex(ref, img, remote.WithTransport(rt), remote.WithAuthFromKeychain(authn.DefaultKeychain)); err != nil {
return err
}
return nil
}
func (o *OCIMultiArch) UploadImageS3(buck *blob.Bucket) error {
fmt.Printf("-- push to the s3 target --\n")
@ -466,13 +529,13 @@ func (o *OCIMultiArch) UploadImageS3(buck *blob.Bucket) error {
}
type StaticRegistryManager struct {
name string
buck *blob.Bucket
name string
buck *blob.Bucket
images []ImageDescriptor
}
type ImageDescriptor struct {
Tag string
Tag string
Date time.Time
}
@ -515,8 +578,8 @@ func (l *StaticRegistryManager) Scan() error {
// we ignore sha256 addressed manifests
continue
}
id := ImageDescriptor {
Tag: fname,
id := ImageDescriptor{
Tag: fname,
Date: obj.ModTime,
}
l.images = append(l.images, id)
@ -531,7 +594,7 @@ func (l *StaticRegistryManager) TagList() TagList {
})
// Build tagList
tagList := TagList {
tagList := TagList{
Name: l.name,
}
for _, img := range l.images {
@ -584,6 +647,9 @@ var containerPublishCmd = &cobra.Command{
localPath := args[0]
remotePath := args[1]
dockerProto := "docker://"
dockerProtoCut := len(dockerProto)
oi, err := NewOCIMultiArch(containerTag)
if err != nil {
fmt.Println(err)
@ -601,7 +667,7 @@ var containerPublishCmd = &cobra.Command{
os.Exit(1)
}
if strings.HasPrefix(remotePath, "s3:") {
if strings.HasPrefix(remotePath, "s3://") {
// open bucket
bucket, err := blob.OpenBucket(context.Background(), remotePath)
if err != nil {
@ -621,6 +687,11 @@ var containerPublishCmd = &cobra.Command{
fmt.Println(err)
os.Exit(1)
}
} else if strings.HasPrefix(remotePath, dockerProto) {
if err = oi.UploadImageRegistry(remotePath[dockerProtoCut:]); err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
fmt.Printf("Protocol not supported for remote path %s. Supported transports are s3:// and docker://\n", remotePath)
os.Exit(1)

View file

@ -181,12 +181,12 @@ func (a *Artifact) Upload(buck *blob.Bucket) error {
//--- Manage uploaded artifacts, list them, etc.
type ArtifactDescriptor struct {
Tag string
Tag string
Date time.Time
}
type ArtifactManager struct {
name string
buck *blob.Bucket
name string
buck *blob.Bucket
artifacts []ArtifactDescriptor
}
@ -197,7 +197,6 @@ func NewArtifactManager(buck *blob.Bucket, name string) *ArtifactManager {
}
}
func (am *ArtifactManager) Scan() error {
iter := am.buck.List(&blob.ListOptions{
Prefix: fmt.Sprintf("df-dist-v1/%s/", am.name),
@ -221,8 +220,8 @@ func (am *ArtifactManager) Scan() error {
}
fname := ksplit[len(ksplit)-1]
ad := ArtifactDescriptor {
Tag: fname,
ad := ArtifactDescriptor{
Tag: fname,
Date: obj.ModTime,
}
@ -238,7 +237,7 @@ func (am *ArtifactManager) TagList() TagList {
})
// Build tagList
tagList := TagList {
tagList := TagList{
Name: am.name,
}
for _, art := range am.artifacts {
@ -247,7 +246,6 @@ func (am *ArtifactManager) TagList() TagList {
return tagList
}
func (am *ArtifactManager) UpdateTagList() error {
fmt.Printf("--- update taglist ---\n")

3
go.mod
View file

@ -6,6 +6,8 @@ require (
code.gitea.io/sdk/gitea v0.15.1
github.com/caarlos0/env/v7 v7.1.0
github.com/containers/image/v5 v5.25.0
github.com/docker/cli v20.10.20+incompatible
github.com/google/go-containerregistry v0.13.0
github.com/hashicorp/consul/api v1.20.0
github.com/hashicorp/nomad/api v0.0.0-20230314144600-1a01e8719272
github.com/spf13/cobra v1.7.0
@ -67,7 +69,6 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-containerregistry v0.13.0 // indirect
github.com/google/go-intervals v0.0.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/wire v0.5.0 // indirect

2
go.sum
View file

@ -847,6 +847,8 @@ github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyG
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4=
github.com/docker/cli v20.10.20+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=