LocalCommandRunner.coffee 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. spawn = require("child_process").spawn
  2. logger = require "logger-sharelatex"
  3. logger.info "using standard command runner"
  4. module.exports = CommandRunner =
  5. run: (project_id, command, directory, image, timeout, environment, callback = (error) ->) ->
  6. command = (arg.toString().replace('$COMPILE_DIR', directory) for arg in command)
  7. logger.log project_id: project_id, command: command, directory: directory, "running command"
  8. logger.warn "timeouts and sandboxing are not enabled with CommandRunner"
  9. # merge environment settings
  10. env = {}
  11. env[key] = value for key, value of process.env
  12. env[key] = value for key, value of environment
  13. # run command as detached process so it has its own process group (which can be killed if needed)
  14. proc = spawn command[0], command.slice(1), cwd: directory, env: env
  15. stdout = ""
  16. proc.stdout.on "data", (data)->
  17. stdout += data
  18. proc.on "error", (err)->
  19. logger.err err:err, project_id:project_id, command: command, directory: directory, "error running command"
  20. callback(err)
  21. proc.on "close", (code, signal) ->
  22. logger.info code:code, signal:signal, project_id:project_id, "command exited"
  23. if signal is 'SIGTERM' # signal from kill method below
  24. err = new Error("terminated")
  25. err.terminated = true
  26. return callback(err)
  27. else if code is 1 # exit status from chktex
  28. err = new Error("exited")
  29. err.code = code
  30. return callback(err)
  31. else
  32. callback(null, {"stdout": stdout})
  33. return proc.pid # return process id to allow job to be killed if necessary
  34. kill: (pid, callback = (error) ->) ->
  35. try
  36. process.kill -pid # kill all processes in group
  37. catch err
  38. return callback(err)
  39. callback()