Add 'kpod login' and 'kpod logout' commands
Signed-off-by: umohnani8 <umohnani@redhat.com>
This commit is contained in:
		
							parent
							
								
									b21a3e36ac
								
							
						
					
					
						commit
						d664a58a6d
					
				
					 9 changed files with 334 additions and 4 deletions
				
			
		
							
								
								
									
										110
									
								
								cmd/kpod/login.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								cmd/kpod/login.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/containers/image/docker" | ||||
| 	"github.com/containers/image/pkg/docker/config" | ||||
| 	"github.com/kubernetes-incubator/cri-o/libpod/common" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/urfave/cli" | ||||
| 	"golang.org/x/crypto/ssh/terminal" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	loginFlags = []cli.Flag{ | ||||
| 		cli.StringFlag{ | ||||
| 			Name:  "password, p", | ||||
| 			Usage: "Password for registry", | ||||
| 		}, | ||||
| 		cli.StringFlag{ | ||||
| 			Name:  "username, u", | ||||
| 			Usage: "Username for registry", | ||||
| 		}, | ||||
| 		cli.StringFlag{ | ||||
| 			Name:  "authfile", | ||||
| 			Usage: "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json", | ||||
| 		}, | ||||
| 	} | ||||
| 	loginDescription = "Login to a container registry on a specified server." | ||||
| 	loginCommand     = cli.Command{ | ||||
| 		Name:        "login", | ||||
| 		Usage:       "login to a container registry", | ||||
| 		Description: loginDescription, | ||||
| 		Flags:       loginFlags, | ||||
| 		Action:      loginCmd, | ||||
| 		ArgsUsage:   "REGISTRY", | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // loginCmd uses the authentication package to store a user's authenticated credentials | ||||
| // in an auth.json file for future use | ||||
| func loginCmd(c *cli.Context) error { | ||||
| 	args := c.Args() | ||||
| 	if len(args) > 1 { | ||||
| 		return errors.Errorf("too many arguments, login takes only 1 argument") | ||||
| 	} | ||||
| 	if len(args) == 0 { | ||||
| 		return errors.Errorf("registry must be given") | ||||
| 	} | ||||
| 	var server string | ||||
| 	if len(args) == 1 { | ||||
| 		server = args[0] | ||||
| 	} | ||||
| 
 | ||||
| 	sc := common.GetSystemContext("", c.String("authfile")) | ||||
| 
 | ||||
| 	// username of user logged in to server (if one exists) | ||||
| 	userFromAuthFile := config.GetUserLoggedIn(sc, server) | ||||
| 	username, password, err := getUserAndPass(c.String("username"), c.String("password"), userFromAuthFile) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrapf(err, "error getting username and password") | ||||
| 	} | ||||
| 
 | ||||
| 	if err = docker.CheckAuth(context.TODO(), sc, username, password, server); err == nil { | ||||
| 		if err := config.SetAuthentication(sc, server, username, password); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	switch err { | ||||
| 	case nil: | ||||
| 		fmt.Println("Login Succeeded!") | ||||
| 		return nil | ||||
| 	case docker.ErrUnauthorizedForCredentials: | ||||
| 		return errors.Errorf("error logging into %q: invalid username/password\n", server) | ||||
| 	default: | ||||
| 		return errors.Wrapf(err, "error authenticating creds for %q", server) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // getUserAndPass gets the username and password from STDIN if not given | ||||
| // using the -u and -p flags | ||||
| func getUserAndPass(username, password, userFromAuthFile string) (string, string, error) { | ||||
| 	var err error | ||||
| 	reader := bufio.NewReader(os.Stdin) | ||||
| 	if username == "" { | ||||
| 		if userFromAuthFile != "" { | ||||
| 			fmt.Printf("Username (%s): ", userFromAuthFile) | ||||
| 		} else { | ||||
| 			fmt.Print("Username: ") | ||||
| 		} | ||||
| 		username, err = reader.ReadString('\n') | ||||
| 		if err != nil { | ||||
| 			return "", "", errors.Wrapf(err, "error reading username") | ||||
| 		} | ||||
| 	} | ||||
| 	if password == "" { | ||||
| 		fmt.Print("Password: ") | ||||
| 		pass, err := terminal.ReadPassword(0) | ||||
| 		if err != nil { | ||||
| 			return "", "", errors.Wrapf(err, "error reading password") | ||||
| 		} | ||||
| 		password = string(pass) | ||||
| 		fmt.Println() | ||||
| 	} | ||||
| 	return strings.TrimSpace(username), password, err | ||||
| } | ||||
							
								
								
									
										66
									
								
								cmd/kpod/logout.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								cmd/kpod/logout.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/containers/image/pkg/docker/config" | ||||
| 	"github.com/kubernetes-incubator/cri-o/libpod/common" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	logoutFlags = []cli.Flag{ | ||||
| 		cli.StringFlag{ | ||||
| 			Name:  "authfile", | ||||
| 			Usage: "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json", | ||||
| 		}, | ||||
| 		cli.BoolFlag{ | ||||
| 			Name:  "all, a", | ||||
| 			Usage: "Remove the cached credentials for all registries in the auth file", | ||||
| 		}, | ||||
| 	} | ||||
| 	logoutDescription = "Remove the cached username and password for the registry." | ||||
| 	logoutCommand     = cli.Command{ | ||||
| 		Name:        "logout", | ||||
| 		Usage:       "logout of a container registry", | ||||
| 		Description: logoutDescription, | ||||
| 		Flags:       logoutFlags, | ||||
| 		Action:      logoutCmd, | ||||
| 		ArgsUsage:   "REGISTRY", | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // logoutCmd uses the authentication package to remove the authenticated of a registry | ||||
| // stored in the auth.json file | ||||
| func logoutCmd(c *cli.Context) error { | ||||
| 	args := c.Args() | ||||
| 	if len(args) > 1 { | ||||
| 		return errors.Errorf("too many arguments, logout takes only 1 argument") | ||||
| 	} | ||||
| 	var server string | ||||
| 	if len(args) == 1 { | ||||
| 		server = args[0] | ||||
| 	} | ||||
| 
 | ||||
| 	sc := common.GetSystemContext("", c.String("authfile")) | ||||
| 
 | ||||
| 	if c.Bool("all") { | ||||
| 		if err := config.RemoveAllAuthentication(sc); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		fmt.Println("Remove login credentials for all registries") | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	err := config.RemoveAuthentication(sc, server) | ||||
| 	switch err { | ||||
| 	case nil: | ||||
| 		fmt.Printf("Remove login credentials for %s\n", server) | ||||
| 		return nil | ||||
| 	case config.ErrNotLoggedIn: | ||||
| 		return errors.Errorf("Not logged into %s\n", server) | ||||
| 	default: | ||||
| 		return errors.Wrapf(err, "error logging out of %q", server) | ||||
| 	} | ||||
| } | ||||
|  | @ -39,6 +39,8 @@ func main() { | |||
| 		inspectCommand, | ||||
| 		killCommand, | ||||
| 		loadCommand, | ||||
| 		loginCommand, | ||||
| 		logoutCommand, | ||||
| 		logsCommand, | ||||
| 		mountCommand, | ||||
| 		pauseCommand, | ||||
|  |  | |||
|  | @ -431,6 +431,34 @@ _kpod_load() { | |||
|     _complete_ "$options_with_args" "$boolean_options" | ||||
| } | ||||
| 
 | ||||
| _kpod_login() { | ||||
|      local options_with_args=" | ||||
|      --username | ||||
|      -u | ||||
|      --password | ||||
|      -p | ||||
|      --authfile | ||||
|      " | ||||
|      local boolean_options=" | ||||
|      --help | ||||
|      -h | ||||
|      " | ||||
|      _complete_ "$options_with_args" "$boolean_options" | ||||
| } | ||||
| 
 | ||||
| _kpod_logout() { | ||||
|      local options_with_args=" | ||||
|      --authfile | ||||
|      " | ||||
|      local boolean_options=" | ||||
|      --all | ||||
|      -a | ||||
|      --help | ||||
|      -h | ||||
|      " | ||||
|      _complete_ "$options_with_args" "$boolean_options" | ||||
| } | ||||
| 
 | ||||
| _kpod_kpod() { | ||||
|      local options_with_args=" | ||||
|            --config -c | ||||
|  | @ -453,6 +481,8 @@ _kpod_kpod() { | |||
|     inspect | ||||
|     kill | ||||
|     load | ||||
|     login | ||||
|     logout | ||||
|     logs | ||||
|     mount | ||||
|     pause | ||||
|  |  | |||
							
								
								
									
										65
									
								
								docs/kpod-login.1.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								docs/kpod-login.1.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| % kpod(1) kpod-login - Simple tool to login to a registry server | ||||
| % Urvashi Mohnani | ||||
| # kpod-login "1" "August 2017" "kpod" | ||||
| 
 | ||||
| ## NAME | ||||
| kpod-login - Login to a container registry | ||||
| 
 | ||||
| ## SYNOPSIS | ||||
| **kpod login** | ||||
| [**--help**|**-h**] | ||||
| [**--authfile**] | ||||
| [**--user**|**-u**] | ||||
| [**--password**|**-p**] | ||||
| **REGISTRY** | ||||
| 
 | ||||
| ## DESCRIPTION | ||||
| **kpod login** logs into a specified registry server with the correct username | ||||
| and password. **kpod login** reads in the username and password from STDIN. | ||||
| The username and password can also be set using the **username** and **password** flags. | ||||
| The path of the authentication file can be specified by the user by setting the **authfile** | ||||
| flag. The default path used is **${XDG\_RUNTIME_DIR}/containers/auth.json**. | ||||
| 
 | ||||
| **kpod [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| **kpod login [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| **kpod login [OPTIONS] REGISTRY [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| ## OPTIONS | ||||
| 
 | ||||
| **--password, -p** | ||||
| Password for registry | ||||
| 
 | ||||
| **--username, -u** | ||||
| Username for registry | ||||
| 
 | ||||
| **--authfile** | ||||
| Path of the authentication file. Default is ${XDG_\RUNTIME\_DIR}/containers/auth.json | ||||
| 
 | ||||
| ## EXAMPLES | ||||
| 
 | ||||
| ``` | ||||
| # kpod login docker.io | ||||
| Username: umohnani | ||||
| Password: | ||||
| Login Succeeded! | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| # kpod login -u testuser -p testpassword localhost:5000 | ||||
| Login Succeeded! | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| # kpod login --authfile authdir/myauths.json docker.io | ||||
| Username: umohnani | ||||
| Password: | ||||
| Login Succeeded! | ||||
| ``` | ||||
| 
 | ||||
| ## SEE ALSO | ||||
| kpod(1), kpod-logout(1), crio(8), crio.conf(5) | ||||
| 
 | ||||
| ## HISTORY | ||||
| August 2017, Originally compiled by Urvashi Mohnani <umohnani@redhat.com> | ||||
							
								
								
									
										56
									
								
								docs/kpod-logout.1.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/kpod-logout.1.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| % kpod(1) kpod-logout - Simple tool to logout of a registry server | ||||
| % Urvashi Mohnani | ||||
| # kpod-logout "1" "August 2017" "kpod" | ||||
| 
 | ||||
| ## NAME | ||||
| kpod-logout - Logout of a container registry | ||||
| 
 | ||||
| ## SYNOPSIS | ||||
| **kpod logout** | ||||
| [**--help**|**-h**] | ||||
| [**--authfile**] | ||||
| [**--all**|**-a**] | ||||
| **REGISTRY** | ||||
| 
 | ||||
| ## DESCRIPTION | ||||
| **kpod logout** logs out of a specified registry server by deleting the cached credentials | ||||
| stored in the **auth.json** file. The path of the authentication file can be overrriden by the user by setting the **authfile** flag. | ||||
| The default path used is **${XDG\_RUNTIME_DIR}/containers/auth.json**. | ||||
| All the cached credentials can be removed by setting the **all** flag. | ||||
| 
 | ||||
| **kpod [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| **kpod logout [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| **kpod logout [OPTIONS] REGISTRY [GLOBAL OPTIONS]** | ||||
| 
 | ||||
| ## OPTIONS | ||||
| 
 | ||||
| **--authfile** | ||||
| Path of the authentication file. Default is ${XDG_\RUNTIME\_DIR}/containers/auth.json | ||||
| 
 | ||||
| **--all, -a** | ||||
| Remove the cached credentials for all registries in the auth file | ||||
| 
 | ||||
| ## EXAMPLES | ||||
| 
 | ||||
| ``` | ||||
| # kpod logout docker.io | ||||
| Remove login credentials for https://registry-1.docker.io/v2/ | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| # kpod logout --authfile authdir/myauths.json docker.io | ||||
| Remove login credentials for https://registry-1.docker.io/v2/ | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| # kpod logout --all | ||||
| Remove login credentials for all registries | ||||
| ``` | ||||
| 
 | ||||
| ## SEE ALSO | ||||
| kpod(1), kpod-login(1), crio(8), crio.conf(5) | ||||
| 
 | ||||
| ## HISTORY | ||||
| August 2017, Originally compiled by Urvashi Mohnani <umohnani@redhat.com> | ||||
|  | @ -36,11 +36,12 @@ func GetCopyOptions(reportWriter io.Writer, signaturePolicyPath string, srcDocke | |||
| } | ||||
| 
 | ||||
| // GetSystemContext Constructs a new containers/image/types.SystemContext{} struct from the given signaturePolicy path | ||||
| func GetSystemContext(signaturePolicyPath string) *types.SystemContext { | ||||
| func GetSystemContext(signaturePolicyPath, authFilePath string) *types.SystemContext { | ||||
| 	sc := &types.SystemContext{} | ||||
| 	if signaturePolicyPath != "" { | ||||
| 		sc.SignaturePolicyPath = signaturePolicyPath | ||||
| 	} | ||||
| 	sc.AuthFilePath = authFilePath | ||||
| 	return sc | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -413,7 +413,7 @@ func (r *Runtime) GetImageCopyData(image string) (*CopyData, error) { | |||
| 		return nil, errors.Wrapf(err, "error locating image %q for importing settings", image) | ||||
| 	} | ||||
| 
 | ||||
| 	systemContext := common.GetSystemContext("") | ||||
| 	systemContext := common.GetSystemContext("", "") | ||||
| 	data, err := r.ImportCopyDataFromImage(systemContext, img.ID, "", "") | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrapf(err, "error reading image") | ||||
|  | @ -435,7 +435,7 @@ func (r *Runtime) importCopyData(store storage.Store, container, signaturePolicy | |||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	systemContext := common.GetSystemContext(signaturePolicyPath) | ||||
| 	systemContext := common.GetSystemContext(signaturePolicyPath, "") | ||||
| 
 | ||||
| 	data, err := r.ImportCopyDataFromImage(systemContext, c.ImageID, container, c.ID) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ func (r *Runtime) PullImage(imgName string, allTags bool, signaturePolicyPath st | |||
| 		signaturePolicyPath = r.config.SignaturePolicyPath | ||||
| 	} | ||||
| 
 | ||||
| 	sc := common.GetSystemContext(signaturePolicyPath) | ||||
| 	sc := common.GetSystemContext(signaturePolicyPath, "") | ||||
| 
 | ||||
| 	srcRef, err := alltransports.ParseImageName(imgName) | ||||
| 	if err != nil { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue