Skip to content

Commit

Permalink
添加push支持
Browse files Browse the repository at this point in the history
  • Loading branch information
go committed Sep 27, 2024
1 parent 49a7103 commit a6ec2ce
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 85 deletions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,33 @@
```


### 2) 拉取镜像到docker
### 5) 拉取镜像到docker
```
./gopull pull redis
```

### 3) 拉取Digest格式镜像到docker(需要指定 -t 参数)
### 6) 拉取Digest格式镜像到docker(需要指定 -t 参数)
```
./gopull pull sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 -t redis:custom_tag
```

### 4) login | logout
### 7) 推送镜像到镜像仓库
```
./gopull push redis
```

### 8) 推送镜像到镜像仓库并重名
```
./gopull push redis -t your_registry/your_repository:your_tag
```

### 9) login | logout
```
./gopull login docker.io
./gopull logout docker.io
```

### 4) 获取镜像详情
### 10) 获取镜像详情
```
./gopull inspect redis
```
Expand Down
84 changes: 84 additions & 0 deletions cmd/copy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package cmd

import (
"errors"
"fmt"
"io"

commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/common/pkg/retry"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/types"
)

type copyOptions struct {
global *globalOptions
deprecatedTLSVerify *deprecatedTLSVerifyOption
srcImage *imageOptions
destImage *imageDestOptions
retryOpts *retry.Options
format commonFlag.OptionalString // Force conversion of the image to a specified format
quiet bool // Suppress output information when copying images
}

type buildImageRefer func(string) (types.ImageReference, *types.SystemContext, error)

func (opts *copyOptions) execCopy(args []string, stdout io.Writer, s buildImageRefer, d buildImageRefer) (retErr error) {
if len(args) != 1 {
return errorShouldDisplayUsage{errors.New("image is required")}
}
opts.deprecatedTLSVerify.warnIfUsed([]string{"--src-tls-verify", "--dest-tls-verify"})
imageName := args[0]

policyContext, err := opts.global.getPolicyContext()
if err != nil {
return fmt.Errorf("error loading trust policy: %v", err)
}
defer func() {
if err := policyContext.Destroy(); err != nil {
retErr = noteCloseFailure(retErr, "tearing down policy context", err)
}
}()

srcRef, sourceCtx, err := s(imageName)
if err != nil {
return err
}

destRef, destCtx, err := d(imageName)
if err != nil {
return err
}

var manifestType string
if opts.format.Present() {
manifestType, err = parseManifestFormat(opts.format.Value())
if err != nil {
return err
}
}

ctx, cancel := opts.global.commandTimeoutContext()
defer cancel()

if opts.quiet {
stdout = nil
}

opts.destImage.warnAboutIneffectiveOptions(destRef.Transport())

return retry.IfNecessary(ctx, func() error {
_, err := copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: stdout,
SourceCtx: sourceCtx,
DestinationCtx: destCtx,
ForceManifestMIMEType: manifestType,
ImageListSelection: copy.CopySystemImage,
})
if err != nil {
return err
}

return nil
}, opts.retryOpts)
}
14 changes: 8 additions & 6 deletions cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ func download(global *globalOptions) *cobra.Command {
retryFlags, retryOpts := retryFlags()
opts := downloadOptions{
pullOptions: &pullOptions{
global: global,
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
srcImage: srcOpts,
destImage: destOpts,
retryOpts: retryOpts,
copyOptions: &copyOptions{
global: global,
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
srcImage: srcOpts,
destImage: destOpts,
retryOpts: retryOpts,
},
},
}
cmd := &cobra.Command{
Expand Down Expand Up @@ -63,7 +65,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
}

func (opts *downloadOptions) run(args []string, stdout io.Writer) error {
return opts.pullOptions.execCopy(args, stdout, opts.buildDestRef)
return opts.pullOptions.execCopy(args, stdout, opts.buildSrcRef, opts.buildDestRef)
}

func (opts *downloadOptions) buildDestRef(imageName string) (types.ImageReference, *types.SystemContext, error) {
Expand Down
91 changes: 16 additions & 75 deletions cmd/pull.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
package cmd

import (
"errors"
"fmt"
"gopull/pkgs/image"
"io"
"strings"

commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/common/pkg/retry"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/spf13/cobra"
)

type pullOptions struct {
global *globalOptions
deprecatedTLSVerify *deprecatedTLSVerifyOption
srcImage *imageOptions
destImage *imageDestOptions
retryOpts *retry.Options
format commonFlag.OptionalString // Force conversion of the image to a specified format
quiet bool // Suppress output information when copying images
addTag string // For docker-archive: destinations, in addition to the name:tag specified as destination, also add these
*copyOptions
addTag string // For docker-archive: destinations, in addition to the name:tag specified as destination, also add these

}

type buildDestFunc func(string) (types.ImageReference, *types.SystemContext, error)

func pull(global *globalOptions) *cobra.Command {
sharedFlags, sharedOpts := sharedImageFlags()
deprecatedTLSVerifyFlags, deprecatedTLSVerifyOpt := deprecatedTLSVerifyFlags()
srcFlags, srcOpts := imageFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "src-", "screds")
destFlags, destOpts := imageDestFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "dest-", "dcreds")
retryFlags, retryOpts := retryFlags()
opts := pullOptions{global: global,
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
srcImage: srcOpts,
destImage: destOpts,
retryOpts: retryOpts,
opts := pullOptions{
copyOptions: &copyOptions{
global: global,
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
srcImage: srcOpts,
destImage: destOpts,
retryOpts: retryOpts,
},
}
cmd := &cobra.Command{
Use: "pull [command options] IMAGE ",
Expand All @@ -65,76 +57,25 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
flags.AddFlagSet(&retryFlags)
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress output information when copying images")
flags.VarP(commonFlag.NewOptionalStringValue(&opts.format), "format", "f", `MANIFEST TYPE (oci, v2s1, or v2s2) to use in the destination (default is manifest type of source, with fallbacks)`)
flags.StringVarP(&opts.addTag, "tag", "t", "", "set dest tag ")
flags.StringVarP(&opts.addTag, "tag", "t", "", "set dest tag")
return cmd
}

func (opts *pullOptions) run(args []string, stdout io.Writer) error {
return opts.execCopy(args, stdout, opts.buildDestRef)
return opts.execCopy(args, stdout, opts.buildSrcRef, opts.buildDestRef)
}

func (opts *pullOptions) execCopy(args []string, stdout io.Writer, f buildDestFunc) (retErr error) {
if len(args) != 1 {
return errorShouldDisplayUsage{errors.New("image is required")}
}
opts.deprecatedTLSVerify.warnIfUsed([]string{"--src-tls-verify", "--dest-tls-verify"})
imageName := args[0]

policyContext, err := opts.global.getPolicyContext()
if err != nil {
return fmt.Errorf("error loading trust policy: %v", err)
}
defer func() {
if err := policyContext.Destroy(); err != nil {
retErr = noteCloseFailure(retErr, "tearing down policy context", err)
}
}()
func (opts *pullOptions) buildSrcRef(imageName string) (types.ImageReference, *types.SystemContext, error) {

srcRef, err := alltransports.ParseImageName("docker://" + imageName)
if err != nil {
return fmt.Errorf("invalid source name %s: %v", imageName, err)
return nil, nil, fmt.Errorf("invalid source name %s: %v", imageName, err)
}

sourceCtx, err := opts.srcImage.newSystemContext()
if err != nil {
return err
}
destRef, destCtx, err := f(imageName)
if err != nil {
return err
}

var manifestType string
if opts.format.Present() {
manifestType, err = parseManifestFormat(opts.format.Value())
if err != nil {
return err
}
}

ctx, cancel := opts.global.commandTimeoutContext()
defer cancel()

if opts.quiet {
stdout = nil
return nil, nil, err
}

opts.destImage.warnAboutIneffectiveOptions(destRef.Transport())

return retry.IfNecessary(ctx, func() error {
_, err := copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: stdout,
SourceCtx: sourceCtx,
DestinationCtx: destCtx,
ForceManifestMIMEType: manifestType,
ImageListSelection: copy.CopySystemImage,
})
if err != nil {
return err
}

return nil
}, opts.retryOpts)
return srcRef, sourceCtx, nil
}

func (opts *pullOptions) buildDestRef(imageName string) (types.ImageReference, *types.SystemContext, error) {
Expand Down
98 changes: 98 additions & 0 deletions cmd/push.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package cmd

import (
"fmt"
"io"
"strings"

commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/spf13/cobra"
)

type pushOptions struct {
*copyOptions
destTag string
}

func push(global *globalOptions) *cobra.Command {
sharedFlags, sharedOpts := sharedImageFlags()
deprecatedTLSVerifyFlags, deprecatedTLSVerifyOpt := deprecatedTLSVerifyFlags()
srcFlags, srcOpts := imageFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "src-", "screds")
destFlags, destOpts := imageDestFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "dest-", "dcreds")
retryFlags, retryOpts := retryFlags()
opts := pushOptions{
copyOptions: &copyOptions{
global: global,
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
srcImage: srcOpts,
destImage: destOpts,
retryOpts: retryOpts,
},
}
cmd := &cobra.Command{
Use: "push [command options] IMAGE ",
Short: "push an image",
Long: fmt.Sprintf(`Container "IMAGE-NAME" uses a "transport":"details" format.
Supported transports:
%s
See skopeo(1) section "IMAGE NAMES" for the expected format
`, strings.Join(transports.ListNames(), ", ")),
RunE: commandAction(opts.run),
Example: `gopull push redis
gopull push redis -t example.harbor.org/redis:v1
`,
ValidArgsFunction: autocompleteSupportedTransports,
}
adjustUsage(cmd)
flags := cmd.Flags()
flags.AddFlagSet(&sharedFlags)
flags.AddFlagSet(&deprecatedTLSVerifyFlags)
flags.AddFlagSet(&srcFlags)
flags.AddFlagSet(&destFlags)
flags.AddFlagSet(&retryFlags)
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress output information when copying images")
flags.VarP(commonFlag.NewOptionalStringValue(&opts.format), "format", "f", `MANIFEST TYPE (oci, v2s1, or v2s2) to use in the destination (default is manifest type of source, with fallbacks)`)
flags.StringVarP(&opts.destTag, "--tag", "t", "", "Push destination")
return cmd
}

func (opts *pushOptions) run(args []string, stdout io.Writer) error {
return opts.execCopy(args, stdout, opts.buildSrcRef, opts.buildDestRef)
}

func (opts *pushOptions) buildSrcRef(imageName string) (types.ImageReference, *types.SystemContext, error) {

srcRef, err := alltransports.ParseImageName("docker-daemon:" + imageName)
if err != nil {
return nil, nil, fmt.Errorf("invalid source name %s: %v", imageName, err)
}
sourceCtx, err := opts.srcImage.newSystemContext()
if err != nil {
return nil, nil, err
}
return srcRef, sourceCtx, nil
}

func (opts *pushOptions) buildDestRef(imageName string) (types.ImageReference, *types.SystemContext, error) {

dest := "docker://" + imageName
if opts.destTag != "" {
dest = "docker://" + opts.destTag
}

destRef, err := alltransports.ParseImageName(dest)
if err != nil {
return nil, nil, fmt.Errorf("invalid destination name %s: %v", dest, err)
}

destCtx, err := opts.destImage.newSystemContext()
if err != nil {
return nil, nil, err
}
return destRef, destCtx, nil
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func createApp() (*cobra.Command, *globalOptions) {
rootCommand.AddCommand(
download(&opts),
pull(&opts),
push(&opts),
inspectCmd(&opts),
loginCmd(&opts),
logoutCmd(&opts),
Expand Down

0 comments on commit a6ec2ce

Please sign in to comment.