Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dubboctl] update docker image hub logic #586

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 20 additions & 84 deletions dubboctl/cmd/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,84 +7,57 @@ import (
"github.com/apache/dubbo-kubernetes/dubboctl/pkg/sdk"
"github.com/apache/dubbo-kubernetes/dubboctl/pkg/sdk/dubbo"
"github.com/apache/dubbo-kubernetes/dubboctl/pkg/util"
"github.com/ory/viper"
"github.com/spf13/cobra"
"os"
"os/exec"
"path/filepath"
)

type buildConfig struct {
type hubConfig struct {
Image string
BuilderImage string
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)
ihc := imageHubCmd(cmd, clientFactory)
ic := &cobra.Command{
Use: "image",
Short: "Used to build and push images, apply to cluster",
}
ic.AddCommand(ibc)
ic.AddCommand(ipc)
ic.AddCommand(ihc)
return ic
}

func newBuildConfig(cmd *cobra.Command) *buildConfig {
bc := &buildConfig{}
return bc
func newHubConfig(cmd *cobra.Command) *hubConfig {
hc := &hubConfig{}
return hc
}

func newPushConfig(cmd *cobra.Command) *pushConfig {
pc := &pushConfig{
Apply: viper.GetBool("apply"),
}
return pc
}

func (c buildConfig) buildclientOptions() ([]sdk.Option, error) {
func (c hubConfig) imageClientOptions() ([]sdk.Option, error) {
var do []sdk.Option
do = append(do, sdk.WithBuilder(pack.NewBuilder()))
return do, nil
}

func imageBuildCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
func imageHubCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
bc := &cobra.Command{
Use: "build",
Short: "Build to images",
Long: "The build subcommand used to build images",
Use: "hub",
Short: "Build and Push to images",
Long: "The hub subcommand used to build and push images",
Example: "",
RunE: func(cmd *cobra.Command, args []string) error {
return runBuild(cmd, args, clientFactory)
return runHub(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 {
func runHub(cmd *cobra.Command, args []string, clientFactory ClientFactory) error {
if err := util.GetCreatePath(); err != nil {
return err
}
config := newBuildConfig(cmd)
config := newHubConfig(cmd)

fp, err := dubbo.NewDubboConfig(config.Path)
if err != nil {
Expand All @@ -102,54 +75,17 @@ func runPush(cmd *cobra.Command, args []string, clientFactory ClientFactory) err

config.configure(fp)

clientOptions, err := config.buildclientOptions()
clientOptions, err := config.imageClientOptions()
if err != nil {
return err
}

client, done := clientFactory(clientOptions...)
defer done()

if fp, err = client.Push(cmd.Context(), fp); 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
}
config := newBuildConfig(cmd)

fp, err := dubbo.NewDubboConfig(config.Path)
if err != nil {
return err
if fp.Built() {
return nil
}

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.Build(cmd.Context(), fp); err != nil {
return err
}
Expand Down Expand Up @@ -177,7 +113,7 @@ func runApply(cmd *cobra.Command, dc *dubbo.DubboConfig) error {
return nil
}

func (c *buildConfig) configure(dc *dubbo.DubboConfig) {
func (c *hubConfig) configure(dc *dubbo.DubboConfig) {
if c.Path == "" {
root, err := os.Getwd()
if err != nil {
Expand All @@ -195,7 +131,7 @@ func (c *buildConfig) configure(dc *dubbo.DubboConfig) {
}
}

func (c *buildConfig) prompt(dc *dubbo.DubboConfig) (*buildConfig, error) {
func (c *hubConfig) prompt(dc *dubbo.DubboConfig) (*hubConfig, error) {
var err error
if !util.InteractiveTerminal() {
return c, nil
Expand Down
25 changes: 9 additions & 16 deletions dubboctl/pkg/hub/credentials/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
)

var (
ErrUnauthorized = errors.New("bad credentials")
ErrCredentialsNotFound = errors.New("credentials not found")
errUnauthorized = errors.New("bad credentials")
errCredentialsNotFound = errors.New("credentials not found")
errNoCredentialHelperConfigured = errors.New("no credential helper configure")
)

Expand Down Expand Up @@ -126,7 +126,7 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
result, err = load(registry)

if err != nil {
if errors.Is(err, ErrCredentialsNotFound) {
if errors.Is(err, errCredentialsNotFound) {
continue
}
return pusher.Credentials{}, err
Expand All @@ -136,15 +136,15 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
if err == nil {
return result, nil
} else {
if !errors.Is(err, ErrUnauthorized) {
if !errors.Is(err, errUnauthorized) {
return pusher.Credentials{}, err
}
}

}

if c.promptForCredentials == nil {
return pusher.Credentials{}, ErrCredentialsNotFound
return pusher.Credentials{}, errCredentialsNotFound
}

for {
Expand All @@ -158,7 +158,6 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
err = setCredentialsByCredentialHelper(c.authFilePath, registry, result.Username, result.Password)
if err != nil {

// This shouldn't be fatal error.
if strings.Contains(err.Error(), "not implemented") {
fmt.Fprintf(os.Stderr, "the cred-helper does not support write operation (consider changing the cred-helper it in auth.json)\n")
return pusher.Credentials{}, nil
Expand Down Expand Up @@ -192,7 +191,7 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
}
return result, nil
} else {
if errors.Is(err, ErrUnauthorized) {
if errors.Is(err, errUnauthorized) {
continue
}
return pusher.Credentials{}, err
Expand Down Expand Up @@ -222,7 +221,7 @@ func checkAuth(ctx context.Context, image string, credentials pusher.Credentials
if err != nil {
var transportErr *transport.Error
if errors.As(err, &transportErr) && transportErr.StatusCode == 401 {
return errors.New("bad credentials")
return errUnauthorized
}
return err
}
Expand Down Expand Up @@ -283,7 +282,7 @@ func getCredentialsByCredentialHelper(confFilePath, registry string) (pusher.Cre
return result, fmt.Errorf("failed to get helper from config: %w", err)
}
if helper == "" {
return result, ErrCredentialsNotFound
return result, errCredentialsNotFound
}

helperName := fmt.Sprintf("docker-credential-%s", helper)
Expand All @@ -306,7 +305,7 @@ func getCredentialsByCredentialHelper(confFilePath, registry string) (pusher.Cre
}
}

return result, fmt.Errorf("failed to get credentials from helper specified in ~/.docker/config.json: %w", ErrCredentialsNotFound)
return result, fmt.Errorf("failed to get credentials from helper specified in ~/.docker/config.json: %w", errCredentialsNotFound)
}

func setCredentialsByCredentialHelper(confFilePath, registry, username, secret string) error {
Expand Down Expand Up @@ -408,12 +407,6 @@ func WithPromptForCredentials(cbk CredentialsCallback) Opt {
}
}

func WithVerifyCredentials(cbk VerifyCredentialsCallback) Opt {
return func(opts *credentialsProvider) {
opts.verifyCredentials = cbk
}
}

func WithPromptForCredentialStore(cbk ChooseCredentialHelperCallback) Opt {
return func(opts *credentialsProvider) {
opts.promptForCredentialStore = cbk
Expand Down
12 changes: 6 additions & 6 deletions dubboctl/pkg/hub/pusher/pusher.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/docker/docker/pkg/jsonmessage"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/google/go-containerregistry/pkg/v1/remote"
"golang.org/x/term"
Expand Down Expand Up @@ -42,7 +42,7 @@ type Pusher struct {
dockerClientFactory PusherDockerClientFactory
}

type AuthConfig struct {
type authConfig struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Auth string `json:"auth,omitempty"`
Expand Down Expand Up @@ -89,7 +89,7 @@ func (p *Pusher) Push(ctx context.Context, dc *dubbo.DubboConfig) (digest string
fmt.Fprintf(os.Stderr, "Pushing function image to the registry %q using the %q user credentials\n", registry, credentials.Username)

if _, err = net.DefaultResolver.LookupHost(ctx, registry); err == nil {
return p.daemon(ctx, dc, credentials, output)
return p.daemonPush(ctx, dc, credentials, output)
}

return p.push(ctx, dc, credentials, output)
Expand All @@ -104,19 +104,19 @@ func getRegistry(img string) (string, error) {
return registry, nil
}

func (p *Pusher) daemon(ctx context.Context, dc *dubbo.DubboConfig, credentials Credentials, output io.Writer) (digest string, err error) {
func (p *Pusher) daemonPush(ctx context.Context, dc *dubbo.DubboConfig, credentials Credentials, output io.Writer) (digest string, err error) {
cli, err := p.dockerClientFactory()
if err != nil {
return "", fmt.Errorf("failed to create docker api client: %w", err)
}
defer cli.Close()

authConfig := AuthConfig{
ac := authConfig{
Username: credentials.Username,
Password: credentials.Password,
}

b, err := json.Marshal(&authConfig)
b, err := json.Marshal(&ac)
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion dubboctl/pkg/sdk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type Builder interface {
}

type Pusher interface {
Push(ctx context.Context, dcfg *dubbo.DubboConfig) (string, error)
Push(ctx context.Context, dc *dubbo.DubboConfig) (string, error)
}

type DeployOption func(f *DeployParams)
Expand Down
Loading