cmd_provider.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package worker
  2. import (
  3. "errors"
  4. "os"
  5. "github.com/anmitsu/go-shlex"
  6. )
  7. type cmdConfig struct {
  8. name string
  9. upstreamURL, command string
  10. workingDir, logDir, logFile string
  11. interval int
  12. env map[string]string
  13. }
  14. type cmdProvider struct {
  15. baseProvider
  16. cmdConfig
  17. command []string
  18. cmd *cmdJob
  19. logFile *os.File
  20. }
  21. func newCmdProvider(c cmdConfig) (*cmdProvider, error) {
  22. // TODO: check config options
  23. provider := &cmdProvider{
  24. baseProvider: baseProvider{
  25. name: c.name,
  26. ctx: NewContext(),
  27. interval: c.interval,
  28. },
  29. cmdConfig: c,
  30. }
  31. provider.ctx.Set(_WorkingDirKey, c.workingDir)
  32. provider.ctx.Set(_LogDirKey, c.logDir)
  33. provider.ctx.Set(_LogFileKey, c.logFile)
  34. cmd, err := shlex.Split(c.command, true)
  35. if err != nil {
  36. return nil, err
  37. }
  38. provider.command = cmd
  39. return provider, nil
  40. }
  41. func (p *cmdProvider) Start() error {
  42. env := map[string]string{
  43. "TUNASYNC_MIRROR_NAME": p.Name(),
  44. "TUNASYNC_WORKING_DIR": p.WorkingDir(),
  45. "TUNASYNC_UPSTREAM_URL": p.upstreamURL,
  46. "TUNASYNC_LOG_FILE": p.LogFile(),
  47. }
  48. for k, v := range p.env {
  49. env[k] = v
  50. }
  51. p.cmd = newCmdJob(p.command, p.WorkingDir(), env)
  52. logFile, err := os.OpenFile(p.LogFile(), os.O_WRONLY|os.O_CREATE, 0644)
  53. if err != nil {
  54. return err
  55. }
  56. p.logFile = logFile
  57. p.cmd.SetLogFile(logFile)
  58. return p.cmd.Start()
  59. }
  60. func (p *cmdProvider) Wait() error {
  61. if p.logFile != nil {
  62. defer p.logFile.Close()
  63. }
  64. return p.cmd.Wait()
  65. }
  66. func (p *cmdProvider) Terminate() error {
  67. if p.cmd == nil {
  68. return errors.New("provider command job not initialized")
  69. }
  70. if p.logFile != nil {
  71. defer p.logFile.Close()
  72. }
  73. err := p.cmd.Terminate()
  74. return err
  75. }
  76. // TODO: implement this
  77. func (p *cmdProvider) Hooks() {
  78. }