// Exec func Exec(params string) error { // connect to the server; this will wait until a single read is returned from // the server (blocking) conn, data, err := connect(fmt.Sprintf("POST /exec?pid=%d&%v HTTP/1.1\r\n\r\n", os.Getpid(), params)) if err != nil { return err } defer conn.Close() // begin watching for changes to the project go func() { if err := notifyutil.Watch(config.CWDir, NotifyServer); err != nil { fmt.Printf(err.Error()) } }() // get current term info stdIn, stdOut, _ := term.StdStreams() // terminal.Connect(stdIn, stdOut) // print the first read data from above os.Stderr.WriteString(string(data)) // return pipeToConnection(conn, stdIn, stdOut) }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) flag.Merge(flag.CommandLine, clientFlags.FlagSet, commonFlags.FlagSet) flag.Usage = func() { fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n"+daemonUsage+" docker [ -h | --help | -v | --version ]\n\n") fmt.Fprint(os.Stdout, "A self-sufficient runtime for containers.\n\nOptions:\n") flag.CommandLine.SetOutput(os.Stdout) flag.PrintDefaults() help := "\nCommands:\n" for _, cmd := range dockerCommands { help += fmt.Sprintf(" %-10.10s%s\n", cmd.name, cmd.description) } help += "\nRun 'docker COMMAND --help' for more information on a command." fmt.Fprintf(os.Stdout, "%s\n", help) } flag.Parse() if *flVersion { showVersion() return } clientCli := client.NewDockerCli(stdin, stdout, stderr, clientFlags) // TODO: remove once `-d` is retired handleGlobalDaemonFlag() if *flHelp { // if global flag --help is present, regardless of what other options and commands there are, // just print the usage. flag.Usage() return } c := cli.New(clientCli, daemonCli) if err := c.Run(flag.Args()...); err != nil { if sterr, ok := err.(cli.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(os.Stderr, sterr.Status) os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(os.Stderr, err) os.Exit(1) } }
// Develop func Develop(params string, mist mistClient.Client) error { // connect to the server; this will wait until a single read is returned from // the server (blocking) conn, data, err := connect(fmt.Sprintf("POST /develop?pid=%d&%v HTTP/1.1\r\n\r\n", os.Getpid(), params)) if err != nil { return err } defer conn.Close() // disconnect mist mist.Close() // begin watching for changes to the project go func() { if err := notifyutil.Watch(config.CWDir, NotifyServer); err != nil { fmt.Printf(err.Error()) } }() // os.Stderr.WriteString(fmt.Sprintf(`+> Opening a nanobox console: ** ******** *************** ********************* ***************** :: ********* :: :: *** :: ++ ::: ::: ++ ++ ::: ++ ++ ++ + _ _ ____ _ _ ____ ___ ____ _ _ |\ | |__| |\ | | | |__) | | \/ | \| | | | \| |__| |__) |__| _/\_ -------------------------------------------------------------------------------- + You are in a virtual machine (vm) + Your local source code has been mounted into the vm, and changes in either the vm or local will be mirrored. + If you run a server, access it at >> %s -------------------------------------------------------------------------------- `, config.Nanofile.Domain)) // get current term info stdIn, stdOut, _ := term.StdStreams() // terminal.Connect(stdIn, stdOut) // print the first read data from above os.Stderr.WriteString(string(data)) // return pipeToConnection(conn, stdIn, stdOut) }
// Exec func Exec(where, params string) error { // stdIn, stdOut, _ := term.StdStreams() // return execInternal(where, params, stdIn, stdOut) }
func main() { _, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) err := dnetCommand(stdout, stderr) if err != nil { os.Exit(1) } }
// NewCobraAdaptor returns a new handler func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { stdin, stdout, stderr := term.StdStreams() dockerCli := client.NewDockerCli(stdin, stdout, stderr, clientFlags) var rootCmd = &cobra.Command{ Use: "docker", SilenceUsage: true, SilenceErrors: true, } rootCmd.SetUsageTemplate(usageTemplate) rootCmd.SetHelpTemplate(helpTemplate) rootCmd.SetFlagErrorFunc(cli.FlagErrorFunc) rootCmd.SetOutput(stdout) rootCmd.AddCommand( container.NewAttachCommand(dockerCli), container.NewCreateCommand(dockerCli), container.NewDiffCommand(dockerCli), container.NewExportCommand(dockerCli), container.NewKillCommand(dockerCli), container.NewLogsCommand(dockerCli), container.NewPauseCommand(dockerCli), container.NewPortCommand(dockerCli), container.NewRenameCommand(dockerCli), container.NewRestartCommand(dockerCli), container.NewRmCommand(dockerCli), container.NewRunCommand(dockerCli), container.NewStartCommand(dockerCli), container.NewStatsCommand(dockerCli), container.NewStopCommand(dockerCli), container.NewTopCommand(dockerCli), container.NewUnpauseCommand(dockerCli), container.NewWaitCommand(dockerCli), image.NewBuildCommand(dockerCli), image.NewHistoryCommand(dockerCli), image.NewImagesCommand(dockerCli), image.NewLoadCommand(dockerCli), image.NewRemoveCommand(dockerCli), image.NewSaveCommand(dockerCli), image.NewSearchCommand(dockerCli), image.NewImportCommand(dockerCli), image.NewTagCommand(dockerCli), network.NewNetworkCommand(dockerCli), system.NewEventsCommand(dockerCli), system.NewVersionCommand(dockerCli), volume.NewVolumeCommand(dockerCli), ) rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") return CobraAdaptor{ rootCmd: rootCmd, dockerCli: dockerCli, } }
func newDockerClient() *client.DockerCli { // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) if len(flHosts) > 1 { log.Fatal("Please specify only one -H") } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli tlsConfig tls.Config ) tlsConfig.InsecureSkipVerify = true // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls if flag.IsSet("-tlsverify") { *flTls = true } // If we should verify the server, we need to load a trusted ca if *flTlsVerify { certPool := x509.NewCertPool() file, err := ioutil.ReadFile(*flCa) if err != nil { log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err) } certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false } // If tls is enabled, try to load and send client certificates if *flTls || *flTlsVerify { _, errCert := os.Stat(*flCert) _, errKey := os.Stat(*flKey) if errCert == nil && errKey == nil { *flTls = true cert, err := tls.LoadX509KeyPair(*flCert, *flKey) if err != nil { log.Fatalf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Avoid fallback to SSL protocols < TLS1.0 tlsConfig.MinVersion = tls.VersionTLS10 } cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig) return cli }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. _, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) flag.Merge(flag.CommandLine, daemonCli.commonFlags.FlagSet) flag.Usage = func() { fmt.Fprint(stdout, "Usage: dockerd [ --help | -v | --version ]\n\n") fmt.Fprint(stdout, "A self-sufficient runtime for containers.\n\nOptions:\n") flag.CommandLine.SetOutput(stdout) flag.PrintDefaults() } flag.CommandLine.ShortUsage = func() { fmt.Fprint(stderr, "\nUsage:\tdockerd [OPTIONS]\n") } if err := flag.CommandLine.ParseFlags(os.Args[1:], false); err != nil { os.Exit(1) } if *flVersion { showVersion() return } if *flHelp { // if global flag --help is present, regardless of what other options and commands there are, // just print the usage. flag.Usage() return } // On Windows, this may be launching as a service or with an option to // register the service. stop, err := initService() if err != nil { logrus.Fatal(err) } if !stop { err = daemonCli.start() notifyShutdown(err) if err != nil { logrus.Fatal(err) } } }
// Console func Console(params string) error { // connect to the server; this will wait until a single read is returned from // the server (blocking) conn, data, err := connect(fmt.Sprintf("POST /exec?pid=%d&%v HTTP/1.1\r\n\r\n", os.Getpid(), params)) if err != nil { return err } defer conn.Close() // begin watching for changes to the project go func() { if err := notifyutil.Watch(config.CWDir, NotifyServer); err != nil { fmt.Printf(err.Error()) } }() // os.Stderr.WriteString(`+> Opening a nanobox console: ** ******** *************** ********************* ***************** :: ********* :: :: *** :: ++ ::: ::: ++ ++ ::: ++ ++ ++ + _ _ ____ _ _ ____ ___ ____ _ _ |\ | |__| |\ | | | |__) | | \/ | \| | | | \| |__| |__) |__| _/\_ `) // get current term info stdIn, stdOut, _ := term.StdStreams() // connect a raw terminal; if no error is returned defer resetting the terminal state, err := terminal.Connect(stdIn, stdOut) if err == nil { defer terminal.Disconnect(stdIn, state) } // print the first read data from above os.Stderr.Write(data) // return pipeToConnection(conn, stdIn, stdOut) }
// Console opens a secure console to a code or database service. For code // services, a command is required. This command is executed as root in the // context of the application root directory. For database services, no command // is needed - instead, the appropriate command for the database type is run. // For example, for a postgres database, psql is run. func Console(serviceLabel string, command string, settings *models.Settings) { helpers.SignIn(settings) service := helpers.RetrieveServiceByLabel(serviceLabel, settings) if service == nil { fmt.Printf("Could not find a service with the label \"%s\"\n", serviceLabel) os.Exit(1) } fmt.Printf("Opening console to %s (%s)\n", serviceLabel, service.ID) task := helpers.RequestConsole(command, service.ID, settings) fmt.Print("Waiting for the console to be ready. This might take a minute.") ch := make(chan string, 1) go helpers.PollConsoleJob(task.ID, service.ID, ch, settings) jobID := <-ch defer helpers.DestroyConsole(jobID, service.ID, settings) creds := helpers.RetrieveConsoleTokens(jobID, service.ID, settings) creds.URL = strings.Replace(creds.URL, "http", "ws", 1) fmt.Println("Connecting...") // BEGIN websocket impl config, _ := websocket.NewConfig(creds.URL, "ws://localhost:9443/") config.TlsConfig = &tls.Config{ MinVersion: tls.VersionTLS12, } config.Header["X-Console-Token"] = []string{creds.Token} ws, err := websocket.DialConfig(config) if err != nil { panic(err) } defer ws.Close() fmt.Println("Connection opened") stdin, stdout, _ := term.StdStreams() fdIn, isTermIn := term.GetFdInfo(stdin) if !isTermIn { panic(errors.New("StdIn is not a terminal")) } oldState, err := term.SetRawTerminal(fdIn) if err != nil { panic(err) } done := make(chan bool) msgCh := make(chan []byte, 2) go webSocketDaemon(ws, &stdout, done, msgCh) signal.Notify(make(chan os.Signal, 1), os.Interrupt) defer term.RestoreTerminal(fdIn, oldState) go termDaemon(&stdin, ws) <-done }
func main() { if reexec.Init() { return } _, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) err := dnetApp(stdout, stderr) if err != nil { os.Exit(1) } }
func runDockerCommand(c *cli.Context, cmd string) { _, stdout, stderr := term.StdStreams() oldcli := client.NewNetworkCli(stdout, stderr, epConn.httpCall) var args []string args = append(args, cmd) if c.Bool("h") { args = append(args, "--help") } else { args = append(args, c.Args()...) } if err := oldcli.Cmd("dnet", args...); err != nil { fmt.Println(err) os.Exit(1) } }
func promptForCredentials(settings *models.Settings) { var username string fmt.Print("Username: "******"Password: "******"windows" { stdIn, _, _ := term.StdStreams() fd, _ = term.GetFdInfo(stdIn) } bytes, _ := terminal.ReadPassword(int(fd)) fmt.Println("") settings.Password = string(bytes) }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. _, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) cmd := newDaemonCommand() cmd.SetOutput(stdout) if err := cmd.Execute(); err != nil { fmt.Fprintf(stderr, "%s\n", err) os.Exit(1) } }
func NewKubectlServer() *Server { // need to use term.StdStreams to get the right IO refs on Windows stdin, stdout, stderr := term.StdStreams() cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), stdin, stdout, stderr) localFlags := cmd.LocalFlags() localFlags.SetInterspersed(false) return &Server{ name: "kubectl", SimpleUsage: "Kubernetes command line client", Long: "Kubernetes command line client", Run: func(s *Server, args []string) error { cmd.SetArgs(args) return cmd.Execute() }, flags: localFlags, } }
func generateManPages(path string) error { header := &doc.GenManHeader{ Title: "DOCKER", Section: "1", Source: "Docker Community", } stdin, stdout, stderr := term.StdStreams() dockerCli := command.NewDockerCli(stdin, stdout, stderr) cmd := &cobra.Command{Use: "docker"} commands.AddCommands(cmd, dockerCli) cmd.DisableAutoGenTag = true return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{ Header: header, Path: path, CommandSeparator: "-", }) }
func generateManPages(opts *options) error { header := &doc.GenManHeader{ Title: "DOCKER", Section: "1", Source: "Docker Community", } stdin, stdout, stderr := term.StdStreams() dockerCli := command.NewDockerCli(stdin, stdout, stderr) cmd := &cobra.Command{Use: "docker"} commands.AddCommands(cmd, dockerCli) source := filepath.Join(opts.source, descriptionSourcePath) if err := loadLongDescription(cmd, source); err != nil { return err } cmd.DisableAutoGenTag = true return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{ Header: header, Path: opts.target, CommandSeparator: "-", }) }
func main() { // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) dockerCli := client.NewDockerCli(stdin, stdout, stderr) cmd := newDockerCommand(dockerCli) if err := cmd.Execute(); err != nil { if sterr, ok := err.(cli.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(stderr, sterr.Status) } // StatusError should only be used for errors, and all errors should // have a non-zero exit status, so never exit with 0 if sterr.StatusCode == 0 { os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(stderr, err) os.Exit(1) } }
func main() { app := cli.NewApp() app.Name = "pony" app.Version = VERSION app.Author = "@jfrazelle" app.Email = "*****@*****.**" app.Usage = "Local File-Based Password, API Key, Secret, Recovery Code Store Backed By GPG" app.Before = preload app.EnableBashCompletion = true app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "debug, d", Usage: "run in debug mode", }, cli.StringFlag{ Name: "file, f", Value: fmt.Sprintf("%s/%s", homedir.GetShortcutString(), defaultFilestore), Usage: "file to use for saving encrypted secrets", }, cli.StringFlag{ Name: "gpgpath", Value: fmt.Sprintf("%s/%s", homedir.GetShortcutString(), defaultGPGPath), Usage: "filepath used for gpg keys", }, cli.StringFlag{ Name: "keyid", Usage: "optionally set specific gpg keyid/fingerprint to use for encryption & decryption", EnvVar: fmt.Sprintf("%s_KEYID", strings.ToUpper(app.Name)), }, } app.Commands = []cli.Command{ { Name: "add", Aliases: []string{"save"}, Usage: "Add a new secret", Action: func(c *cli.Context) { args := c.Args() if len(args) < 2 { logrus.Errorf("You need to pass a key and value to the command. ex: %s %s com.example.apikey EUSJCLLAWE", app.Name, c.Command.Name) cli.ShowSubcommandHelp(c) } // add the key value pair to secrets key, value := args[0], args[1] s.setKeyValue(key, value, false) fmt.Printf("Added %s %s to secrets", key, value) }, }, { Name: "delete", Aliases: []string{"rm"}, Usage: "Delete a secret", Action: func(c *cli.Context) { args := c.Args() if len(args) < 1 { cli.ShowSubcommandHelp(c) } key := args[0] if _, ok := s.Secrets[key]; !ok { logrus.Fatalf("Secret for (%s) does not exist", key) } delete(s.Secrets, key) if err := writeSecretsFile(filestore, s); err != nil { logrus.Fatal(err) } fmt.Printf("Secret %q deleted successfully", key) }, }, { Name: "get", Usage: "Get the value of a secret", Flags: []cli.Flag{ cli.BoolFlag{ Name: "copy, c", Usage: "copy the secret to your clipboard", }, }, Action: func(c *cli.Context) { args := c.Args() if len(args) < 1 { cli.ShowSubcommandHelp(c) } // add the key value pair to secrets key := args[0] if _, ok := s.Secrets[key]; !ok { logrus.Fatalf("Secret for (%s) does not exist", key) } fmt.Println(s.Secrets[key]) // copy to clipboard if c.Bool("copy") { if err := clipboard.WriteAll(s.Secrets[key]); err != nil { logrus.Fatalf("Clipboard copy failed: %v", err) } fmt.Println("Copied to clipboard!") } }, }, { Name: "list", Aliases: []string{"ls"}, Usage: "List all secrets", Flags: []cli.Flag{ cli.StringFlag{ Name: "filter, f", Usage: "filter secrets keys by a regular expression", }, }, Action: func(c *cli.Context) { _, stdout, _ := term.StdStreams() w := tabwriter.NewWriter(stdout, 20, 1, 3, ' ', 0) // print header fmt.Fprintln(w, "KEY\tVALUE") // print the keys alphabetically printSorted := func(m map[string]string) { mk := make([]string, len(m)) i := 0 for k := range m { mk[i] = k i++ } sort.Strings(mk) for _, key := range mk { filter := c.String("filter") if filter != "" { if ok, _ := regexp.MatchString(c.String("filter"), key); !ok { continue } } fmt.Fprintf(w, "%s\t%s\n", key, m[key]) } } printSorted(s.Secrets) w.Flush() }, }, { Name: "update", Usage: "Update a secret", Action: func(c *cli.Context) { args := c.Args() if len(args) < 2 { logrus.Errorf("You need to pass a key and value to the command. ex: %s %s com.example.apikey EUSJCLLAWE", app.Name, c.Command.Name) cli.ShowSubcommandHelp(c) } // add the key value pair to secrets key, value := args[0], args[1] s.setKeyValue(key, value, true) fmt.Printf("Updated secret %s to %s", key, value) }, }, } app.Run(os.Args) }
func main() { // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() logrus.SetOutput(stderr) flag.Merge(flag.CommandLine, clientFlags.FlagSet, commonFlags.FlagSet) cobraAdaptor := cobraadaptor.NewCobraAdaptor(clientFlags) flag.Usage = func() { fmt.Fprint(stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n docker [ --help | -v | --version ]\n\n") fmt.Fprint(stdout, "A self-sufficient runtime for containers.\n\nOptions:\n") flag.CommandLine.SetOutput(stdout) flag.PrintDefaults() help := "\nCommands:\n" dockerCommands := append(cli.DockerCommandUsage, cobraAdaptor.Usage()...) for _, cmd := range sortCommands(dockerCommands) { help += fmt.Sprintf(" %-10.10s%s\n", cmd.Name, cmd.Description) } help += "\nRun 'docker COMMAND --help' for more information on a command." fmt.Fprintf(stdout, "%s\n", help) } flag.Parse() if *flVersion { showVersion() return } if *flHelp { // if global flag --help is present, regardless of what other options and commands there are, // just print the usage. flag.Usage() return } clientCli := client.NewDockerCli(stdin, stdout, stderr, clientFlags) c := cli.New(clientCli, NewDaemonProxy(), cobraAdaptor) if err := c.Run(flag.Args()...); err != nil { if sterr, ok := err.(cli.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(stderr, sterr.Status) } // StatusError should only be used for errors, and all errors should // have a non-zero exit status, so never exit with 0 if sterr.StatusCode == 0 { os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(stderr, err) os.Exit(1) } }
// Decrypt a io.Reader with the given secretKeyring. // You can optionally pass a defaultGPGKey to use for the // decryption, otherwise it will use the first entity. func Decrypt(f io.Reader, secretKeyring, defaultGPGKey string) (io.Reader, error) { // Open the private key file keyringFileBuffer, err := os.Open(secretKeyring) if err != nil { return nil, err } defer keyringFileBuffer.Close() entityList, err := openpgp.ReadKeyRing(keyringFileBuffer) if err != nil { return nil, err } var entity *openpgp.Entity if defaultGPGKey != "" { // loop through their keys until we find the one they want var foundKey bool for _, e := range entityList { // we can match on the fingerprint or the keyid because // why not? I bet no one knows the difference if e.PrimaryKey.KeyIdString() == defaultGPGKey || e.PrimaryKey.KeyIdShortString() == defaultGPGKey || fmt.Sprintf("%X", e.PrimaryKey.Fingerprint) == defaultGPGKey { foundKey = true entity = e break } } if !foundKey { // we didn't find the key they specified return nil, fmt.Errorf("Could not find private GPG Key with id: %s", defaultGPGKey) } } else { // they didn't set a default key // so let's hope it is the first one :/ // TODO(jessfraz): maybe prompt here if they have // more than one private key entity = entityList[0] } var identityString string for _, identity := range entity.Identities { identityString = fmt.Sprintf(" %s [%s]", identity.Name, entity.PrimaryKey.KeyIdString()) break } // Get the passphrase and read the private key. // Have not touched the encrypted string yet stdin, _, stderr := term.StdStreams() stdinFd, _ := term.GetFdInfo(stdin) oldState, err := term.SaveState(stdinFd) if err != nil { return nil, err } // prompt for passphrase fmt.Fprintf(stderr, "GPG Passphrase for key%s: ", identityString) term.DisableEcho(stdinFd, oldState) // read what they inputed passphrase := readInput(stdin, stderr) fmt.Fprint(stderr, "\n\n") // restore the terminal term.RestoreTerminal(stdinFd, oldState) logrus.Debugln("Decrypting private key using passphrase") entity.PrivateKey.Decrypt(passphrase) for _, subkey := range entity.Subkeys { subkey.PrivateKey.Decrypt(passphrase) } logrus.Debugln("Finished decrypting private key using passphrase") // base64 decode dec := base64.NewDecoder(base64.StdEncoding, f) // Decrypt it with the contents of the private key md, err := openpgp.ReadMessage(dec, entityList, nil, nil) if err != nil { return nil, fmt.Errorf("GPG ReadMessage failed: %v", err) } // return the body contents return md.UnverifiedBody, nil }
/* WARNING: this logic is duplicated, with minor changes, in cmd/hyperkube/kubectl.go Any salient changes here will need to be manually reflected in that file. */ func Run() error { // need to use term.StdStreams to get the right IO refs on Windows stdin, stdout, stderr := term.StdStreams() cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), stdin, stdout, stderr) return cmd.Execute() }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() initLogging(stderr) flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flLogLevel != "" { lvl, err := logrus.ParseLevel(*flLogLevel) if err != nil { logrus.Fatalf("Unable to parse logging level: %s", *flLogLevel) } setLogLevel(lvl) } else { setLogLevel(logrus.InfoLevel) } // -D, --debug, -l/--log-level=debug processing // When/if -D is removed this block can be deleted if *flDebug { os.Setenv("DEBUG", "1") setLogLevel(logrus.DebugLevel) } if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET) } defaultHost, err := api.ValidateHost(defaultHost) if err != nil { logrus.Fatal(err) } flHosts = append(flHosts, defaultHost) } setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) if *flDaemon { if *flHelp { flag.Usage() return } mainDaemon() return } if len(flHosts) > 1 { logrus.Fatal("Please specify only one -H") } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli tlsConfig tls.Config ) tlsConfig.InsecureSkipVerify = true // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls if flag.IsSet("-tlsverify") { *flTls = true } // If we should verify the server, we need to load a trusted ca if *flTlsVerify { certPool := x509.NewCertPool() file, err := ioutil.ReadFile(*flCa) if err != nil { logrus.Fatalf("Couldn't read ca cert %s: %s", *flCa, err) } certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false } // If tls is enabled, try to load and send client certificates if *flTls || *flTlsVerify { _, errCert := os.Stat(*flCert) _, errKey := os.Stat(*flKey) if errCert == nil && errKey == nil { *flTls = true cert, err := tls.LoadX509KeyPair(*flCert, *flKey) if err != nil { logrus.Fatalf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Avoid fallback to SSL protocols < TLS1.0 tlsConfig.MinVersion = tls.VersionTLS10 } if *flTls || *flTlsVerify { cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig) } else { cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], nil) } if err := cli.Cmd(flag.Args()...); err != nil { if sterr, ok := err.(client.StatusError); ok { if sterr.Status != "" { logrus.Println(sterr.Status) } os.Exit(sterr.StatusCode) } logrus.Fatal(err) } }
// NewCobraAdaptor returns a new handler func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { stdin, stdout, stderr := term.StdStreams() dockerCli := client.NewDockerCli(stdin, stdout, stderr, clientFlags) var rootCmd = &cobra.Command{ Use: "docker [OPTIONS]", Short: "A self-sufficient runtime for containers", SilenceUsage: true, SilenceErrors: true, } rootCmd.SetUsageTemplate(usageTemplate) rootCmd.SetHelpTemplate(helpTemplate) rootCmd.SetFlagErrorFunc(cli.FlagErrorFunc) rootCmd.SetOutput(stdout) rootCmd.AddCommand( node.NewNodeCommand(dockerCli), service.NewServiceCommand(dockerCli), stack.NewStackCommand(dockerCli), stack.NewTopLevelDeployCommand(dockerCli), swarm.NewSwarmCommand(dockerCli), container.NewAttachCommand(dockerCli), container.NewCommitCommand(dockerCli), container.NewCopyCommand(dockerCli), container.NewCreateCommand(dockerCli), container.NewDiffCommand(dockerCli), container.NewExecCommand(dockerCli), container.NewExportCommand(dockerCli), container.NewKillCommand(dockerCli), container.NewLogsCommand(dockerCli), container.NewPauseCommand(dockerCli), container.NewPortCommand(dockerCli), container.NewPsCommand(dockerCli), container.NewRenameCommand(dockerCli), container.NewRestartCommand(dockerCli), container.NewRmCommand(dockerCli), container.NewRunCommand(dockerCli), container.NewStartCommand(dockerCli), container.NewStatsCommand(dockerCli), container.NewStopCommand(dockerCli), container.NewTopCommand(dockerCli), container.NewUnpauseCommand(dockerCli), container.NewUpdateCommand(dockerCli), container.NewWaitCommand(dockerCli), image.NewBuildCommand(dockerCli), image.NewHistoryCommand(dockerCli), image.NewImagesCommand(dockerCli), image.NewLoadCommand(dockerCli), image.NewRemoveCommand(dockerCli), image.NewSaveCommand(dockerCli), image.NewPullCommand(dockerCli), image.NewPushCommand(dockerCli), image.NewSearchCommand(dockerCli), image.NewImportCommand(dockerCli), image.NewTagCommand(dockerCli), network.NewNetworkCommand(dockerCli), system.NewEventsCommand(dockerCli), registry.NewLoginCommand(dockerCli), registry.NewLogoutCommand(dockerCli), system.NewVersionCommand(dockerCli), volume.NewVolumeCommand(dockerCli), system.NewInfoCommand(dockerCli), ) plugin.NewPluginCommand(rootCmd, dockerCli) rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") return CobraAdaptor{ rootCmd: rootCmd, dockerCli: dockerCli, } }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() initLogging(stderr) flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flConfigDir != "" { cliconfig.SetConfigDir(*flConfigDir) } if *flLogLevel != "" { lvl, err := logrus.ParseLevel(*flLogLevel) if err != nil { fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel) os.Exit(1) } setLogLevel(lvl) } else { setLogLevel(logrus.InfoLevel) } if *flDebug { os.Setenv("DEBUG", "1") setLogLevel(logrus.DebugLevel) } if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { if runtime.GOOS != "windows" { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket) } else { // If we do not have a host, default to TCP socket on Windows defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort) } } defaultHost, err := opts.ValidateHost(defaultHost) if err != nil { if *flDaemon { logrus.Fatal(err) } else { fmt.Fprint(os.Stderr, err) } os.Exit(1) } flHosts = append(flHosts, defaultHost) } setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls // *flTlsVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need to check that here as well if flag.IsSet("-tlsverify") || *flTlsVerify { *flTls = true } if *flDaemon { if *flHelp { flag.Usage() return } mainDaemon() return } // From here on, we assume we're a client, not a server. if len(flHosts) > 1 { fmt.Fprintf(os.Stderr, "Please specify only one -H") os.Exit(0) } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var tlsConfig *tls.Config if *flTls { tlsOptions.InsecureSkipVerify = !*flTlsVerify if !flag.IsSet("-tlscert") { if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) { tlsOptions.CertFile = "" } } if !flag.IsSet("-tlskey") { if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) { tlsOptions.KeyFile = "" } } var err error tlsConfig, err = tlsconfig.Client(tlsOptions) if err != nil { fmt.Fprintln(stderr, err) os.Exit(1) } } cli := client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], tlsConfig) if err := cli.Cmd(flag.Args()...); err != nil { if sterr, ok := err.(client.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(cli.Err(), sterr.Status) os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(cli.Err(), err) os.Exit(1) } }
func (t *terminalHelper) StdStreams() (io.ReadCloser, io.Writer, io.Writer) { return term.StdStreams() }
// Open opens a secure console to a code or database service. For code // services, a command is required. This command is executed as root in the // context of the application root directory. For database services, no command // is needed - instead, the appropriate command for the database type is run. // For example, for a postgres database, psql is run. func (c *SConsole) Open(command string, service *models.Service) error { stdin, stdout, _ := term.StdStreams() fdIn, isTermIn := term.GetFdInfo(stdin) if !isTermIn { return errors.New("StdIn is not a terminal") } var size *term.Winsize var err error if runtime.GOOS != "windows" { size, err = term.GetWinsize(fdIn) } else { fdOut, _ := term.GetFdInfo(stdout) size, err = term.GetWinsize(fdOut) } if err != nil { return err } if size.Width != 80 { logrus.Warnln("Your terminal width is not 80 characters. Please resize your terminal to be exactly 80 characters wide to avoid line wrapping issues.") } else { logrus.Warnln("Keep your terminal width at 80 characters. Resizing your terminal will introduce line wrapping issues.") } logrus.Printf("Opening console to %s (%s)", service.Name, service.ID) job, err := c.Request(command, service) if err != nil { return err } // all because logrus treats print, println, and printf the same logrus.StandardLogger().Out.Write([]byte(fmt.Sprintf("Waiting for the console (job ID = %s) to be ready. This might take a minute.", job.ID))) validStatuses := []string{"running", "finished", "failed"} status, err := c.Jobs.PollForStatus(validStatuses, job.ID, service.ID) if err != nil { return err } found := false for _, validStatus := range validStatuses { if status == validStatus { found = true break } } if !found { return fmt.Errorf("\nCould not open a console connection. Entered state '%s'", status) } job.Status = status defer c.Destroy(job.ID, service) creds, err := c.RetrieveTokens(job.ID, service) if err != nil { return err } creds.URL = strings.Replace(creds.URL, "http", "ws", 1) logrus.Println("\nConnecting...") // BEGIN websocket impl config, _ := websocket.NewConfig(creds.URL, "ws://localhost:9443/") config.TlsConfig = &tls.Config{ MinVersion: tls.VersionTLS12, } config.Header["X-Console-Token"] = []string{creds.Token} ws, err := websocket.DialConfig(config) if err != nil { return err } defer ws.Close() logrus.Println("Connection opened") oldState, err := term.SetRawTerminal(fdIn) if err != nil { return err } defer term.RestoreTerminal(fdIn, oldState) signal.Notify(make(chan os.Signal, 1), os.Interrupt) done := make(chan struct{}, 2) go readWS(ws, stdout, done) go readStdin(stdin, ws, done) <-done return nil }