watch_command.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package command
  2. import (
  3. "errors"
  4. "os"
  5. "os/signal"
  6. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli"
  7. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd"
  8. )
  9. // NewWatchCommand returns the CLI command for "watch".
  10. func NewWatchCommand() cli.Command {
  11. return cli.Command{
  12. Name: "watch",
  13. Usage: "watch a key for changes",
  14. Flags: []cli.Flag{
  15. cli.BoolFlag{Name: "forever", Usage: "forever watch a key until CTRL+C"},
  16. cli.IntFlag{Name: "after-index", Value: 0, Usage: "watch after the given index"},
  17. cli.BoolFlag{Name: "recursive", Usage: "returns all values for key and child keys"},
  18. },
  19. Action: func(c *cli.Context) {
  20. handleKey(c, watchCommandFunc)
  21. },
  22. }
  23. }
  24. // watchCommandFunc executes the "watch" command.
  25. func watchCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) {
  26. if len(c.Args()) == 0 {
  27. return nil, errors.New("Key required")
  28. }
  29. key := c.Args()[0]
  30. recursive := c.Bool("recursive")
  31. forever := c.Bool("forever")
  32. index := 0
  33. if c.Int("after-index") != 0 {
  34. index = c.Int("after-index") + 1
  35. }
  36. if forever {
  37. sigch := make(chan os.Signal, 1)
  38. signal.Notify(sigch, os.Interrupt)
  39. stop := make(chan bool)
  40. go func() {
  41. <-sigch
  42. os.Exit(0)
  43. }()
  44. receiver := make(chan *etcd.Response)
  45. errCh := make(chan error, 1)
  46. go func() {
  47. _, err := client.Watch(key, uint64(index), recursive, receiver, stop)
  48. errCh <- err
  49. }()
  50. for {
  51. select {
  52. case resp := <-receiver:
  53. printAll(resp, c.GlobalString("output"))
  54. case err := <-errCh:
  55. handleError(-1, err)
  56. }
  57. }
  58. } else {
  59. var resp *etcd.Response
  60. var err error
  61. resp, err = client.Watch(key, uint64(index), recursive, nil, nil)
  62. if err != nil {
  63. handleError(ErrorFromEtcd, err)
  64. }
  65. if err != nil {
  66. return nil, err
  67. }
  68. printAll(resp, c.GlobalString("output"))
  69. }
  70. return nil, nil
  71. }