github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/logout.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/containerd/nerdctl/pkg/imgutil/dockerconfigresolver"
    23  	dockercliconfig "github.com/docker/cli/cli/config"
    24  	"github.com/spf13/cobra"
    25  )
    26  
    27  func newLogoutCommand() *cobra.Command {
    28  	var logoutCommand = &cobra.Command{
    29  		Use:               "logout [flags] [SERVER]",
    30  		Args:              cobra.MaximumNArgs(1),
    31  		Short:             "Log out from a container registry",
    32  		RunE:              logoutAction,
    33  		ValidArgsFunction: logoutShellComplete,
    34  		SilenceUsage:      true,
    35  		SilenceErrors:     true,
    36  	}
    37  	return logoutCommand
    38  }
    39  
    40  // code inspired from XXX
    41  func logoutAction(cmd *cobra.Command, args []string) error {
    42  	serverAddress := dockerconfigresolver.IndexServer
    43  	isDefaultRegistry := true
    44  	if len(args) >= 1 {
    45  		serverAddress = args[0]
    46  		isDefaultRegistry = false
    47  	}
    48  
    49  	var (
    50  		regsToLogout    = []string{serverAddress}
    51  		hostnameAddress = serverAddress
    52  	)
    53  
    54  	if !isDefaultRegistry {
    55  		hostnameAddress = dockerconfigresolver.ConvertToHostname(serverAddress)
    56  		// the tries below are kept for backward compatibility where a user could have
    57  		// saved the registry in one of the following format.
    58  		regsToLogout = append(regsToLogout, hostnameAddress, "http://"+hostnameAddress, "https://"+hostnameAddress)
    59  	}
    60  
    61  	fmt.Fprintf(cmd.OutOrStdout(), "Removing login credentials for %s\n", hostnameAddress)
    62  
    63  	dockerConfigFile, err := dockercliconfig.Load("")
    64  	if err != nil {
    65  		return err
    66  	}
    67  	errs := make(map[string]error)
    68  	for _, r := range regsToLogout {
    69  		if err := dockerConfigFile.GetCredentialsStore(r).Erase(r); err != nil {
    70  			errs[r] = err
    71  		}
    72  	}
    73  
    74  	// if at least one removal succeeded, report success. Otherwise report errors
    75  	if len(errs) == len(regsToLogout) {
    76  		fmt.Fprintln(cmd.ErrOrStderr(), "WARNING: could not erase credentials:")
    77  		for k, v := range errs {
    78  			fmt.Fprintf(cmd.OutOrStdout(), "%s: %s\n", k, v)
    79  		}
    80  	}
    81  
    82  	return nil
    83  }
    84  
    85  func logoutShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    86  	dockerConfigFile, err := dockercliconfig.Load("")
    87  	if err != nil {
    88  		return nil, cobra.ShellCompDirectiveError
    89  	}
    90  	candidates := []string{}
    91  	for key := range dockerConfigFile.AuthConfigs {
    92  		candidates = append(candidates, key)
    93  	}
    94  	return candidates, cobra.ShellCompDirectiveNoFileComp
    95  }