mirror of
https://github.com/tuna/tunasync.git
synced 2025-04-21 12:52:45 +00:00
commit 4540ba24c72cb2d24e2e04870025dfa233dedf30 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 11:16:13 2020 +0800 wait longer commit c8f07b81a7fe5fdef9224e8bc187500c4d67f049 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 10:55:49 2020 +0800 try to Terminate commit 10d2d4b9d0756cf8f60fe27e1e41ae29b5ea6cbe Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 10:50:26 2020 +0800 forward the error commit 38c96ee44d31088b9e6de67ebb745358fac8d49a Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 10:31:39 2020 +0800 now enable the assertion commit 3b3c46a065a035d906d4cc5022d42e30b1f52a08 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 10:26:40 2020 +0800 rm un-related info commit dd7ef7e3d0a0765c1fc48296d70966b3b4d581dd Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 10:12:01 2020 +0800 print err of provider.Run commit 49a7b57dbf52d410c0dfe796be9c2f6213884931 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 09:55:48 2020 +0800 wait until it exits commit a3e8f699072e3252b3300c667f1425a966aedb39 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 09:54:19 2020 +0800 targeting alpine:3.8 commit f30b8565049bb373a1a91a34ad07c8c3df8e1036 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 09:47:27 2020 +0800 see what happens commit 8c21229a8be8e2ac0737bbc4bb88ba54e9fb7a20 Author: z4yx <z4yx@users.noreply.github.com> Date: Sat Mar 14 09:30:50 2020 +0800 remove one assertion commit 123368e6ef07aa63c489bb49bdf370d3abdd17bb Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 23:32:45 2020 +0800 docker test somehow works now commit 94fa294a9bbedb569e6dd9cc7e4f27e73ed97443 Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 23:27:12 2020 +0800 should use -d commit b35bae2a9cb5e006c513da95377ab9487fc4341a Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 23:22:25 2020 +0800 docker run not working?? commit 9aea0036f434d333087f0cff3ce5165a53554e5f Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 23:12:39 2020 +0800 test if docker works commit f92578b159587a8bbda296bbf9261fb4c5e2f186 Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 17:42:00 2020 +0800 debugging docker_test commit b649e32f76549711af597ce3a642309a41a08bf9 Author: z4yx <z4yx@users.noreply.github.com> Date: Fri Mar 13 17:27:55 2020 +0800 Revert "remove docker_test.go" This reverts commit a517a4bb6407e873f9b3893bdddebcd369679a03.
180 lines
3.8 KiB
Go
180 lines
3.8 KiB
Go
package worker
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"sync"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/codeskyblue/go-sh"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// runner is to run os commands giving command line, env and log file
|
|
// it's an alternative to python-sh or go-sh
|
|
|
|
var errProcessNotStarted = errors.New("Process Not Started")
|
|
|
|
type cmdJob struct {
|
|
sync.Mutex
|
|
cmd *exec.Cmd
|
|
workingDir string
|
|
env map[string]string
|
|
logFile *os.File
|
|
finished chan empty
|
|
provider mirrorProvider
|
|
retErr error
|
|
}
|
|
|
|
func newCmdJob(provider mirrorProvider, cmdAndArgs []string, workingDir string, env map[string]string) *cmdJob {
|
|
var cmd *exec.Cmd
|
|
|
|
if d := provider.Docker(); d != nil {
|
|
c := "docker"
|
|
args := []string{
|
|
"run", "--rm",
|
|
"-a", "STDOUT", "-a", "STDERR",
|
|
"--name", d.Name(),
|
|
"-w", workingDir,
|
|
}
|
|
// specify user
|
|
args = append(
|
|
args, "-u",
|
|
fmt.Sprintf("%d:%d", os.Getuid(), os.Getgid()),
|
|
)
|
|
// add volumes
|
|
for _, vol := range d.Volumes() {
|
|
logger.Debugf("volume: %s", vol)
|
|
args = append(args, "-v", vol)
|
|
}
|
|
// set env
|
|
for k, v := range env {
|
|
kv := fmt.Sprintf("%s=%s", k, v)
|
|
args = append(args, "-e", kv)
|
|
}
|
|
// apply options
|
|
args = append(args, d.options...)
|
|
// apply image and command
|
|
args = append(args, d.image)
|
|
// apply command
|
|
args = append(args, cmdAndArgs...)
|
|
|
|
cmd = exec.Command(c, args...)
|
|
|
|
} else if provider.Cgroup() != nil {
|
|
c := "cgexec"
|
|
args := []string{"-g", provider.Cgroup().Cgroup()}
|
|
args = append(args, cmdAndArgs...)
|
|
cmd = exec.Command(c, args...)
|
|
|
|
} else {
|
|
if len(cmdAndArgs) == 1 {
|
|
cmd = exec.Command(cmdAndArgs[0])
|
|
} else if len(cmdAndArgs) > 1 {
|
|
c := cmdAndArgs[0]
|
|
args := cmdAndArgs[1:]
|
|
cmd = exec.Command(c, args...)
|
|
} else if len(cmdAndArgs) == 0 {
|
|
panic("Command length should be at least 1!")
|
|
}
|
|
}
|
|
|
|
if provider.Docker() == nil {
|
|
logger.Debugf("Executing command %s at %s", cmdAndArgs[0], workingDir)
|
|
if _, err := os.Stat(workingDir); os.IsNotExist(err) {
|
|
logger.Debugf("Making dir %s", workingDir)
|
|
if err = os.MkdirAll(workingDir, 0755); err != nil {
|
|
logger.Errorf("Error making dir %s: %s", workingDir, err.Error())
|
|
}
|
|
}
|
|
cmd.Dir = workingDir
|
|
cmd.Env = newEnviron(env, true)
|
|
}
|
|
|
|
return &cmdJob{
|
|
cmd: cmd,
|
|
workingDir: workingDir,
|
|
env: env,
|
|
provider: provider,
|
|
}
|
|
}
|
|
|
|
func (c *cmdJob) Start() error {
|
|
logger.Debugf("Command start: %v", c.cmd.Args)
|
|
c.finished = make(chan empty, 1)
|
|
return c.cmd.Start()
|
|
}
|
|
|
|
func (c *cmdJob) Wait() error {
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
|
|
select {
|
|
case <-c.finished:
|
|
return c.retErr
|
|
default:
|
|
err := c.cmd.Wait()
|
|
if c.cmd.Stdout != nil {
|
|
c.cmd.Stdout.(*os.File).Close()
|
|
}
|
|
c.retErr = err
|
|
close(c.finished)
|
|
return err
|
|
}
|
|
}
|
|
|
|
func (c *cmdJob) SetLogFile(logFile *os.File) {
|
|
c.cmd.Stdout = logFile
|
|
c.cmd.Stderr = logFile
|
|
}
|
|
|
|
func (c *cmdJob) Terminate() error {
|
|
if c.cmd == nil || c.cmd.Process == nil {
|
|
return errProcessNotStarted
|
|
}
|
|
|
|
if d := c.provider.Docker(); d != nil {
|
|
sh.Command(
|
|
"docker", "stop", "-t", "2", d.Name(),
|
|
).Run()
|
|
return nil
|
|
}
|
|
|
|
err := unix.Kill(c.cmd.Process.Pid, syscall.SIGTERM)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
select {
|
|
case <-time.After(2 * time.Second):
|
|
unix.Kill(c.cmd.Process.Pid, syscall.SIGKILL)
|
|
return errors.New("SIGTERM failed to kill the job")
|
|
case <-c.finished:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Copied from go-sh
|
|
func newEnviron(env map[string]string, inherit bool) []string { //map[string]string {
|
|
environ := make([]string, 0, len(env))
|
|
if inherit {
|
|
for _, line := range os.Environ() {
|
|
// if os environment and env collapses,
|
|
// omit the os one
|
|
k := strings.Split(line, "=")[0]
|
|
if _, ok := env[k]; ok {
|
|
continue
|
|
}
|
|
environ = append(environ, line)
|
|
}
|
|
}
|
|
for k, v := range env {
|
|
environ = append(environ, k+"="+v)
|
|
}
|
|
return environ
|
|
}
|