2023-05-21 23:37:54 +09:00
|
|
|
package client
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"archive/zip"
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"regexp"
|
2023-05-23 10:57:24 +09:00
|
|
|
"runtime/debug"
|
2023-05-30 16:29:14 +09:00
|
|
|
"strings"
|
2023-05-21 23:37:54 +09:00
|
|
|
"syscall"
|
|
|
|
|
"time"
|
2023-05-22 02:13:03 +09:00
|
|
|
|
2023-06-14 00:13:51 +09:00
|
|
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
2023-05-22 02:13:03 +09:00
|
|
|
"repositories.action2quare.com/ayo/houston/shared"
|
|
|
|
|
"repositories.action2quare.com/ayo/houston/shared/protos"
|
2023-05-21 23:37:54 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func lastExecutionArgs(verpath string) []string {
|
|
|
|
|
argf, err := os.Open(path.Join(verpath, "@args"))
|
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
|
argf, err = os.Open(path.Clean(path.Join(verpath, "..", "@args")))
|
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
defer argf.Close()
|
|
|
|
|
|
|
|
|
|
var out []string
|
|
|
|
|
dec := json.NewDecoder(argf)
|
|
|
|
|
dec.Decode(&out)
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-26 17:51:28 +09:00
|
|
|
var errUploadZipLogFailed = errors.New("not ok")
|
|
|
|
|
|
|
|
|
|
func (hc *houstonClient) uploadZipLogFile(zipFile string, name string, version string) error {
|
|
|
|
|
zf, err := os.Open(zipFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if zf == nil {
|
|
|
|
|
return errUploadZipLogFailed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer zf.Close()
|
|
|
|
|
|
|
|
|
|
req, err := http.NewRequest("POST", hc.httpAddr+"/upload", zf)
|
|
|
|
|
if err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println(err)
|
2023-05-26 17:51:28 +09:00
|
|
|
}
|
|
|
|
|
req.Header.Set("Houston-Service-Name", name)
|
|
|
|
|
req.Header.Set("Houston-Service-Version", version)
|
|
|
|
|
req.Header.Set("Houston-Service-Filename", path.Base(zipFile))
|
|
|
|
|
req.Header.Set("Content-Type", "application/zip")
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
|
return errUploadZipLogFailed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func zipLogFiles(req *shared.UploadRequest, start, except string) (string, []string, error) {
|
2023-05-23 10:57:24 +09:00
|
|
|
root := path.Join(req.Name, req.Version)
|
|
|
|
|
matches, err := filepath.Glob(path.Join(root, req.Filter))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(matches) == 0 {
|
|
|
|
|
return "", nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-28 21:21:37 +09:00
|
|
|
for i, file := range matches {
|
|
|
|
|
file = filepath.ToSlash(file)
|
|
|
|
|
matches[i] = file
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
root = path.Join(root, path.Dir(req.Filter))
|
2023-05-28 21:21:37 +09:00
|
|
|
zipFileName := path.Join(os.TempDir(), path.Base(matches[0])) + ".zip"
|
2023-05-26 17:51:28 +09:00
|
|
|
f, err := os.OpenFile(zipFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return "", nil, err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
defer f.Close()
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
w := zip.NewWriter(f)
|
|
|
|
|
defer w.Close()
|
|
|
|
|
|
|
|
|
|
oldestFile := ""
|
2023-05-28 21:21:37 +09:00
|
|
|
for _, file := range matches {
|
2023-05-23 10:57:24 +09:00
|
|
|
if file == root {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-05-26 17:51:28 +09:00
|
|
|
if len(except) > 0 && file >= except {
|
2023-05-23 10:57:24 +09:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if len(start) > 0 && file < start {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if len(oldestFile) == 0 {
|
|
|
|
|
oldestFile = path.Base(file)
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
relative := file[len(root)+1:]
|
|
|
|
|
fw, err := w.Create(relative)
|
|
|
|
|
if err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println(err)
|
2023-05-23 10:57:24 +09:00
|
|
|
return "", nil, err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
src, err := os.Open(file)
|
|
|
|
|
if err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println(err)
|
2023-05-23 10:57:24 +09:00
|
|
|
return "", nil, err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
defer src.Close()
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
if _, err = io.Copy(fw, src); err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println(err)
|
2023-05-23 10:57:24 +09:00
|
|
|
return "", nil, err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
return f.Name(), matches, nil
|
|
|
|
|
// defer func() {
|
|
|
|
|
// tempname := f.Name()
|
|
|
|
|
// f.Close()
|
|
|
|
|
|
|
|
|
|
// resp, _ := http.Post(req.Url, "application/zip", f)
|
|
|
|
|
// if resp != nil && resp.Body != nil {
|
|
|
|
|
// resp.Body.Close()
|
|
|
|
|
// }
|
|
|
|
|
// os.Remove(tempname)
|
|
|
|
|
// if del, err := strconv.ParseBool(req.DeleteAfterUploaded); del && err == nil {
|
|
|
|
|
// for _, file := range matches {
|
|
|
|
|
// if strings.HasSuffix(file, except) {
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
// os.Remove(file)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }()
|
|
|
|
|
|
|
|
|
|
// Create a new zip archive.
|
|
|
|
|
|
|
|
|
|
//}(f)
|
|
|
|
|
|
|
|
|
|
//return nil
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
func prepareProcessLaunch(req *shared.StartProcessRequest) *procmeta {
|
|
|
|
|
re := regexp.MustCompile(`[^\s"']+|"([^"]*)"|'([^']*)`)
|
|
|
|
|
args := re.FindAllString(req.Args, -1)
|
|
|
|
|
|
2023-05-30 15:28:18 +09:00
|
|
|
if len(args) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-05-30 12:12:23 +09:00
|
|
|
verpath := path.Join(req.Name, req.Version)
|
2023-05-23 10:57:24 +09:00
|
|
|
fi, err := os.Stat(verpath)
|
|
|
|
|
|
|
|
|
|
if err == nil && fi.IsDir() {
|
2023-05-30 16:29:14 +09:00
|
|
|
args[0] = "./" + path.Clean(strings.TrimPrefix(args[0], "/"))
|
2023-06-13 10:10:30 +09:00
|
|
|
os.Chmod(path.Join(verpath, args[0]), 0777)
|
|
|
|
|
|
2023-05-26 16:26:40 +09:00
|
|
|
cmd := exec.Command(args[0], args[1:]...)
|
2023-05-23 10:57:24 +09:00
|
|
|
cmd.Dir = verpath
|
|
|
|
|
stdin, _ := cmd.StdinPipe()
|
|
|
|
|
|
|
|
|
|
return &procmeta{
|
|
|
|
|
cmd: cmd,
|
|
|
|
|
name: req.Name,
|
|
|
|
|
version: req.Version,
|
|
|
|
|
state: protos.ProcessState_Stopped,
|
|
|
|
|
stdin: stdin,
|
|
|
|
|
logUploadChan: make(chan *shared.UploadRequest),
|
|
|
|
|
buffers: bufferStack{cursor: 0},
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
return nil
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
func (hc *houstonClient) launch(meta *procmeta) error {
|
|
|
|
|
stdout, err := meta.cmd.StdoutPipe()
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
stderr, err := meta.cmd.StderrPipe()
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-13 10:10:30 +09:00
|
|
|
err = os.MkdirAll(path.Join(meta.cmd.Dir, "logs"), 0775)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
relayChan := make(chan struct {
|
|
|
|
|
size int
|
|
|
|
|
buf []byte
|
|
|
|
|
})
|
2023-05-21 23:37:54 +09:00
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
defer func() {
|
2023-05-23 10:57:24 +09:00
|
|
|
r := recover()
|
|
|
|
|
if r != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println(r)
|
2023-05-23 10:57:24 +09:00
|
|
|
debug.PrintStack()
|
|
|
|
|
}
|
|
|
|
|
close(relayChan)
|
|
|
|
|
hc.exitChan <- meta.cmd
|
2023-05-21 23:37:54 +09:00
|
|
|
}()
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
now := time.Now().UTC()
|
|
|
|
|
ext := path.Ext(meta.cmd.Args[0])
|
|
|
|
|
nameonly := path.Base(meta.cmd.Args[0])
|
|
|
|
|
if len(ext) > 0 {
|
|
|
|
|
nameonly = nameonly[:len(nameonly)-len(ext)]
|
|
|
|
|
}
|
|
|
|
|
ts := now.Format("2006-01-02T15-04-05")
|
|
|
|
|
stdPrefix := path.Join(meta.cmd.Dir, "logs", fmt.Sprintf("%s_%s", nameonly, ts))
|
|
|
|
|
logfile, _ := os.Create(stdPrefix + "_0.log")
|
|
|
|
|
defer logfile.Close()
|
|
|
|
|
|
|
|
|
|
logfileIdx := 0
|
2023-05-21 23:37:54 +09:00
|
|
|
for {
|
2023-05-23 10:57:24 +09:00
|
|
|
thisFileSize := 0
|
|
|
|
|
switchToNextFile := func() string {
|
|
|
|
|
logfileIdx++
|
|
|
|
|
nextFile := fmt.Sprintf("%s_%d.log", stdPrefix, logfileIdx)
|
|
|
|
|
if nextLogfile, err := os.Create(nextFile); err == nil {
|
|
|
|
|
logfile.Close()
|
|
|
|
|
logfile = nextLogfile
|
|
|
|
|
}
|
|
|
|
|
thisFileSize = 0
|
|
|
|
|
return nextFile
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uploadStartFile := ""
|
|
|
|
|
select {
|
|
|
|
|
case req := <-meta.logUploadChan:
|
|
|
|
|
nextFile := switchToNextFile()
|
|
|
|
|
startFile := uploadStartFile
|
|
|
|
|
uploadStartFile = nextFile
|
|
|
|
|
go func(startFile, nextFile string) {
|
2023-05-26 17:51:28 +09:00
|
|
|
zipFile, srcFiles, err := zipLogFiles(req, startFile, nextFile)
|
2023-05-23 10:57:24 +09:00
|
|
|
if err == nil && len(zipFile) > 0 && len(srcFiles) > 0 {
|
2023-05-26 17:51:28 +09:00
|
|
|
if err = hc.uploadZipLogFile(zipFile, meta.name, meta.version); err == nil {
|
|
|
|
|
for _, oldf := range srcFiles {
|
|
|
|
|
os.Remove(oldf)
|
2023-05-23 10:57:24 +09:00
|
|
|
}
|
2023-05-26 17:51:28 +09:00
|
|
|
} else {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("uploadZipLogFile failed :", err)
|
2023-05-23 10:57:24 +09:00
|
|
|
}
|
2023-05-26 17:51:28 +09:00
|
|
|
} else if err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("zipLogFiles failed :", err)
|
2023-05-23 10:57:24 +09:00
|
|
|
}
|
|
|
|
|
}(startFile, nextFile)
|
|
|
|
|
|
|
|
|
|
case bt := <-relayChan:
|
|
|
|
|
if bt.buf == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
logfile.Write(bt.buf[:bt.size])
|
|
|
|
|
meta.buffers.push(bt.buf)
|
|
|
|
|
thisFileSize += bt.size
|
|
|
|
|
if thisFileSize > 1024*1024 {
|
|
|
|
|
switchToNextFile()
|
|
|
|
|
}
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
stdReader := func(r io.Reader) {
|
2023-05-21 23:37:54 +09:00
|
|
|
defer func() {
|
|
|
|
|
recover()
|
2023-05-23 10:57:24 +09:00
|
|
|
stdout.Close()
|
2023-05-21 23:37:54 +09:00
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
for {
|
2023-05-23 10:57:24 +09:00
|
|
|
buff := meta.buffers.pop()
|
|
|
|
|
size, err := r.Read(buff)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
2023-05-23 10:57:24 +09:00
|
|
|
relayChan <- struct {
|
|
|
|
|
size int
|
|
|
|
|
buf []byte
|
|
|
|
|
}{buf: nil}
|
2023-05-21 23:37:54 +09:00
|
|
|
break
|
|
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
if size > 0 {
|
|
|
|
|
relayChan <- struct {
|
|
|
|
|
size int
|
|
|
|
|
buf []byte
|
|
|
|
|
}{size: size, buf: buff}
|
|
|
|
|
}
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
go stdReader(stderr)
|
|
|
|
|
go stdReader(stdout)
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
err = meta.cmd.Start()
|
|
|
|
|
if err == nil {
|
|
|
|
|
meta.state = protos.ProcessState_Running
|
|
|
|
|
}
|
|
|
|
|
return err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-30 15:28:18 +09:00
|
|
|
var errPrepareprocessLaunchFailed = errors.New("prepareProcessLaunch failed")
|
|
|
|
|
|
2023-05-21 23:37:54 +09:00
|
|
|
func (hc *houstonClient) startChildProcess(req *shared.StartProcessRequest) error {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("startChildProcess :", *req)
|
2023-05-21 23:37:54 +09:00
|
|
|
if req.Version == "latest" {
|
|
|
|
|
// 최신 버전을 찾음
|
2023-05-30 12:12:23 +09:00
|
|
|
latest, err := shared.FindLastestVersion(req.Name)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req.Version = latest
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
meta := prepareProcessLaunch(req)
|
2023-05-30 15:28:18 +09:00
|
|
|
if meta == nil {
|
|
|
|
|
return errPrepareprocessLaunchFailed
|
|
|
|
|
}
|
2023-05-23 10:57:24 +09:00
|
|
|
if err := hc.launch(meta); err != nil {
|
|
|
|
|
return err
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
// launch가 성공하면 args 저장. this and parent folder
|
2023-05-30 16:29:14 +09:00
|
|
|
vers := hc.deploys[req.Name]
|
|
|
|
|
for _, ver := range vers {
|
|
|
|
|
if ver.Version == req.Version {
|
|
|
|
|
ver.Args = meta.cmd.Args
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
if argfile, err := os.Create(path.Join(req.Name, "@args")); err == nil {
|
|
|
|
|
enc := json.NewEncoder(argfile)
|
|
|
|
|
enc.Encode(meta.cmd.Args)
|
|
|
|
|
argfile.Close()
|
|
|
|
|
}
|
|
|
|
|
if argfile, err := os.Create(path.Join(req.Name, req.Version, "@args")); err == nil {
|
|
|
|
|
enc := json.NewEncoder(argfile)
|
|
|
|
|
enc.Encode(meta.cmd.Args)
|
|
|
|
|
argfile.Close()
|
|
|
|
|
}
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
hc.childProcs = append(hc.childProcs, meta)
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
op := protos.NewOperationClient(hc.client)
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
2023-05-21 23:37:54 +09:00
|
|
|
|
2023-05-23 10:57:24 +09:00
|
|
|
return nil
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var errNoRunningProcess = errors.New("no running processed")
|
|
|
|
|
|
|
|
|
|
func (hc *houstonClient) stopChildProcess(req *shared.StopProcessRequest) error {
|
|
|
|
|
if req.Version == "latest" {
|
|
|
|
|
// 최신 버전을 찾음
|
2023-05-30 12:12:23 +09:00
|
|
|
latest, err := shared.FindLastestVersion(req.Name)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req.Version = latest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var remains []*procmeta
|
|
|
|
|
var killing []*procmeta
|
|
|
|
|
for _, proc := range hc.childProcs {
|
|
|
|
|
if proc.state != protos.ProcessState_Running {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if req.Pid != 0 {
|
|
|
|
|
if req.Pid == int32(proc.cmd.Process.Pid) {
|
|
|
|
|
// 해당 pid만 제거
|
|
|
|
|
killing = append(killing, proc)
|
|
|
|
|
} else {
|
|
|
|
|
remains = append(remains, proc)
|
|
|
|
|
}
|
|
|
|
|
} else if proc.name == req.Name {
|
|
|
|
|
if len(req.Version) == 0 {
|
|
|
|
|
// program 다 정지
|
|
|
|
|
killing = append(killing, proc)
|
|
|
|
|
} else if req.Version == proc.version {
|
|
|
|
|
// program의 특정 버전만 정지
|
|
|
|
|
killing = append(killing, proc)
|
|
|
|
|
} else {
|
|
|
|
|
// 해당 사항 없음
|
|
|
|
|
remains = append(remains, proc)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 해당 사항 없음
|
|
|
|
|
remains = append(remains, proc)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(killing) > 0 {
|
|
|
|
|
for _, proc := range killing {
|
|
|
|
|
if err := proc.cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
|
|
|
|
proc.cmd.Process.Signal(os.Kill)
|
|
|
|
|
proc.state = protos.ProcessState_Stopping
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
op := protos.NewOperationClient(hc.client)
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
|
|
|
|
|
|
|
|
|
for _, proc := range killing {
|
|
|
|
|
proc.cmd.Wait()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hc.childProcs = remains
|
|
|
|
|
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return errNoRunningProcess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (hc *houstonClient) restartChildProcess(req *shared.RestartProcessRequest) error {
|
|
|
|
|
if req.Version == "latest" {
|
|
|
|
|
// 최신 버전을 찾음
|
2023-05-30 12:12:23 +09:00
|
|
|
latest, err := shared.FindLastestVersion(req.Name)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req.Version = latest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var restarts []*procmeta
|
|
|
|
|
for _, proc := range hc.childProcs {
|
|
|
|
|
if proc.name == req.Name {
|
|
|
|
|
if len(req.Version) == 0 {
|
|
|
|
|
restarts = append(restarts, proc)
|
|
|
|
|
} else if req.Version == proc.version {
|
|
|
|
|
restarts = append(restarts, proc)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(restarts) == 0 {
|
|
|
|
|
return errNoRunningProcess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, proc := range restarts {
|
|
|
|
|
if err := proc.cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
|
|
|
|
proc.cmd.Process.Signal(os.Kill)
|
|
|
|
|
}
|
|
|
|
|
proc.state = protos.ProcessState_Stopping
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
op := protos.NewOperationClient(hc.client)
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
|
|
|
|
|
|
|
|
|
for _, proc := range restarts {
|
|
|
|
|
proc.cmd.Wait()
|
|
|
|
|
proc.state = protos.ProcessState_Stopped
|
|
|
|
|
}
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
|
|
|
|
|
|
|
|
|
for _, proc := range restarts {
|
2023-05-23 10:57:24 +09:00
|
|
|
if err := hc.launch(proc); err != nil {
|
2023-05-21 23:37:54 +09:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
op.Refresh(context.Background(), hc.makeOperationQueryRequest())
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (hc *houstonClient) uploadFiles(req *shared.UploadRequest) error {
|
|
|
|
|
if req.Version == "latest" {
|
|
|
|
|
// 최신 버전을 찾음
|
2023-05-30 12:12:23 +09:00
|
|
|
latest, err := shared.FindLastestVersion(req.Name)
|
2023-05-21 23:37:54 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req.Version = latest
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("uploadFiles req :", *req)
|
2023-05-23 10:57:24 +09:00
|
|
|
for _, child := range hc.childProcs {
|
|
|
|
|
if child.version == req.Version && child.name == req.Name {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("uploadFiles found :", child.version, child.name)
|
2023-05-23 10:57:24 +09:00
|
|
|
child.logUploadChan <- req
|
2023-05-26 17:51:28 +09:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 실행 중이 아닌 폴더에서도 대상을 찾는다
|
|
|
|
|
// 전체 파일을 대상으로
|
|
|
|
|
zipFile, srcFiles, err := zipLogFiles(req, "", "")
|
|
|
|
|
if err == nil && len(zipFile) > 0 && len(srcFiles) > 0 {
|
|
|
|
|
if err = hc.uploadZipLogFile(zipFile, req.Name, req.Version); err == nil {
|
|
|
|
|
for _, oldf := range srcFiles {
|
|
|
|
|
os.Remove(oldf)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("uploadZipLogFile failed :", err)
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
2023-05-26 17:51:28 +09:00
|
|
|
} else if err != nil {
|
2023-06-14 00:13:51 +09:00
|
|
|
logger.Println("zipLogFiles failed :", err)
|
2023-05-21 23:37:54 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|