Skip to content

Commit 87fce1f

Browse files
committed
Login code refactor
Signed-off-by: apostasie <[email protected]>
1 parent bec95c4 commit 87fce1f

30 files changed

+2518
-716
lines changed

cmd/nerdctl/compose_run_linux_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,9 @@ func TestComposePushAndPullWithCosignVerify(t *testing.T) {
437437
reg.Cleanup(nil)
438438
})
439439

440+
localhostIP := "127.0.0.1"
440441
tID := testutil.Identifier(t)
441-
testImageRefPrefix := fmt.Sprintf("127.0.0.1:%d/%s/", reg.Port, tID)
442+
testImageRefPrefix := fmt.Sprintf("%s:%d/%s/", localhostIP, reg.Port, tID)
442443

443444
var (
444445
imageSvc0 = testImageRefPrefix + "composebuild_svc0"

cmd/nerdctl/container_run_verify_linux_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ func TestRunVerifyCosign(t *testing.T) {
4242
})
4343

4444
tID := testutil.Identifier(t)
45-
testImageRef := fmt.Sprintf("127.0.0.1:%d/%s", reg.Port, tID)
45+
localhostIP := "127.0.0.1"
46+
testImageRef := fmt.Sprintf("%s:%d/%s",
47+
localhostIP, reg.Port, tID)
48+
4649
dockerfile := fmt.Sprintf(`FROM %s
4750
CMD ["echo", "nerdctl-build-test-string"]
4851
`, testutil.CommonImage)

cmd/nerdctl/flagutil.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func processRootCmdFlags(cmd *cobra.Command) (types.GlobalCommandOptions, error)
104104
return types.GlobalCommandOptions{}, err
105105
}
106106
insecureRegistry, err := cmd.Flags().GetBool("insecure-registry")
107+
explicitInsecureRegistry := cmd.Flags().Changed("insecure-registry")
107108
if err != nil {
108109
return types.GlobalCommandOptions{}, err
109110
}
@@ -120,18 +121,19 @@ func processRootCmdFlags(cmd *cobra.Command) (types.GlobalCommandOptions, error)
120121
return types.GlobalCommandOptions{}, err
121122
}
122123
return types.GlobalCommandOptions{
123-
Debug: debug,
124-
DebugFull: debugFull,
125-
Address: address,
126-
Namespace: namespace,
127-
Snapshotter: snapshotter,
128-
CNIPath: cniPath,
129-
CNINetConfPath: cniConfigPath,
130-
DataRoot: dataRoot,
131-
CgroupManager: cgroupManager,
132-
InsecureRegistry: insecureRegistry,
133-
HostsDir: hostsDir,
134-
Experimental: experimental,
135-
HostGatewayIP: hostGatewayIP,
124+
Debug: debug,
125+
DebugFull: debugFull,
126+
Address: address,
127+
Namespace: namespace,
128+
Snapshotter: snapshotter,
129+
CNIPath: cniPath,
130+
CNINetConfPath: cniConfigPath,
131+
DataRoot: dataRoot,
132+
CgroupManager: cgroupManager,
133+
InsecureRegistry: insecureRegistry,
134+
ExplicitInsecureRegistry: explicitInsecureRegistry,
135+
HostsDir: hostsDir,
136+
Experimental: experimental,
137+
HostGatewayIP: hostGatewayIP,
136138
}, nil
137139
}

cmd/nerdctl/login.go

Lines changed: 110 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ package main
1818

1919
import (
2020
"errors"
21+
"fmt"
2122
"io"
2223
"strings"
2324

25+
"github.com/spf13/cobra"
26+
2427
"github.com/containerd/log"
2528
"github.com/containerd/nerdctl/v2/pkg/api/types"
2629
"github.com/containerd/nerdctl/v2/pkg/cmd/login"
27-
28-
"github.com/spf13/cobra"
30+
"github.com/containerd/nerdctl/v2/pkg/nerderr"
2931
)
3032

3133
func newLoginCommand() *cobra.Command {
@@ -43,50 +45,50 @@ func newLoginCommand() *cobra.Command {
4345
return loginCommand
4446
}
4547

46-
func processLoginOptions(cmd *cobra.Command) (types.LoginCommandOptions, error) {
48+
func processLoginOptions(cmd *cobra.Command) (*types.LoginCommandOptions, error) {
4749
globalOptions, err := processRootCmdFlags(cmd)
4850
if err != nil {
49-
return types.LoginCommandOptions{}, err
51+
return nil, err
5052
}
5153

5254
username, err := cmd.Flags().GetString("username")
5355
if err != nil {
54-
return types.LoginCommandOptions{}, err
56+
return nil, err
5557
}
5658
password, err := cmd.Flags().GetString("password")
5759
if err != nil {
58-
return types.LoginCommandOptions{}, err
60+
return nil, err
5961
}
6062
passwordStdin, err := cmd.Flags().GetBool("password-stdin")
6163
if err != nil {
62-
return types.LoginCommandOptions{}, err
64+
return nil, err
6365
}
6466

6567
if strings.Contains(username, ":") {
66-
return types.LoginCommandOptions{}, errors.New("username cannot contain colons")
68+
return nil, errors.New("username cannot contain colons")
6769
}
6870

6971
if password != "" {
7072
log.L.Warn("WARNING! Using --password via the CLI is insecure. Use --password-stdin.")
7173
if passwordStdin {
72-
return types.LoginCommandOptions{}, errors.New("--password and --password-stdin are mutually exclusive")
74+
return nil, errors.New("--password and --password-stdin are mutually exclusive")
7375
}
7476
}
7577

7678
if passwordStdin {
7779
if username == "" {
78-
return types.LoginCommandOptions{}, errors.New("must provide --username with --password-stdin")
80+
return nil, errors.New("must provide --username with --password-stdin")
7981
}
8082

8183
contents, err := io.ReadAll(cmd.InOrStdin())
8284
if err != nil {
83-
return types.LoginCommandOptions{}, err
85+
return nil, err
8486
}
8587

86-
password = strings.TrimSuffix(string(contents), "\n")
87-
password = strings.TrimSuffix(password, "\r")
88+
password = strings.TrimSpace(string(contents))
8889
}
89-
return types.LoginCommandOptions{
90+
91+
return &types.LoginCommandOptions{
9092
GOptions: globalOptions,
9193
Username: username,
9294
Password: password,
@@ -103,5 +105,98 @@ func loginAction(cmd *cobra.Command, args []string) error {
103105
options.ServerAddress = args[0]
104106
}
105107

106-
return login.Login(cmd.Context(), options, cmd.OutOrStdout())
108+
stdo := cmd.OutOrStdout()
109+
110+
// Warnings may be returned with or without an error
111+
warnings, err := login.Login(cmd.Context(), options, stdo)
112+
113+
// Note that we are ignoring Fprintln errors here, as we do not want to return BEFORE the main error is handled
114+
for _, warning := range warnings {
115+
_, _ = fmt.Fprintln(stdo, warning)
116+
}
117+
118+
switch err {
119+
case nil:
120+
_, fErr := fmt.Fprintln(cmd.OutOrStdout(), "Login Succeeded")
121+
return fErr
122+
case nerderr.ErrSystemIsBroken:
123+
log.L.Error("Your system is misconfigure or in a broken state. Probably your hosts.toml files have error, or your ~/.docker/config.json file is hosed")
124+
case nerderr.ErrInvalidArgument:
125+
log.L.Error("Invalid arguments provided")
126+
case nerderr.ErrServerIsMisbehaving:
127+
log.L.Error("The registry server you are trying to log into is possibly misconfigured, or otherwise misbehaving")
128+
case login.ErrCredentialsCannotBeRead:
129+
log.L.Error("Nerdctl cannot login without a username and password")
130+
case login.ErrConnectionFailed:
131+
log.L.Error("Failed establishing a connection. There was a DNS, TCP, or TLS issue preventing nerdctl from talking to the registry")
132+
case login.ErrAuthenticationFailure:
133+
log.L.Error("Authentication failed. Provided credentials were refused by the registry")
134+
}
135+
/*
136+
var dnsErr *net.DNSError
137+
var sysCallErr *os.SyscallError
138+
var opErr *net.OpError
139+
var urlErr *url.Error
140+
var tlsErr *tls.CertificateVerificationError
141+
// Providing understandable feedback to user for specific errors
142+
if errors.Is(err, login.ErrLoginCredentialsCannotBeRead) {
143+
log.L.Errorf("Unable to read credentials from docker store (~/.docker/config.json or credentials helper). Please manually inspect.")
144+
} else if errors.Is(err, login.ErrLoginCredentialsCannotBeWritten) {
145+
log.L.Errorf("Though the login was succesfull, credentials could not be saved to the docker store (~/.docker/config.json or credentials helper). Please manually inspect.")
146+
} else if errors.Is(err, login.ErrLoginCredentialsRefused) {
147+
log.L.Errorf("Unable to login with the provided credentials")
148+
} else if errors.As(err, &dnsErr) {
149+
if dnsErr.IsNotFound && !dnsErr.IsTemporary {
150+
// donotresolveeverever.foo
151+
log.L.Errorf("domain name %q is unknown to your DNS server %q (hint: is the domain name spelled correctly?)", dnsErr.Name, dnsErr.Server)
152+
} else if dnsErr.Timeout() {
153+
// resolve using an unreachable DNS server
154+
log.L.Errorf("unable to get a timely response from your DNS server %q (hint: is your DNS configuration ok?)", dnsErr.Server)
155+
} else {
156+
debErr, _ := json.Marshal(dnsErr)
157+
log.L.Errorf("non-specific DNS resolution error (timeout: %t):\n%s", dnsErr.Timeout(), string(debErr))
158+
}
159+
} else if errors.Is(err, http.ErrSchemeMismatch) {
160+
log.L.Errorf("the server does not speak https")
161+
} else if errors.As(err, &sysCallErr) {
162+
if sysCallErr.Syscall == "connect" {
163+
// Connect error - no way to reach that server, or server dropped us immediately
164+
log.L.Error("failed connecting to server")
165+
} else {
166+
debErr, _ := json.Marshal(sysCallErr)
167+
log.L.Errorf("non-specific syscall error (timeout: %t):\n%s", sysCallErr.Timeout(), string(debErr))
168+
}
169+
} else if errors.As(err, &opErr) {
170+
// Typically a tcp timeout
171+
if opErr.Timeout() {
172+
log.L.Errorf("timeout trying to connect to server)")
173+
} else {
174+
debErr, _ := json.Marshal(opErr)
175+
log.L.Errorf("non-specific tcp error:\n%s", string(debErr))
176+
}
177+
} else if errors.As(err, &tlsErr) {
178+
log.L.Debugf("server certificate verification error")
179+
} else if errors.As(err, &urlErr) {
180+
// Typically a TLS handshake timeout
181+
if urlErr.Timeout() {
182+
log.L.Debugf("server timeout while awaiting response")
183+
} else {
184+
debErr, _ := json.Marshal(urlErr)
185+
log.L.Errorf("non-specific server error:\n%s", string(debErr))
186+
}
187+
} else if errors.Is(err, login.ErrTooManyRedirects) {
188+
log.L.Errorf("too many redirects sent back by server - it is likely misconfigured")
189+
} else if errors.Is(err, login.ErrRedirectAuthorizerError) {
190+
log.L.Errorf("server is redirecting to a different location and credentials are not going to be sent there - " +
191+
"server is either misconfigured, or there is a security problem")
192+
} else if errors.Is(err, login.ErrAuthorizerError) {
193+
log.L.Errorf("credentials cannot be sent to that server - " +
194+
"server is possibly misconfigured, or there is a security problem")
195+
//} else {
196+
// log.L.Error("non-specific error")
197+
}
198+
199+
*/
200+
201+
return err
107202
}

0 commit comments

Comments
 (0)