2023-06-09 16:16:26 +09:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2023-06-14 01:50:25 +09:00
|
|
|
"encoding/json"
|
2023-06-09 16:16:26 +09:00
|
|
|
"errors"
|
|
|
|
|
"io"
|
2023-06-13 20:03:10 +09:00
|
|
|
"log"
|
2023-06-09 16:16:26 +09:00
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path"
|
2023-06-26 22:38:29 +09:00
|
|
|
"time"
|
2023-06-09 16:16:26 +09:00
|
|
|
)
|
|
|
|
|
|
2023-06-29 14:13:04 +09:00
|
|
|
func copy(src, dst string, stdlog *log.Logger) error {
|
2023-06-09 16:16:26 +09:00
|
|
|
fi, err := os.Stat(src)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-06-29 14:13:04 +09:00
|
|
|
if fi.IsDir() {
|
|
|
|
|
entries, _ := os.ReadDir(src)
|
|
|
|
|
for _, ent := range entries {
|
|
|
|
|
if err := copy(path.Join(src, ent.Name()), path.Join(dst, ent.Name()), stdlog); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-09 16:16:26 +09:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-29 14:13:04 +09:00
|
|
|
stdlog.Println("file copied :", src, dst)
|
2023-06-09 16:16:26 +09:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
2023-06-13 20:03:10 +09:00
|
|
|
logfile, _ := os.OpenFile("replacer.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
|
|
|
|
defer logfile.Close()
|
|
|
|
|
stdlog := log.New(logfile, "", log.LstdFlags)
|
|
|
|
|
|
2023-06-09 16:16:26 +09:00
|
|
|
args := os.Args
|
|
|
|
|
// args[1] : 나를 시작한 pid. pid가 종료될 때 까지 기다림
|
|
|
|
|
// args[2] : target 폴더
|
|
|
|
|
// args[3:] : 다시 시작할 때 넘겨줄 arguments(프로세스 이름 포함)
|
2023-06-13 20:03:10 +09:00
|
|
|
stdlog.Println(args)
|
2023-06-09 16:16:26 +09:00
|
|
|
|
2023-06-26 22:38:29 +09:00
|
|
|
for {
|
|
|
|
|
stdlog.Println("wait for terminating of", args[3])
|
2023-06-28 18:29:12 +09:00
|
|
|
cmd := exec.Command("ps", "-p", args[1])
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
2023-06-28 18:22:50 +09:00
|
|
|
break
|
|
|
|
|
}
|
2023-06-26 22:38:29 +09:00
|
|
|
time.Sleep(time.Second)
|
2023-06-09 16:16:26 +09:00
|
|
|
}
|
|
|
|
|
|
2023-06-28 18:15:13 +09:00
|
|
|
stdlog.Println("target is terminated")
|
|
|
|
|
|
2023-06-29 14:13:04 +09:00
|
|
|
// replacer 제거. 내가 돌고 있으므로 복사는 안된다.
|
|
|
|
|
// 내가 실행되기 전에 이미 복사가 되서 나는 최신 버전임
|
|
|
|
|
os.Remove(path.Join(args[2], os.Args[0]))
|
|
|
|
|
if err := copy(args[2], "", stdlog); err != nil {
|
|
|
|
|
stdlog.Fatal(err)
|
|
|
|
|
}
|
2023-06-09 16:16:26 +09:00
|
|
|
|
2023-06-29 14:13:04 +09:00
|
|
|
nextArgs := args[4:]
|
|
|
|
|
if bt, _ := os.ReadFile("@args"); len(bt) > 0 {
|
|
|
|
|
var tempArgs []string
|
|
|
|
|
if json.Unmarshal(bt, &tempArgs) == nil {
|
|
|
|
|
nextArgs = tempArgs
|
2023-06-09 16:16:26 +09:00
|
|
|
}
|
|
|
|
|
}
|
2023-06-29 14:13:04 +09:00
|
|
|
os.Remove("@args")
|
2023-06-09 16:16:26 +09:00
|
|
|
|
2023-06-28 18:29:12 +09:00
|
|
|
err := os.RemoveAll(args[2])
|
2023-06-13 20:03:10 +09:00
|
|
|
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)
|
2023-06-14 01:50:25 +09:00
|
|
|
cmd := exec.Command(args[3], nextArgs...)
|
2023-06-09 16:16:26 +09:00
|
|
|
cmd.Start()
|
|
|
|
|
}
|