push to docker registry
This commit is contained in:
parent
559506c170
commit
8de564e62e
4 changed files with 88 additions and 16 deletions
|
@ -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")
|
||||
|
||||
|
@ -515,7 +578,7 @@ func (l *StaticRegistryManager) Scan() error {
|
|||
// we ignore sha256 addressed manifests
|
||||
continue
|
||||
}
|
||||
id := ImageDescriptor {
|
||||
id := ImageDescriptor{
|
||||
Tag: fname,
|
||||
Date: obj.ModTime,
|
||||
}
|
||||
|
@ -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)
|
||||
|
|
|
@ -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,7 +220,7 @@ func (am *ArtifactManager) Scan() error {
|
|||
}
|
||||
fname := ksplit[len(ksplit)-1]
|
||||
|
||||
ad := ArtifactDescriptor {
|
||||
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
3
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||
|
|
Loading…
Reference in a new issue