This is an automated email from the ASF dual-hosted git repository.

zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git


The following commit(s) were added to refs/heads/master by this push:
     new a8db05ca [dubboctl] add image push commnd logic (#581)
a8db05ca is described below

commit a8db05caa6f3baafabd26f22e7f04cddc7081381
Author: Jian Zhong <[email protected]>
AuthorDate: Wed Feb 5 14:00:40 2025 +0800

    [dubboctl] add image push commnd logic (#581)
---
 dubboctl/cmd/image.go         | 80 +++++++++++++++++++++++++++++++++++++++++--
 dubboctl/pkg/hub/cred/cred.go | 43 ++++++++++++++++++++++-
 dubboctl/pkg/hub/pusher.go    |  8 ++---
 3 files changed, 124 insertions(+), 7 deletions(-)

diff --git a/dubboctl/cmd/image.go b/dubboctl/cmd/image.go
index fe3b92d3..565cc48f 100644
--- a/dubboctl/cmd/image.go
+++ b/dubboctl/cmd/image.go
@@ -20,13 +20,19 @@ type buildConfig struct {
        Path         string
 }
 
+type pushConfig struct {
+       Apply bool
+}
+
 func ImageCmd(ctx cli.Context, cmd *cobra.Command, clientFactory 
ClientFactory) *cobra.Command {
        ibc := imageBuildCmd(cmd, clientFactory)
+       ipc := imagePushCmd(cmd, clientFactory)
        ic := &cobra.Command{
                Use:   "image",
                Short: "Used to build and push images, apply to cluster",
        }
        ic.AddCommand(ibc)
+       ic.AddCommand(ipc)
        return ic
 }
 
@@ -37,6 +43,13 @@ func newBuildConfig(cmd *cobra.Command) *buildConfig {
        return bc
 }
 
+func newPushConfig(cmd *cobra.Command) *pushConfig {
+       pc := &pushConfig{
+               Apply: viper.GetBool("apply"),
+       }
+       return pc
+}
+
 func (c buildConfig) buildclientOptions() ([]sdk.Option, error) {
        var do []sdk.Option
        do = append(do, sdk.WithBuilder(pack.NewBuilder()))
@@ -44,7 +57,7 @@ func (c buildConfig) buildclientOptions() ([]sdk.Option, 
error) {
 }
 
 func imageBuildCmd(cmd *cobra.Command, clientFactory ClientFactory) 
*cobra.Command {
-       pc := &cobra.Command{
+       bc := &cobra.Command{
                Use:     "build",
                Short:   "Build to images",
                Long:    "The build subcommand used to build images",
@@ -53,9 +66,72 @@ func imageBuildCmd(cmd *cobra.Command, clientFactory 
ClientFactory) *cobra.Comma
                        return runBuild(cmd, args, clientFactory)
                },
        }
+       return bc
+}
+
+func imagePushCmd(cmd *cobra.Command, clientFactory ClientFactory) 
*cobra.Command {
+       pc := &cobra.Command{
+               Use:     "push",
+               Short:   "Push to images",
+               Long:    "The push subcommand used to push images",
+               Example: "",
+               RunE: func(cmd *cobra.Command, args []string) error {
+                       return runPush(cmd, args, clientFactory)
+               },
+       }
        return pc
 }
 
+func runPush(cmd *cobra.Command, args []string, clientFactory ClientFactory) 
error {
+       if err := util.GetCreatePath(); err != nil {
+               return err
+       }
+       config := newBuildConfig(cmd)
+
+       fp, err := dubbo.NewDubboConfig(config.Path)
+       if err != nil {
+               return err
+       }
+
+       config, err = config.prompt(fp)
+       if err != nil {
+               return err
+       }
+
+       if !fp.Initialized() {
+               return util.NewErrNotInitialized(fp.Root)
+       }
+
+       config.configure(fp)
+
+       clientOptions, err := config.buildclientOptions()
+       if err != nil {
+               return err
+       }
+
+       client, done := clientFactory(clientOptions...)
+       defer done()
+       if fp, err = client.Push(cmd.Context(), fp); err != nil {
+               return err
+       }
+
+       pushArgs := newPushConfig(cmd)
+
+       if pushArgs.Apply {
+               err := apply(cmd, fp)
+               if err != nil {
+                       return err
+               }
+       }
+
+       err = fp.WriteFile()
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
 func runBuild(cmd *cobra.Command, args []string, clientFactory ClientFactory) 
error {
        if err := util.GetCreatePath(); err != nil {
                return err
@@ -97,7 +173,7 @@ func runBuild(cmd *cobra.Command, args []string, 
clientFactory ClientFactory) er
        return nil
 }
 
-func applyToCluster(cmd *cobra.Command, dc *dubbo.DubboConfig) error {
+func apply(cmd *cobra.Command, dc *dubbo.DubboConfig) error {
        file := filepath.Join(dc.Root)
        ec := exec.CommandContext(cmd.Context(), "kubectl", "apply", "-f", file)
        ec.Stdout = os.Stdout
diff --git a/dubboctl/pkg/hub/cred/cred.go b/dubboctl/pkg/hub/cred/cred.go
index 4ab0632b..7c72b634 100644
--- a/dubboctl/pkg/hub/cred/cred.go
+++ b/dubboctl/pkg/hub/cred/cred.go
@@ -17,6 +17,21 @@ type keyChain struct {
        pwd  string
 }
 
+type verifyCredentialsCallback func(ctx context.Context, image string, 
credentials hub.Credentials) error
+
+type credentialsCallback func(registry string) (hub.Credentials, error)
+
+type chooseCredentialHelperCallback func(available []string) (string, error)
+
+type credentialsProvider struct {
+       promptForCredentials     credentialsCallback
+       verifyCredentials        verifyCredentialsCallback
+       promptForCredentialStore chooseCredentialHelperCallback
+       credentialLoaders        []credentialsCallback
+       authFilePath             string
+       transport                http.RoundTripper
+}
+
 func (k keyChain) Resolve(resource authn.Resource) (authn.Authenticator, 
error) {
        return &authn.Basic{
                Username: k.user,
@@ -24,7 +39,7 @@ func (k keyChain) Resolve(resource authn.Resource) 
(authn.Authenticator, error)
        }, nil
 }
 
-func CheckAuth(ctx context.Context, image string, credentials hub.Credentials, 
trans http.RoundTripper) error {
+func checkAuth(ctx context.Context, image string, credentials hub.Credentials, 
trans http.RoundTripper) error {
        ref, err := name.ParseReference(image)
        if err != nil {
                return fmt.Errorf("cannot parse image reference: %w", err)
@@ -46,3 +61,29 @@ func CheckAuth(ctx context.Context, image string, 
credentials hub.Credentials, t
 
        return nil
 }
+
+type Opt func(opts *credentialsProvider)
+
+func WithPromptForCredentials(cbk credentialsCallback) Opt {
+       return func(opts *credentialsProvider) {
+               opts.promptForCredentials = cbk
+       }
+}
+
+func WithVerifyCredentials(cbk verifyCredentialsCallback) Opt {
+       return func(opts *credentialsProvider) {
+               opts.verifyCredentials = cbk
+       }
+}
+
+func WithPromptForCredentialStore(cbk chooseCredentialHelperCallback) Opt {
+       return func(opts *credentialsProvider) {
+               opts.promptForCredentialStore = cbk
+       }
+}
+
+func WithTransport(transport http.RoundTripper) Opt {
+       return func(opts *credentialsProvider) {
+               opts.transport = transport
+       }
+}
diff --git a/dubboctl/pkg/hub/pusher.go b/dubboctl/pkg/hub/pusher.go
index b6405ed5..adfafc34 100644
--- a/dubboctl/pkg/hub/pusher.go
+++ b/dubboctl/pkg/hub/pusher.go
@@ -15,6 +15,10 @@ type Credentials struct {
        Password string
 }
 
+type CredentialsProvider func(ctx context.Context, image string) (Credentials, 
error)
+
+type PusherDockerClientFactory func() (PusherDockerClient, error)
+
 type Pusher struct {
        credentialsProvider CredentialsProvider
        transport           http.RoundTripper
@@ -26,7 +30,3 @@ type PusherDockerClient interface {
        ImagePush(ctx context.Context, ref string, options 
types.ImagePushOptions) (io.ReadCloser, error)
        Close() error
 }
-
-type CredentialsProvider func(ctx context.Context, image string) (Credentials, 
error)
-
-type PusherDockerClientFactory func() (PusherDockerClient, error)

Reply via email to