From 279c9f47f052678e4fd9fd27f04234bb7dc2a6a4 Mon Sep 17 00:00:00 2001 From: mountain Date: Wed, 14 Jun 2023 14:16:47 +0900 Subject: [PATCH] =?UTF-8?q?client=EB=8F=84=20storageroot=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.go | 32 ++++++++++++++++++++++++-------- client/deploy.go | 17 ++++++++--------- client/operation.go | 26 +++++++++++++------------- server/http_api.go | 11 +++++++++-- server/http_handler.go | 2 +- server/server.go | 2 +- shared/operator.go | 6 ++++-- 7 files changed, 60 insertions(+), 36 deletions(-) diff --git a/client/client.go b/client/client.go index ffb474f..367beb2 100644 --- a/client/client.go +++ b/client/client.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "io/fs" "os" "os/exec" "os/signal" @@ -31,6 +32,7 @@ import ( type clientConfig struct { GrpcAddress string `json:"grpc_server_address"` HttpAddress string `json:"http_server_address"` + StorageRoot string `json:"storage_path"` } func loadClientConfig() (clientConfig, error) { @@ -132,12 +134,13 @@ func unmarshal[T any](val *T, src map[string]string) { } } -func gatherDeployedPrograms(name string) []*protos.VersionAndArgs { +func gatherDeployedPrograms(storageRoot, name string) []*protos.VersionAndArgs { var rawvers []*protos.VersionAndArgs - if vers, err := os.ReadDir(name); err == nil { + targetPath := path.Join(storageRoot, name) + if vers, err := os.ReadDir(targetPath); err == nil { for _, ver := range vers { if ver.IsDir() { - args := lastExecutionArgs(path.Join(name, ver.Name())) + args := lastExecutionArgs(path.Join(targetPath, ver.Name())) rawvers = append(rawvers, &protos.VersionAndArgs{ Version: ver.Name(), Args: args, @@ -205,13 +208,26 @@ func NewClient() (HoustonClient, error) { return nil, err } + sp, err := os.Stat(clientConfig.StorageRoot) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + err = os.MkdirAll(clientConfig.StorageRoot, 0775) + } + } else if !sp.IsDir() { + err = errors.New(clientConfig.StorageRoot + " is not directory") + } + + if err != nil { + return nil, err + } + deploys := make(map[string][]*protos.VersionAndArgs) - if dirs, err := os.ReadDir("./"); err == nil { + if dirs, err := os.ReadDir(clientConfig.StorageRoot); err == nil { for _, dir := range dirs { if dir.IsDir() { - flagf := path.Join(dir.Name(), "@houston") + flagf := path.Join(clientConfig.StorageRoot, dir.Name(), "@houston") if _, err := os.Stat(flagf); !os.IsNotExist(err) { - deploys[dir.Name()] = gatherDeployedPrograms(dir.Name()) + deploys[dir.Name()] = gatherDeployedPrograms(clientConfig.StorageRoot, dir.Name()) } } } @@ -289,7 +305,7 @@ func NewClient() (HoustonClient, error) { } } else { if err := hc.deploy(&dr); err == nil { - prog := gatherDeployedPrograms(dr.Name) + prog := gatherDeployedPrograms(hc.config.StorageRoot, dr.Name) hc.deploys[dr.Name] = prog op.Refresh(ctx, hc.makeOperationQueryRequest()) } else { @@ -302,7 +318,7 @@ func NewClient() (HoustonClient, error) { unmarshal(&wr, resp.Args) err := hc.withdraw(&wr) if err == nil { - prog := gatherDeployedPrograms(wr.Name) + prog := gatherDeployedPrograms(hc.config.StorageRoot, wr.Name) if len(prog) == 0 { delete(hc.deploys, wr.Name) } else { diff --git a/client/deploy.go b/client/deploy.go index 676b9f6..69fa393 100644 --- a/client/deploy.go +++ b/client/deploy.go @@ -56,9 +56,6 @@ func download(dir string, urlpath string, accessToken string) (string, error) { return filepath.ToSlash(out.Name()), nil } -func UnzipTest(fname string) error { - return unzip(fname) -} func unzip(fname string) error { archive, err := zip.OpenReader(fname) if err != nil { @@ -161,8 +158,9 @@ func (hc *houstonClient) prepareDeploy(name string, version string) (destPath st // houston관리용임을 표시하기 위해 더미파일 생성 defer func() { var flagf *os.File - if _, err := os.Stat(path.Join(name, "@houston")); os.IsNotExist(err) { - flagf, err = os.Create(path.Join(name, "@houston")) + markerPath := path.Join(hc.config.StorageRoot, name, "@houston") + if _, err := os.Stat(markerPath); os.IsNotExist(err) { + flagf, err = os.Create(markerPath) if err != nil { return } @@ -171,7 +169,7 @@ func (hc *houstonClient) prepareDeploy(name string, version string) (destPath st } }() - verpath := path.Join(name, version) + verpath := path.Join(hc.config.StorageRoot, name, version) if _, err := os.Stat(verpath); os.IsNotExist(err) { // 없네? 만들면 된다. err = os.MkdirAll(verpath, 0775) @@ -293,7 +291,7 @@ func (hc *houstonClient) deploy(req *shared.DeployRequest) error { err = untar(fname) } - if err == nil { + if err == nil && len(req.Config) > 0 { // config.json도 다운로드 _, err = download(root, hc.makeDownloadUrl(req.Config), req.AccessToken) } @@ -302,7 +300,8 @@ func (hc *houstonClient) deploy(req *shared.DeployRequest) error { } func (hc *houstonClient) withdraw(req *shared.WithdrawRequest) error { - fd, _ := os.Stat(path.Join(req.Name, req.Version)) + targetPath := path.Join(hc.config.StorageRoot, req.Name, req.Version) + fd, _ := os.Stat(targetPath) if fd != nil { if fd.IsDir() { for _, running := range hc.childProcs { @@ -312,7 +311,7 @@ func (hc *houstonClient) withdraw(req *shared.WithdrawRequest) error { } } - return os.RemoveAll(path.Join(req.Name, req.Version)) + return os.RemoveAll(targetPath) } } diff --git a/client/operation.go b/client/operation.go index 51dc7b3..63bc4cf 100644 --- a/client/operation.go +++ b/client/operation.go @@ -74,8 +74,8 @@ func (hc *houstonClient) uploadZipLogFile(zipFile string, name string, version s return nil } -func zipLogFiles(req *shared.UploadRequest, start, except string) (string, []string, error) { - root := path.Join(req.Name, req.Version) +func zipLogFiles(storageRoot string, req *shared.UploadRequest, start, except string) (string, []string, error) { + root := path.Join(storageRoot, req.Name, req.Version) matches, err := filepath.Glob(path.Join(root, req.Filter)) if err != nil { return "", nil, err @@ -164,14 +164,14 @@ func zipLogFiles(req *shared.UploadRequest, start, except string) (string, []str //return nil } -func prepareProcessLaunch(req *shared.StartProcessRequest) *procmeta { +func prepareProcessLaunch(storageRoot string, req *shared.StartProcessRequest) *procmeta { re := regexp.MustCompile(`[^\s"']+|"([^"]*)"|'([^']*)`) args := re.FindAllString(req.Args, -1) if len(args) == 0 { return nil } - verpath := path.Join(req.Name, req.Version) + verpath := path.Join(storageRoot, req.Name, req.Version) fi, err := os.Stat(verpath) if err == nil && fi.IsDir() { @@ -258,7 +258,7 @@ func (hc *houstonClient) launch(meta *procmeta) error { startFile := uploadStartFile uploadStartFile = nextFile go func(startFile, nextFile string) { - zipFile, srcFiles, err := zipLogFiles(req, startFile, nextFile) + zipFile, srcFiles, err := zipLogFiles(hc.config.StorageRoot, req, startFile, nextFile) if err == nil && len(zipFile) > 0 && len(srcFiles) > 0 { if err = hc.uploadZipLogFile(zipFile, meta.name, meta.version); err == nil { for _, oldf := range srcFiles { @@ -327,7 +327,7 @@ func (hc *houstonClient) startChildProcess(req *shared.StartProcessRequest, op p logger.Println("startChildProcess :", *req) if req.Version == "latest" { // 최신 버전을 찾음 - latest, err := shared.FindLastestVersion(req.Name) + latest, err := shared.FindLastestVersion(hc.config.StorageRoot, req.Name) if err != nil { return err } @@ -335,7 +335,7 @@ func (hc *houstonClient) startChildProcess(req *shared.StartProcessRequest, op p req.Version = latest } - meta := prepareProcessLaunch(req) + meta := prepareProcessLaunch(hc.config.StorageRoot, req) if meta == nil { return errPrepareprocessLaunchFailed } @@ -351,12 +351,12 @@ func (hc *houstonClient) startChildProcess(req *shared.StartProcessRequest, op p } } - if argfile, err := os.Create(path.Join(req.Name, "@args")); err == nil { + if argfile, err := os.Create(path.Join(hc.config.StorageRoot, 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 { + if argfile, err := os.Create(path.Join(hc.config.StorageRoot, req.Name, req.Version, "@args")); err == nil { enc := json.NewEncoder(argfile) enc.Encode(meta.cmd.Args) argfile.Close() @@ -373,7 +373,7 @@ var errNoRunningProcess = errors.New("no running processed") func (hc *houstonClient) stopChildProcess(req *shared.StopProcessRequest, op protos.OperationClient) error { if req.Version == "latest" { // 최신 버전을 찾음 - latest, err := shared.FindLastestVersion(req.Name) + latest, err := shared.FindLastestVersion(hc.config.StorageRoot, req.Name) if err != nil { return err } @@ -439,7 +439,7 @@ func (hc *houstonClient) stopChildProcess(req *shared.StopProcessRequest, op pro func (hc *houstonClient) restartChildProcess(req *shared.RestartProcessRequest, op protos.OperationClient) error { if req.Version == "latest" { // 최신 버전을 찾음 - latest, err := shared.FindLastestVersion(req.Name) + latest, err := shared.FindLastestVersion(hc.config.StorageRoot, req.Name) if err != nil { return err } @@ -490,7 +490,7 @@ func (hc *houstonClient) restartChildProcess(req *shared.RestartProcessRequest, func (hc *houstonClient) uploadFiles(req *shared.UploadRequest) error { if req.Version == "latest" { // 최신 버전을 찾음 - latest, err := shared.FindLastestVersion(req.Name) + latest, err := shared.FindLastestVersion(hc.config.StorageRoot, req.Name) if err != nil { return err } @@ -509,7 +509,7 @@ func (hc *houstonClient) uploadFiles(req *shared.UploadRequest) error { // 실행 중이 아닌 폴더에서도 대상을 찾는다 // 전체 파일을 대상으로 - zipFile, srcFiles, err := zipLogFiles(req, "", "") + zipFile, srcFiles, err := zipLogFiles(hc.config.StorageRoot, 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 { diff --git a/server/http_api.go b/server/http_api.go index 5f7d377..3b4fceb 100644 --- a/server/http_api.go +++ b/server/http_api.go @@ -2,7 +2,9 @@ package server import ( "encoding/json" + "errors" "io" + "io/fs" "net/http" "os" "path" @@ -176,12 +178,17 @@ func (h *houstonHandler) Deploy(w http.ResponseWriter, r *http.Request) { return } + configPath := "" + if _, err := os.Stat(path.Join(h.deployPath, name, "config", "config.json")); err == nil || errors.Is(err, fs.ErrExist) { + configPath = path.Join("deploys", name, "config", "config.json") + } + h.Operation().Deploy(MakeDeployRequest( shared.DeployRequest{ Name: name, Version: version, Url: path.Join("deploys", name, version, latestFilename), - Config: path.Join("deploys", name, "config", "config.json"), + Config: configPath, }, targets, )) @@ -338,7 +345,7 @@ func (h *houstonHandler) GetLogFileLinks(w http.ResponseWriter, r *http.Request) } if version == "latest" { - version, _ = shared.FindLastestVersion(path.Join(h.downloadPath, name)) + version, _ = shared.FindLastestVersion(h.downloadPath, name) } root := path.Join(h.downloadPath, name, version) diff --git a/server/http_handler.go b/server/http_handler.go index b192120..b3678df 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -45,7 +45,7 @@ func NewHoustonHandler() HoustonServerWithHandler { } func (h *houstonHandler) RegisterHandlers(serveMux *http.ServeMux, prefix string) error { - storagePath := loadServerConfig().StoragePath + storagePath := loadServerConfig().StorageRoot h.deployPath = path.Join(storagePath, "deploys") h.downloadPath = path.Join(storagePath, "downloads") diff --git a/server/server.go b/server/server.go index 019a56d..52157fc 100644 --- a/server/server.go +++ b/server/server.go @@ -22,7 +22,7 @@ type HoustonServer interface { type serverConfig struct { GrpcPort int `json:"grpc_port"` - StoragePath string `json:"storage_path"` + StorageRoot string `json:"storage_path"` } type DeployRequest struct { diff --git a/shared/operator.go b/shared/operator.go index de404bf..4c64b54 100644 --- a/shared/operator.go +++ b/shared/operator.go @@ -3,6 +3,7 @@ package shared import ( "io/fs" "os" + "path" "strings" ) @@ -89,9 +90,10 @@ func CompareVersionString(lhs, rhs ParsedVersionString) int { return len(lhs) - len(rhs) } -func FindLastestVersion(root string) (string, error) { +func FindLastestVersion(storageRoot, name string) (string, error) { // 최신 버전을 찾음 - entries, err := os.ReadDir(root) + targetPath := path.Join(storageRoot, name) + entries, err := os.ReadDir(targetPath) if err != nil { return "", err }