docker.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package main
  2. import (
  3. "flag"
  4. "github.com/dotcloud/docker"
  5. "github.com/dotcloud/docker/rcli"
  6. "github.com/dotcloud/docker/term"
  7. "io"
  8. "log"
  9. "os"
  10. )
  11. func main() {
  12. if docker.SelfPath() == "/sbin/init" {
  13. // Running in init mode
  14. docker.SysInit()
  15. return
  16. }
  17. // FIXME: Switch d and D ? (to be more sshd like)
  18. flDaemon := flag.Bool("d", false, "Daemon mode")
  19. flDebug := flag.Bool("D", false, "Debug mode")
  20. flag.Parse()
  21. rcli.DEBUG_FLAG = *flDebug
  22. if *flDaemon {
  23. if flag.NArg() != 0 {
  24. flag.Usage()
  25. return
  26. }
  27. if err := daemon(); err != nil {
  28. log.Fatal(err)
  29. }
  30. } else {
  31. if err := runCommand(flag.Args()); err != nil {
  32. log.Fatal(err)
  33. }
  34. }
  35. }
  36. func daemon() error {
  37. service, err := docker.NewServer()
  38. if err != nil {
  39. return err
  40. }
  41. return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
  42. }
  43. func runCommand(args []string) error {
  44. var oldState *term.State
  45. var err error
  46. if term.IsTerminal(0) && os.Getenv("NORAW") == "" {
  47. oldState, err = term.MakeRaw(0)
  48. if err != nil {
  49. return err
  50. }
  51. defer term.Restore(0, oldState)
  52. }
  53. // FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
  54. // CloseWrite(), which we need to cleanly signal that stdin is closed without
  55. // closing the connection.
  56. // See http://code.google.com/p/go/issues/detail?id=3345
  57. if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
  58. receiveStdout := docker.Go(func() error {
  59. _, err := io.Copy(os.Stdout, conn)
  60. return err
  61. })
  62. sendStdin := docker.Go(func() error {
  63. _, err := io.Copy(conn, os.Stdin)
  64. if err := conn.CloseWrite(); err != nil {
  65. log.Printf("Couldn't send EOF: " + err.Error())
  66. }
  67. return err
  68. })
  69. if err := <-receiveStdout; err != nil {
  70. return err
  71. }
  72. if !term.IsTerminal(0) {
  73. if err := <-sendStdin; err != nil {
  74. return err
  75. }
  76. }
  77. } else {
  78. service, err := docker.NewServer()
  79. if err != nil {
  80. return err
  81. }
  82. if err := rcli.LocalCall(service, os.Stdin, os.Stdout, args...); err != nil {
  83. return err
  84. }
  85. }
  86. if oldState != nil {
  87. term.Restore(0, oldState)
  88. }
  89. return nil
  90. }