Files
houston/replacer/main.go

115 lines
2.2 KiB
Go

package main
import (
"encoding/json"
"errors"
"io"
"log"
"os"
"os/exec"
"path"
"time"
)
func copy(src, dst string) error {
fi, err := os.Stat(src)
if err != nil {
return err
}
inmode := fi.Mode()
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
copied, err := io.Copy(out, in)
if err != nil {
return err
}
if copied < fi.Size() {
return errors.New("copy not completed")
}
if err := out.Sync(); err != nil {
return err
}
if err := out.Chmod(inmode); err != nil {
return err
}
return nil
}
func main() {
logfile, _ := os.OpenFile("replacer.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
defer logfile.Close()
stdlog := log.New(logfile, "", log.LstdFlags)
args := os.Args
// args[1] : 나를 시작한 pid. pid가 종료될 때 까지 기다림
// args[2] : target 폴더
// args[3:] : 다시 시작할 때 넘겨줄 arguments(프로세스 이름 포함)
stdlog.Println(args)
for {
stdlog.Println("wait for terminating of", args[3])
cmd := exec.Command("ps", "-p", args[1])
if err := cmd.Run(); err != nil {
break
}
time.Sleep(time.Second)
}
stdlog.Println("target is terminated")
selfext, _ := os.Executable()
selfext = path.Base(selfext)
nextArgs := args[4:]
entries, _ := os.ReadDir(args[2])
for _, ent := range entries {
if ent.Name() == selfext {
continue
}
if ent.IsDir() {
if err := os.MkdirAll(ent.Name(), 0775); err != nil {
stdlog.Fatal(err)
}
} else {
if ent.Name() == "@args" {
var tempArgs []string
argfile, _ := os.Open(path.Join(args[2], ent.Name()))
dec := json.NewDecoder(argfile)
if dec.Decode(&tempArgs) == nil {
nextArgs = tempArgs
}
} else if err := copy(path.Join(args[2], ent.Name()), ent.Name()); err != nil {
stdlog.Println("copy failed :", path.Join(args[2], ent.Name()), ent.Name())
stdlog.Fatal(err)
}
}
}
err := os.RemoveAll(args[2])
if err != nil {
stdlog.Println("os.RemoveAll failed :", args[2], err)
}
err = os.Chmod(args[3], 0775)
if err != nil {
stdlog.Println("os.Chmod failed :", err)
}
stdlog.Println("exec.Command :", args)
cmd := exec.Command(args[3], nextArgs...)
cmd.Start()
}