exec_post_hook.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package worker
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/anmitsu/go-shlex"
  6. "github.com/codeskyblue/go-sh"
  7. )
  8. // hook to execute command after syncing
  9. // typically setting timestamp, etc.
  10. const (
  11. execOnSuccess uint8 = iota
  12. execOnFailure
  13. )
  14. type execPostHook struct {
  15. emptyHook
  16. provider mirrorProvider
  17. // exec on success or on failure
  18. execOn uint8
  19. // command
  20. command []string
  21. }
  22. func newExecPostHook(provider mirrorProvider, execOn uint8, command string) (*execPostHook, error) {
  23. cmd, err := shlex.Split(command, true)
  24. if err != nil {
  25. // logger.Errorf("Failed to create exec-post-hook for command: %s", command)
  26. return nil, err
  27. }
  28. if execOn != execOnSuccess && execOn != execOnFailure {
  29. return nil, fmt.Errorf("Invalid option for exec-on: %d", execOn)
  30. }
  31. return &execPostHook{
  32. provider: provider,
  33. execOn: execOn,
  34. command: cmd,
  35. }, nil
  36. }
  37. func (h *execPostHook) postSuccess() error {
  38. if h.execOn == execOnSuccess {
  39. return h.Do()
  40. }
  41. return nil
  42. }
  43. func (h *execPostHook) postFail() error {
  44. if h.execOn == execOnFailure {
  45. return h.Do()
  46. }
  47. return nil
  48. }
  49. func (h *execPostHook) Do() error {
  50. p := h.provider
  51. exitStatus := ""
  52. if h.execOn == execOnSuccess {
  53. exitStatus = "success"
  54. } else {
  55. exitStatus = "failure"
  56. }
  57. env := map[string]string{
  58. "TUNASYNC_MIRROR_NAME": p.Name(),
  59. "TUNASYNC_WORKING_DIR": p.WorkingDir(),
  60. "TUNASYNC_UPSTREAM_URL": p.Upstream(),
  61. "TUNASYNC_LOG_DIR": p.LogDir(),
  62. "TUNASYNC_LOG_FILE": p.LogFile(),
  63. "TUNASYNC_JOB_EXIT_STATUS": exitStatus,
  64. }
  65. session := sh.NewSession()
  66. for k, v := range env {
  67. session.SetEnv(k, v)
  68. }
  69. var cmd string
  70. args := []interface{}{}
  71. if len(h.command) == 1 {
  72. cmd = h.command[0]
  73. } else if len(h.command) > 1 {
  74. cmd = h.command[0]
  75. for _, arg := range h.command[1:] {
  76. args = append(args, arg)
  77. }
  78. } else {
  79. return errors.New("Invalid Command")
  80. }
  81. return session.Command(cmd, args...).Run()
  82. }