commit 3e8c79a48b386930621c9c30138f40d38a913a1a Author: mountain Date: Sun May 21 23:37:54 2023 +0900 houston package 독립 diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..beff0f0 --- /dev/null +++ b/client/client.go @@ -0,0 +1,329 @@ +package client + +import ( + "context" + "go-ayo/common/logger" + "houston/shared" + "houston/shared/protos" + "io" + "os" + "os/exec" + "path" + "reflect" + "sort" + "strconv" + "sync/atomic" + "unsafe" + + "time" + + "github.com/shirou/gopsutil/v3/cpu" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + sigar "github.com/cloudfoundry/gosigar" +) + +type HoustonClient interface { + SetReportMetrics(map[string]float32) + Shutdown() +} + +type procmeta struct { + cmd *exec.Cmd + name string + version string + state protos.ProcessState + stdin io.WriteCloser + stdPrefix string + stdoutSize int32 + stderrSize int32 +} + +type houstonClient struct { + client *grpc.ClientConn + childProcs []*procmeta + extraMetrics unsafe.Pointer // map[string]float32 + deploys map[string][]*protos.VersionAndArgs + shutdownFunc context.CancelFunc + exitChan chan *exec.Cmd + httpAddr string + timestamp string +} + +func bToMb(b uint64) uint32 { + return uint32(b / 1024 / 1024) +} + +func unmarshal[T any](val *T, src map[string]string) { + argval := reflect.ValueOf(val) + for i := 0; i < argval.Elem().Type().NumField(); i++ { + if !argval.Elem().Type().Field(i).IsExported() { + continue + } + arg := src[argval.Elem().Type().Field(i).Name] + if argval.Elem().Field(i).CanInt() { + num, _ := strconv.ParseInt(arg, 10, 0) + argval.Elem().Field(i).SetInt(num) + } else { + argval.Elem().Field(i).SetString(arg) + } + } +} + +func gatherDeployedPrograms(name string) []*protos.VersionAndArgs { + var rawvers []*protos.VersionAndArgs + if vers, err := os.ReadDir(path.Join("./", name)); err == nil { + for _, ver := range vers { + if ver.IsDir() { + args := lastExecutionArgs(path.Join(name, ver.Name())) + rawvers = append(rawvers, &protos.VersionAndArgs{ + Version: ver.Name(), + Args: args, + }) + } + } + } + sort.Slice(rawvers, func(i, j int) bool { + leftParsed := parseVersionString(rawvers[i].Version) + rightParsed := parseVersionString(rawvers[j].Version) + return compareVersionString(leftParsed, rightParsed) < 0 + }) + return rawvers +} + +func (hc *houstonClient) makeOperationQueryRequest() *protos.OperationQueryRequest { + hn, _ := os.Hostname() + procs := make([]*protos.ProcessDescription, 0, len(hc.childProcs)) + for _, child := range hc.childProcs { + procs = append(procs, &protos.ProcessDescription{ + Name: child.name, + Args: child.cmd.Args, + Version: child.version, + State: child.state, + Pid: int32(child.cmd.Process.Pid), + StdoutSize: atomic.LoadInt32(&child.stdoutSize), + StderrSize: atomic.LoadInt32(&child.stderrSize), + }) + } + + var deploys []*protos.DeployedVersions + for name, prog := range hc.deploys { + deploys = append(deploys, &protos.DeployedVersions{ + Name: name, + Versions: prog, + }) + } + + return &protos.OperationQueryRequest{ + Hostname: hn, + Procs: procs, + Deploys: deploys, + } +} + +func NewClient(grpcAddr string, httpAddr string) (HoustonClient, error) { + client, err := grpc.Dial(grpcAddr, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, err + } + + exefile, err := os.Executable() + if err != nil { + return nil, err + } + + exefi, err := os.Stat(exefile) + if err != nil { + return nil, err + } + + deploys := make(map[string][]*protos.VersionAndArgs) + if dirs, err := os.ReadDir("./"); err == nil { + for _, dir := range dirs { + if dir.IsDir() { + flagf := path.Join(dir.Name(), "@houston") + if _, err := os.Stat(flagf); !os.IsNotExist(err) { + deploys[dir.Name()] = gatherDeployedPrograms(dir.Name()) + } + } + } + } + + hc := &houstonClient{ + client: client, + extraMetrics: unsafe.Pointer(&map[string]float32{}), + deploys: deploys, + httpAddr: httpAddr, + timestamp: exefi.ModTime().String(), + } + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + // regularly send status + sc := protos.NewMonitorClient(client) + hn, _ := os.Hostname() + mem := sigar.Mem{} + mem.Get() + + metrics := &protos.Metrics{ + Hostname: hn, + Total: bToMb(mem.Total), + } + + for { + select { + case <-ctx.Done(): + return + + case <-time.After(5 * time.Second): + percent, _ := cpu.Percent(0, false) + + metrics.Cpu = float32(percent[0]) + metrics.Free = bToMb(mem.ActualFree) + metrics.Metrics = *(*map[string]float32)(atomic.LoadPointer(&hc.extraMetrics)) + + sc.Report(context.Background(), metrics, grpc.WaitForReady(true)) + mem.Get() + } + } + }() + + exitChan := make(chan *exec.Cmd, 10) + operationChan := make(chan *protos.OperationQueryResponse, 10) + go func() { + // 메인 operator + op := protos.NewOperationClient(hc.client) + + for { + select { + case <-ctx.Done(): + return + + case exited := <-exitChan: + for _, proc := range hc.childProcs { + if proc.cmd == exited && proc.state != protos.ProcessState_Stopped { + proc.state = protos.ProcessState_Stopped + op.Refresh(ctx, hc.makeOperationQueryRequest()) + break + } + } + + case resp := <-operationChan: + switch shared.Operation(resp.Operation) { + case shared.Deploy: + var dr shared.DeployRequest + unmarshal(&dr, resp.Args) + err := hc.deploy(&dr) + if err == nil { + prog := gatherDeployedPrograms(dr.Name) + hc.deploys[dr.Name] = prog + op.Refresh(ctx, hc.makeOperationQueryRequest()) + } else { + logger.Println(err) + } + + case shared.Withdraw: + var wr shared.WithdrawRequest + unmarshal(&wr, resp.Args) + err := hc.withdraw(&wr) + if err == nil { + prog := gatherDeployedPrograms(wr.Name) + hc.deploys[wr.Name] = prog + op.Refresh(ctx, hc.makeOperationQueryRequest()) + } else { + logger.Println(err) + } + + case shared.Start: + var sr shared.StartProcessRequest + unmarshal(&sr, resp.Args) + if err := hc.startChildProcess(&sr); err != nil { + logger.Println(err) + } + + case shared.Stop: + var sr shared.StopProcessRequest + unmarshal(&sr, resp.Args) + if err := hc.stopChildProcess(&sr); err != nil { + logger.Println(err) + } + + case shared.Restart: + var rr shared.RestartProcessRequest + unmarshal(&rr, resp.Args) + if err := hc.restartChildProcess(&rr); err != nil { + logger.Println(err) + } + + case shared.Upload: + var ur shared.UploadRequest + unmarshal(&ur, resp.Args) + if err := hc.uploadFiles(&ur); err != nil { + logger.Println(err) + } + } + } + } + }() + + go func() { + // receive from stream + for { + select { + case <-ctx.Done(): + return + + default: + err := hc.checkOperation(operationChan) + if err != nil { + logger.Println("hc.checkUpdate failed :", err) + } + } + } + }() + + hc.shutdownFunc = cancel + hc.exitChan = exitChan + + return hc, nil +} + +func (hc *houstonClient) Shutdown() { + hc.shutdownFunc() +} + +func (hc *houstonClient) checkOperation(opChan chan<- *protos.OperationQueryResponse) error { + defer func() { + r := recover() + if r != nil { + logger.Error(r) + } + }() + + op := protos.NewOperationClient(hc.client) + cl, err := op.Query(context.Background(), grpc.WaitForReady(true)) + if err != nil { + return err + } + + err = cl.Send(hc.makeOperationQueryRequest()) + + if err != nil { + cl.CloseSend() + return err + } + + for { + update, err := cl.Recv() + if err != nil { + cl.CloseSend() + return err + } + opChan <- update + } +} + +func (hc *houstonClient) SetReportMetrics(extra map[string]float32) { + atomic.StorePointer(&hc.extraMetrics, unsafe.Pointer(&extra)) +} diff --git a/client/deploy.go b/client/deploy.go new file mode 100644 index 0000000..fa6a218 --- /dev/null +++ b/client/deploy.go @@ -0,0 +1,228 @@ +package client + +import ( + "archive/tar" + "archive/zip" + "errors" + "fmt" + "go-ayo/common/logger" + "houston/shared" + "houston/shared/protos" + "io" + "io/fs" + "net/http" + "net/url" + "os" + "path" + "strings" + + "golang.org/x/text/encoding/korean" + + "golang.org/x/text/transform" +) + +func download(dir string, urlpath string, accessToken string) (string, error) { + parsed, err := url.Parse(urlpath) + if err != nil { + return "", err + } + + req, _ := http.NewRequest("GET", urlpath, nil) + if len(accessToken) > 0 { + req.Header.Add("Authorization", accessToken) + } + req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("download failed : %d %s", resp.StatusCode, parsed.Path) + } + + out, err := os.Create(path.Join(dir, path.Base(parsed.Path))) + if err != nil { + return "", err + } + defer out.Close() + + _, err = io.Copy(out, resp.Body) + if err != nil { + return "", err + } + + return out.Name(), nil +} + +func unzip(fname string) error { + archive, err := zip.OpenReader(fname) + if err != nil { + os.Remove(fname) + return err + } + defer archive.Close() + + verpath := path.Dir(fname) + for _, f := range archive.File { + var name string + if f.NonUTF8 { + name, _, _ = transform.String(korean.EUCKR.NewDecoder(), f.Name) + } else { + name = f.Name + } + + filePath := path.Join(verpath, name) + + if f.FileInfo().IsDir() { + os.MkdirAll(filePath, os.ModePerm) + continue + } + + if err := os.MkdirAll(path.Dir(filePath), os.ModePerm); err != nil { + return err + } + + dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + if err != nil { + return err + } + + fileInArchive, err := f.Open() + if err != nil { + return err + } + + if _, err := io.Copy(dstFile, fileInArchive); err != nil { + return err + } + + dstFile.Close() + fileInArchive.Close() + } + return nil +} + +func untar(fname string) error { + file, err := os.Open(fname) + if err != nil { + return err + } + defer file.Close() + + verpath := path.Dir(fname) + tarReader := tar.NewReader(file) + for { + header, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + + switch header.Typeflag { + case tar.TypeDir: + if err := os.MkdirAll(path.Join(verpath, header.Name), 0755); err != nil { + return err + } + case tar.TypeReg: + fileWriter, err := os.Create(path.Join(verpath, header.Name)) + if err != nil { + return err + } + defer fileWriter.Close() + + if _, err := io.Copy(fileWriter, tarReader); err != nil { + return err + } + default: + return errors.New("unknown type") + } + } + return nil +} + +func (hc *houstonClient) prepareDeploy(name string, version string) (destPath string, err error) { + // 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")) + if err != nil { + return + } + defer flagf.Close() + flagf.Write([]byte(hc.timestamp)) + } + }() + + verpath := path.Join("./", name, version) + if _, err := os.Stat(verpath); os.IsNotExist(err) { + // 없네? 만들면 된다. + err = os.MkdirAll(verpath, fs.FileMode(os.O_WRONLY)) + if err != nil { + return "", err + } + } else { + // 있네? 재배포 가능한가? + for _, child := range hc.childProcs { + if child.version == version && child.name == name { + // 이미 실행 중인 버전이다. 실패 + return "", fmt.Errorf("%s %s is already running. deploy is failed", name, version) + } + } + // 재배포 가능 + } + return verpath, nil +} + +func (hc *houstonClient) deploy(req *shared.DeployRequest) error { + logger.Println("start deploying") + root, err := hc.prepareDeploy(req.Name, req.Version) + if err != nil { + return err + } + + if !strings.HasPrefix(req.Url, "http") { + tks := strings.SplitN(hc.httpAddr, "://", 2) + req.Url = fmt.Sprintf("%s://%s", tks[0], path.Join(tks[1], req.Url)) + } + + logger.Println("start downloading", req.Url) + // verpath에 배포 시작 + fname, err := download(root, req.Url, req.AccessToken) + if err != nil { + return err + } + + switch path.Ext(fname) { + case ".zip": + err = unzip(fname) + case ".tar": + err = untar(fname) + } + + return err +} + +func (hc *houstonClient) withdraw(req *shared.WithdrawRequest) error { + fd, _ := os.Stat(path.Join("./", req.Name, req.Version)) + if fd != nil { + if fd.IsDir() { + for _, running := range hc.childProcs { + if running.name == req.Name && running.version == req.Version { + // 회수하려는 버전이 돌고 있다 + if running.state != protos.ProcessState_Stopped { + return fmt.Errorf("withdraw failed. %s@%s is still running", req.Name, req.Version) + } + } + } + + return os.RemoveAll(path.Join("./", req.Name, req.Version)) + } + } + + return fmt.Errorf("withdraw failed. %s@%s is not deployed", req.Name, req.Version) +} diff --git a/client/operation.go b/client/operation.go new file mode 100644 index 0000000..cc2c8f5 --- /dev/null +++ b/client/operation.go @@ -0,0 +1,449 @@ +package client + +import ( + "archive/zip" + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "go-ayo/common/logger" + "houston/shared" + "houston/shared/protos" + "io" + "net/http" + "os" + "os/exec" + "path" + "path/filepath" + "regexp" + "strconv" + "strings" + "sync/atomic" + "syscall" + "time" +) + +type parsedVersionString = []string + +func parseVersionString(ver string) parsedVersionString { + return strings.Split(ver, ".") +} + +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 +} + +func compareVersionString(lhs, rhs parsedVersionString) int { + minlen := len(lhs) + if minlen > len(rhs) { + minlen = len(rhs) + } + + for i := 0; i < minlen; i++ { + if len(lhs[i]) < len(rhs[i]) { + return -1 + } + + if len(lhs[i]) > len(rhs[i]) { + return 1 + } + + if lhs[i] < rhs[i] { + return -1 + } + + if lhs[i] > rhs[i] { + return 1 + } + } + + return len(lhs) - len(rhs) +} + +func findLastestVersion(root string) (string, error) { + // 최신 버전을 찾음 + entries, err := os.ReadDir(root) + if err != nil { + return "", err + } + if len(entries) == 0 { + return "", nil + } + latest := parseVersionString(entries[0].Name()) + for i := 1; i < len(entries); i++ { + next := parseVersionString(entries[i].Name()) + if compareVersionString(latest, next) < 0 { + latest = next + } + } + return strings.Join(latest, "."), nil +} + +func (meta *procmeta) launch(args []string, exitChan chan<- *exec.Cmd) error { + exepath := args[0] + verpath := path.Dir(exepath) + args[0] = path.Base(exepath) + + cmd := exec.Command("./"+args[0], args[1:]...) + cmd.Dir = verpath + + stdin, err := cmd.StdinPipe() + if err != nil { + return err + } + stdout, err := cmd.StdoutPipe() + if err != nil { + return err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return err + } + + err = os.MkdirAll(path.Join(cmd.Dir, "logs"), os.ModePerm) + if err != nil { + return err + } + + now := time.Now().UTC() + ext := path.Ext(cmd.Args[0]) + nameonly := path.Base(cmd.Args[0]) + if len(ext) > 0 { + nameonly = nameonly[:len(nameonly)-len(ext)] + } + ts := now.Format("2006-01-02T15-04-05") + stdPrefix := path.Join(cmd.Dir, "logs", fmt.Sprintf("%s_%s", nameonly, ts)) + errfile, err := os.Create(stdPrefix + ".stderr.log") + if err != nil { + return err + } + outfile, err := os.Create(stdPrefix + ".stdout.log") + if err != nil { + return err + } + + go func() { + defer func() { + recover() + stdout.Close() + errfile.Close() + }() + + buff := make([]byte, 1024) + for { + size, err := stderr.Read(buff) + if err != nil { + exitChan <- cmd + errfile.Close() + break + } + errfile.Write(buff[:size]) + new := atomic.AddInt32(&meta.stderrSize, int32(size)) + logger.Println("stderrSize :", new) + } + }() + + go func() { + defer func() { + recover() + stderr.Close() + outfile.Close() + }() + + buff := make([]byte, 1024) + for { + size, err := stdout.Read(buff) + if err != nil { + exitChan <- cmd + break + } + outfile.Write(buff[:size]) + new := atomic.AddInt32(&meta.stdoutSize, int32(size)) + logger.Println("stdoutSize :", new) + } + }() + + err = cmd.Start() + if err != nil { + return err + } + + meta.cmd = cmd + meta.stdin = stdin + meta.stdPrefix = stdPrefix + meta.state = protos.ProcessState_Running + + return nil +} + +func (hc *houstonClient) startChildProcess(req *shared.StartProcessRequest) error { + if req.Version == "latest" { + // 최신 버전을 찾음 + latest, err := findLastestVersion(path.Join("./", req.Name)) + if err != nil { + return err + } + + req.Version = latest + } + + meta := &procmeta{ + name: req.Name, + version: req.Version, + state: protos.ProcessState_Error, + } + + verpath := path.Join("./", req.Name, req.Version) + fi, err := os.Stat(verpath) + if err == nil && fi.IsDir() { + // Define regular expression + re := regexp.MustCompile(`[^\s"']+|"([^"]*)"|'([^']*)`) + + // Split input string into array of strings + result := re.FindAllString(req.Args, -1) + for i := range result { + result[i] = strings.Trim(result[i], "\"'") + } + result[0] = path.Join(verpath, result[0]) + err := meta.launch(result, hc.exitChan) + if err != nil { + return err + } + + // launch가 성공하면 args 저장. this and parent folder + if argfile, err := os.Create(path.Join(req.Name, "@args")); err == nil { + enc := json.NewEncoder(argfile) + enc.Encode(result) + argfile.Close() + } + if argfile, err := os.Create(path.Join(verpath, "@args")); err == nil { + enc := json.NewEncoder(argfile) + enc.Encode(result) + argfile.Close() + } + + hc.childProcs = append(hc.childProcs, meta) + + op := protos.NewOperationClient(hc.client) + op.Refresh(context.Background(), hc.makeOperationQueryRequest()) + + return nil + } + + return err +} + +var errNoRunningProcess = errors.New("no running processed") + +func (hc *houstonClient) stopChildProcess(req *shared.StopProcessRequest) error { + if req.Version == "latest" { + // 최신 버전을 찾음 + latest, err := findLastestVersion(path.Join("./", req.Name)) + 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" { + // 최신 버전을 찾음 + latest, err := findLastestVersion(path.Join("./", req.Name)) + 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 { + args := proc.cmd.Args + args[0] = path.Join(proc.cmd.Dir, args[0]) + + if err := proc.launch(args, hc.exitChan); err != nil { + return err + } + } + op.Refresh(context.Background(), hc.makeOperationQueryRequest()) + + return nil +} + +func (hc *houstonClient) uploadFiles(req *shared.UploadRequest) error { + if req.Version == "latest" { + // 최신 버전을 찾음 + latest, err := findLastestVersion(path.Join("./", req.Name)) + if err != nil { + return err + } + + req.Version = latest + } + + root := path.Join(req.Name, req.Version) + matches, err := filepath.Glob(path.Join(root, req.Filter)) + if err != nil { + return err + } + + if len(matches) == 0 { + resp, err := http.Post(req.Url, "application/zip", bytes.NewBuffer([]byte{})) + if err != nil { + return err + } + resp.Body.Close() + return nil + } + + // Create a file to write the archive to. + f, err := os.CreateTemp("", "") + if err != nil { + return err + } + go func(f *os.File) { + 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 _, f := range matches { + os.Remove(f) + } + } + }() + + // Create a new zip archive. + w := zip.NewWriter(f) + defer w.Close() + + for _, file := range matches { + relative := file[len(root)+1:] + fw, err := w.Create(relative) + if err != nil { + logger.Error(err) + return + } + + src, err := os.Open(file) + if err != nil { + logger.Error(err) + return + } + defer src.Close() + + if _, err = io.Copy(fw, src); err != nil { + logger.Error(err) + return + } + + } + }(f) + + return nil +} diff --git a/config_template.json b/config_template.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/config_template.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9484f21 --- /dev/null +++ b/go.mod @@ -0,0 +1,33 @@ +module houston + +go 1.18 + +require ( + github.com/cloudfoundry/gosigar v1.3.9 + github.com/shirou/gopsutil/v3 v3.23.2 + golang.org/x/text v0.9.0 + google.golang.org/grpc v1.54.0 + google.golang.org/protobuf v1.30.0 +) + +require go-ayo v0.0.0-00010101000000-000000000000 + +require ( + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/onsi/gomega v1.18.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/redis/go-redis/v9 v9.0.4 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect +) + +replace go-ayo => ./go-ayo diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cf93c57 --- /dev/null +++ b/go.sum @@ -0,0 +1,152 @@ +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cloudfoundry/gosigar v1.3.9 h1:zpkxwm3EN+MWwqMTrW1ItFar35fS6uVUOw0jzkzW8MQ= +github.com/cloudfoundry/gosigar v1.3.9/go.mod h1:Rk3ggwwM8/wtIHMX8bwU0QWf36Pt5XdxhUhh9+lK8dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc= +github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU= +github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/houston_test.go b/houston_test.go new file mode 100644 index 0000000..e43495b --- /dev/null +++ b/houston_test.go @@ -0,0 +1,79 @@ +package houston_test + +import ( + "houston/client" + "testing" + "time" +) + +func TestOperationServer(t *testing.T) { + hc, _ := client.NewClient("localhost:8080", "http://localhost/commandcenter") + for i := 0; ; i++ { + hc.SetReportMetrics(map[string]float32{ + "count": float32(i), + }) + time.Sleep(1300 * time.Millisecond) + } + + // token, _ := getMicrosoftAuthoizationToken("30330e18-f407-4e35-a6d6-b734b9fe9ee9", "VTr8Q~VBAUAOSmFiHM~bjgszYXBm9nuGBQCk8cLq") + //go func() { + //time.Sleep(2 * time.Second) + // testver := fmt.Sprintf("%d.%d.%d", time.Now().Hour(), time.Now().Minute(), time.Now().Second()) + + // svr.Operation().Deploy(server.MakeDeployRequest( + // common.DeployRequest{ + // Name: "warehouse", + // Version: testver, + // Url: "https://actionsquare.s3.ap-northeast-2.amazonaws.com/warehouse.zip?response-content-disposition=inline&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEK7%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLW5vcnRoZWFzdC0yIkcwRQIgeYQKZXvVQsYEZNoWzxSRVjsKHzhq5VhIHVIaLpsUpssCIQCeZn8tfVM9jIjiKp62RPwEnb9oGR8T7apbsnqnntNlJCqGAwiH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAIaDDU0OTY2MjkyMDczOCIMeHddxdoH6Xfz68ZqKtoCwVyCYH45tC7aDBpkl%2FsGRPYlhUVy84h%2FVQx4Bu8hvgu3Y3fYSceAFgFWv%2FE3HpvrHD8AY42UsaHPBCd7tmlyydqnPoOr%2F5rjUCAmHXziGV7oAcO3HIbobbjO1rf3W2tQf7FSGbfPyxFdRhoObRz3sQi%2FcmYLKZWPS9UZRuWOSh2J3HHOoEdAIDq38eYxtVl1OEKxPIjfeJHTzmOOmvoOFBOzrY9HJyABcYxvmtOUvR6469Qf5r%2FTe%2BvuL1NQsYyBKwukcSxHcGbg7t%2BNeDTE%2FUS9lL7VYMEZlhfA1WSADbvAcYEu7cv7MENJ44XmAEHnC6zWIvDNqwK9FCfJrpALIJhbXqv%2FU%2Ft%2B5udZT1TXDDqp1se%2FBRLg8NyplcN4E8z6Qt%2F9pNSm1flhORHJsaPzk2ZfGeqvFvZGv1oBigwA6eJ3WCNl2hHhLkiSBg%2BvFwXA1KxxH9U8Nkl7EjDp7JmhBjqzAqPqVamph2PzNkEszr52GH69m90pjYkNTLM4nwMuGdo1f5%2BOm%2FVloBjBCh6OpTSK3XH67zEMZE0tFQ7qmqu2d69EY8Frt749G3RSNPeKptuIKxhBYF692an9nYUXiVH8OJkey0LDMbwWDaVfSZyOiYr%2FmeiVK0eRdK3C0JGwP%2BT6vUHBL1Agi5MH0dKvmlHwzvl%2BuqArgw7ZdOx%2BJsFHRD%2FqA87B5qPuvxPXkAO5qgwZfUW9MAxdh5hxcc9kNfmryYuVWD1DM%2BvRsRF2TsUqeffucajpQ7lhvN6rspDPMltD3VHFX82Hv12nqU7pHwtNLSO0D43W4JCmOJA8TFqhCkY4zCFDok0lx3x6b8w%2F4GptjvCo1c4HG9LAurTNK8HOb3XkYdmPwKOHaqMNajMsKZoohb0%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230331T060558Z&X-Amz-SignedHeaders=host&X-Amz-Expires=43199&X-Amz-Credential=ASIAX76TWSAROTUEDRGM%2F20230331%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Signature=aa6cc8aac808a066ea0c25e57b3a220cb6b2eb6118f6fb28974cb6e3c34e59d0", + // // AccessToken: token, + // }, + // []string{"mountain"}, + // )) + + // time.Sleep(2 * time.Second) + // svr.Operation().Start(server.MakeStartRequest( + // common.StartRequest{ + // Name: "warehouse", + // Version: "latest", + // Args: "biglocal.exe -port=8090 -dev", + // }, + // []string{"mountain"}, + // )) + // time.Sleep(25 * time.Second) + // svr.Operation().Restart(server.MakeRestartRequest( + // common.RestartRequest{ + // Name: "warehouse", + // Version: "latest", + // }, + // []string{"mountain"}, + // )) + + // time.Sleep(5 * time.Second) + // svr.Operation().Stop(server.MakeStopRequest( + // common.StopRequest{ + // Name: "warehouse", + // Version: "latest", + // Pid: 0, + // }, + // []string{"mountain"}, + // )) + + // svr.Operation().Upload(server.MakeUploadRequest( + // common.UploadRequest{ + // Name: "warehouse", + // Version: "latest", + // Url: "http://localhost", + // Filter: "logs/*.log", + // }, + // []string{"mountain"}, + // )) + // time.Sleep(5 * time.Second) + // svr.Operation().Withdraw(server.MakeWithdrawRequest( + // common.WithdrawRequest{ + // Name: "warehouse", + // Version: testver, + // }, + // nil, + // )) + //}() +} diff --git a/protoc.exe b/protoc.exe new file mode 100644 index 0000000..9897b09 Binary files /dev/null and b/protoc.exe differ diff --git a/protos/empty.proto b/protos/empty.proto new file mode 100644 index 0000000..575691b --- /dev/null +++ b/protos/empty.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; +option go_package = "common/protos"; + +message Empty { +} diff --git a/protos/monitor.proto b/protos/monitor.proto new file mode 100644 index 0000000..4c710b9 --- /dev/null +++ b/protos/monitor.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +option go_package = "common/protos"; +import "protos/empty.proto"; + +service Monitor { + rpc Report(Metrics) returns (Empty) {} +} + +message Metrics { + string hostname = 1; + float cpu = 3; + uint32 total = 4; + uint32 free = 5; + map metrics = 6; +} + diff --git a/protos/operation.proto b/protos/operation.proto new file mode 100644 index 0000000..643c65a --- /dev/null +++ b/protos/operation.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +option go_package = "common/protos"; +import "protos/empty.proto"; + +service Operation { + rpc Query(stream OperationQueryRequest) returns (stream OperationQueryResponse) {} + rpc Refresh(OperationQueryRequest) returns (Empty) {} +} + +message VersionAndArgs { + string version = 1; + repeated string args = 2; +} + +message DeployedVersions { + string name = 1; + repeated VersionAndArgs versions = 2; +} + +message OperationQueryRequest { + string hostname = 1; + repeated ProcessDescription procs = 2; + repeated DeployedVersions deploys = 3; +} + +enum ProcessState { + Stopped = 0; + Stopping = 1; + Running = 2; + Error = 3; +} + +message ProcessDescription { + string name = 1; + repeated string args = 2; + string version = 3; + ProcessState state = 4; + int32 pid = 5; + int32 stdout_size = 6; + int32 stderr_size = 7; +} + +message OperationQueryResponse { + string operation = 1; + map args = 2; +} \ No newline at end of file diff --git a/server/monitor.go b/server/monitor.go new file mode 100644 index 0000000..6c3c5aa --- /dev/null +++ b/server/monitor.go @@ -0,0 +1,21 @@ +package server + +import ( + "context" + "houston/shared/protos" +) + +type monitorServer struct { + protos.UnimplementedMonitorServer +} + +func newMonitorServer() *monitorServer { + return &monitorServer{} +} +func (ms *monitorServer) Report(ctx context.Context, metrics *protos.Metrics) (*protos.Empty, error) { + select { + case <-ctx.Done(): + default: + } + return &protos.Empty{}, nil +} diff --git a/server/operation.go b/server/operation.go new file mode 100644 index 0000000..f9a10cd --- /dev/null +++ b/server/operation.go @@ -0,0 +1,407 @@ +package server + +import ( + "context" + "encoding/json" + "fmt" + "go-ayo/common/logger" + "houston/shared" + "houston/shared/protos" + "reflect" + "sync" +) + +type opdef struct { + operation shared.Operation + args any +} + +type ProcessSnapshot struct { + Name string + Args []string + Version string + State protos.ProcessState + Pid int32 + StdoutSize int32 + StderrSize int32 +} + +type hostWithChan struct { + Hostname string + Procs []*protos.ProcessDescription + Deploys map[string][]*protos.VersionAndArgs + opChan chan *opdef +} + +func makeHostWithChan(desc *protos.OperationQueryRequest) *hostWithChan { + newdeploys := make(map[string][]*protos.VersionAndArgs) + for _, deploy := range desc.Deploys { + newdeploys[deploy.Name] = deploy.Versions + } + + return &hostWithChan{ + Hostname: desc.GetHostname(), + Procs: desc.Procs, + Deploys: newdeploys, + } +} + +func (pc *hostWithChan) withOpChan(c chan *opdef) *hostWithChan { + pc.opChan = c + return pc +} + +func (pc *hostWithChan) makeOpChan() *hostWithChan { + pc.opChan = make(chan *opdef, 1) + return pc +} + +type hostPool struct { + sync.Mutex + hosts map[string]*hostWithChan +} + +func (sp *hostPool) regist(desc *protos.OperationQueryRequest) (string, chan *opdef) { + sp.Lock() + defer sp.Unlock() + host := sp.hosts[desc.Hostname] + if host == nil { + host = makeHostWithChan(desc).makeOpChan() + } else { + host = makeHostWithChan(desc).withOpChan(host.opChan) + } + sp.hosts[desc.Hostname] = host + + test, _ := json.Marshal(sp.hosts) + logger.Println(string(test)) + return desc.Hostname, host.opChan +} + +func (sp *hostPool) refresh(desc *protos.OperationQueryRequest) { + sp.Lock() + defer sp.Unlock() + + host := sp.hosts[desc.Hostname] + if host != nil { + host = makeHostWithChan(desc).withOpChan(host.opChan) + sp.hosts[desc.Hostname] = host + } + + test, _ := json.Marshal(sp.hosts) + logger.Println(string(test)) +} + +func (sp *hostPool) unregist(key string) { + sp.Lock() + defer sp.Unlock() + + delete(sp.hosts, key) +} + +type hostSnapshot struct { + Procs []ProcessSnapshot + Deploys map[string][]*protos.VersionAndArgs +} + +func (sp *hostPool) allHosts() map[string]hostSnapshot { + sp.Lock() + defer sp.Unlock() + + out := make(map[string]hostSnapshot) + for hn, v := range sp.hosts { + procs := make([]ProcessSnapshot, 0, len(v.Procs)) + for _, p := range v.Procs { + procs = append(procs, ProcessSnapshot{ + Name: p.Name, + Args: p.Args, + Version: p.Version, + State: p.State, + Pid: p.Pid, + StdoutSize: p.StdoutSize, + StderrSize: p.StderrSize, + }) + } + out[hn] = hostSnapshot{ + Procs: procs, + Deploys: v.Deploys, + } + } + return out +} + +func (sp *hostPool) query(filter func(*hostWithChan) bool) []*hostWithChan { + sp.Lock() + defer sp.Unlock() + + var targets []*hostWithChan + for _, v := range sp.hosts { + if filter(v) { + targets = append(targets, v) + } + } + return targets +} + +type operationServer struct { + protos.UnimplementedOperationServer + hp hostPool +} + +func marshal(argval reflect.Value, output map[string]string) map[string]string { + if argval.Kind() == reflect.Pointer { + argval = argval.Elem() + } + + for i := 0; i < argval.Type().NumField(); i++ { + if !argval.Type().Field(i).IsExported() { + continue + } + + if argval.Type().Field(i).Anonymous { + marshal(argval.Field(i), output) + } else if argval.Field(i).CanInt() { + output[argval.Type().Field(i).Name] = fmt.Sprintf("%d", argval.Field(i).Int()) + } else { + output[argval.Type().Field(i).Name] = argval.Field(i).String() + } + } + return output +} + +func (os *operationServer) Query(svr protos.Operation_QueryServer) error { + // 서버는 업데이트가 있는지 확인하고 있으면 stream에 응답을 보낸다. + // 업데이트가 없으면 대기 + desc, err := svr.Recv() + if err != nil { + return err + } + + key, opChan := os.hp.regist(desc) + defer os.hp.unregist(key) + +Outer: + for { + select { + case <-svr.Context().Done(): + break Outer + + case opdef := <-opChan: + svr.Send(&protos.OperationQueryResponse{ + Operation: string(opdef.operation), + Args: marshal(reflect.ValueOf(opdef.args), make(map[string]string)), + }) + } + } + + return nil +} + +func (os *operationServer) Refresh(ctx context.Context, desc *protos.OperationQueryRequest) (*protos.Empty, error) { + os.hp.refresh(desc) + return &protos.Empty{}, nil +} + +func (os *operationServer) Deploy(d DeployRequest) { + var targets []*hostWithChan + if len(d.hostnames) > 0 { + // hostname에 배포 + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + targets = os.hp.query(func(p *hostWithChan) bool { + _, ok := conv[p.Hostname] + return ok + }) + } else { + // d.process에 모두 배포 + targets = os.hp.query(func(p *hostWithChan) bool { + for _, p := range p.Procs { + if p.Name == d.Name { + return true + } + } + return false + }) + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Deploy, + args: d, + } + } +} + +func (os *operationServer) Withdraw(d WithdrawRequest) { + // 프로세스가 안돌고 있는 호스트에서도 회수해야 할 수 있다. + targets := os.hp.query(func(p *hostWithChan) bool { + return true + }) + + if len(d.hostnames) > 0 { + // hostname만 정지 + var final []*hostWithChan + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + + for _, t := range targets { + if _, ok := conv[t.Hostname]; ok { + final = append(final, t) + } + } + targets = final + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Withdraw, + args: d, + } + } +} + +func (os *operationServer) StartProcess(d StartProcessRequest) { + targets := os.hp.query(func(p *hostWithChan) bool { + // 디플로이만 되어있어도 해당 + _, ok := p.Deploys[d.Name] + return ok + }) + + if len(d.hostnames) > 0 { + // hostname만 업로드 + var final []*hostWithChan + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + + for _, t := range targets { + if _, ok := conv[t.Hostname]; ok { + final = append(final, t) + } + } + targets = final + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Start, + args: d, + } + } +} + +func (os *operationServer) StopProcess(d StopProcessRequest) { + // d.process 모두 정지 + targets := os.hp.query(func(p *hostWithChan) bool { + for _, p := range p.Procs { + if p.Name == d.Name { + return true + } + } + return false + }) + + if len(d.hostnames) > 0 { + // hostname만 정지 + var final []*hostWithChan + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + + for _, t := range targets { + if _, ok := conv[t.Hostname]; ok { + final = append(final, t) + } + } + targets = final + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Stop, + args: d, + } + } +} + +func (os *operationServer) RestartProcess(d RestartProcessRequest) { + targets := os.hp.query(func(p *hostWithChan) bool { + for _, p := range p.Procs { + if p.Name == d.Name { + return true + } + } + return false + }) + + if len(d.hostnames) > 0 { + // hostname만 재시작 + var final []*hostWithChan + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + + for _, t := range targets { + if _, ok := conv[t.Hostname]; ok { + final = append(final, t) + } + } + targets = final + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Restart, + args: d, + } + } +} + +func (os *operationServer) Upload(d UploadRequest) { + targets := os.hp.query(func(p *hostWithChan) bool { + // 실행 중이 아니라 디플로이만 되어있어도 해당 + _, ok := p.Deploys[d.Name] + return ok + }) + + if len(d.hostnames) > 0 { + // hostname만 업로드 + var final []*hostWithChan + conv := make(map[string]bool) + for _, hn := range d.hostnames { + conv[hn] = true + } + + for _, t := range targets { + if _, ok := conv[t.Hostname]; ok { + final = append(final, t) + } + } + targets = final + } + + for _, t := range targets { + t.opChan <- &opdef{ + operation: shared.Upload, + args: d, + } + } +} + +func (os *operationServer) Hosts() map[string]hostSnapshot { + return os.hp.allHosts() +} + +func newOperationServer() *operationServer { + return &operationServer{ + hp: hostPool{ + hosts: map[string]*hostWithChan{}, + }, + } +} diff --git a/server/server.go b/server/server.go new file mode 100644 index 0000000..d5590f2 --- /dev/null +++ b/server/server.go @@ -0,0 +1,143 @@ +package server + +import ( + "fmt" + "houston/shared" + "houston/shared/protos" + "net" + + "google.golang.org/grpc" +) + +// protoc --go_out=. --go-grpc_out=. protos/*.proto +type HoustonServer interface { + Start(port int) error + Stop() + Operation() Operation +} + +type DeployRequest struct { + shared.DeployRequest + hostnames []string +} + +func MakeDeployRequest(req shared.DeployRequest, targets []string) DeployRequest { + return DeployRequest{ + DeployRequest: req, + hostnames: targets, + } +} + +type WithdrawRequest struct { + shared.WithdrawRequest + hostnames []string +} + +func MakeWithdrawRequest(req shared.WithdrawRequest, targets []string) WithdrawRequest { + return WithdrawRequest{ + WithdrawRequest: req, + hostnames: targets, + } +} + +type StartProcessRequest struct { + shared.StartProcessRequest + hostnames []string +} + +func MakeStartProcessRequest(req shared.StartProcessRequest, targets []string) StartProcessRequest { + return StartProcessRequest{ + StartProcessRequest: req, + hostnames: targets, + } +} + +type StopProcessRequest struct { + shared.StopProcessRequest + hostnames []string +} + +func MakeStopRequest(req shared.StopProcessRequest, targets []string) StopProcessRequest { + return StopProcessRequest{ + StopProcessRequest: req, + hostnames: targets, + } +} + +type RestartProcessRequest struct { + shared.RestartProcessRequest + hostnames []string +} + +func MakeRestartRequest(req shared.RestartProcessRequest, targets []string) RestartProcessRequest { + return RestartProcessRequest{ + RestartProcessRequest: req, + hostnames: targets, + } +} + +type UploadRequest struct { + shared.UploadRequest + hostnames []string +} + +func MakeUploadRequest(req shared.UploadRequest, targets []string) UploadRequest { + return UploadRequest{ + UploadRequest: req, + hostnames: targets, + } +} + +type Operation interface { + Deploy(DeployRequest) + Withdraw(WithdrawRequest) + StartProcess(StartProcessRequest) + StopProcess(StopProcessRequest) + RestartProcess(RestartProcessRequest) + Upload(UploadRequest) + Hosts() map[string]hostSnapshot +} + +func NewServer() HoustonServer { + + var opts []grpc.ServerOption + grpcServer := grpc.NewServer(opts...) + + os := newOperationServer() + ms := newMonitorServer() + protos.RegisterOperationServer(grpcServer, os) + protos.RegisterMonitorServer(grpcServer, ms) + + return &houstonServer{ + rpcServer: grpcServer, + os: os, + ms: ms, + } +} + +type houstonServer struct { + rpcServer *grpc.Server + os *operationServer + ms *monitorServer +} + +func (hs *houstonServer) Start(port int) error { + lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) + if err != nil { + return err + } + + if err := hs.rpcServer.Serve(lis); err != nil { + return err + } + + return nil +} + +func (hs *houstonServer) Stop() { + hs.rpcServer.GracefulStop() +} + +func (hs *houstonServer) Operation() Operation { + return hs.os +} diff --git a/shared/operator.go b/shared/operator.go new file mode 100644 index 0000000..8f5178c --- /dev/null +++ b/shared/operator.go @@ -0,0 +1,50 @@ +package shared + +type Operation string + +const ( + Deploy = Operation("deploy") + Withdraw = Operation("withdraw") + Upgrade = Operation("upgrade") + Start = Operation("start") + Restart = Operation("restart") + Stop = Operation("stop") + Upload = Operation("upload") +) + +type DeployRequest struct { + Name string + Version string + Url string + AccessToken string +} + +type WithdrawRequest struct { + Name string + Version string +} + +type StartProcessRequest struct { + Name string + Version string + Args string +} + +type StopProcessRequest struct { + Name string + Version string + Pid int32 +} + +type RestartProcessRequest struct { + Name string + Version string +} + +type UploadRequest struct { + Name string + Version string + Url string + Filter string + DeleteAfterUploaded string // true, false +} diff --git a/shared/protos/empty.pb.go b/shared/protos/empty.pb.go new file mode 100644 index 0000000..a167e92 --- /dev/null +++ b/shared/protos/empty.pb.go @@ -0,0 +1,131 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.10 +// source: protos/empty.proto + +package protos + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_empty_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_protos_empty_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_protos_empty_proto_rawDescGZIP(), []int{0} +} + +var File_protos_empty_proto protoreflect.FileDescriptor + +var file_protos_empty_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x0f, 0x5a, + 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protos_empty_proto_rawDescOnce sync.Once + file_protos_empty_proto_rawDescData = file_protos_empty_proto_rawDesc +) + +func file_protos_empty_proto_rawDescGZIP() []byte { + file_protos_empty_proto_rawDescOnce.Do(func() { + file_protos_empty_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_empty_proto_rawDescData) + }) + return file_protos_empty_proto_rawDescData +} + +var file_protos_empty_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protos_empty_proto_goTypes = []interface{}{ + (*Empty)(nil), // 0: Empty +} +var file_protos_empty_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_protos_empty_proto_init() } +func file_protos_empty_proto_init() { + if File_protos_empty_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protos_empty_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protos_empty_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_protos_empty_proto_goTypes, + DependencyIndexes: file_protos_empty_proto_depIdxs, + MessageInfos: file_protos_empty_proto_msgTypes, + }.Build() + File_protos_empty_proto = out.File + file_protos_empty_proto_rawDesc = nil + file_protos_empty_proto_goTypes = nil + file_protos_empty_proto_depIdxs = nil +} diff --git a/shared/protos/monitor.pb.go b/shared/protos/monitor.pb.go new file mode 100644 index 0000000..3f1d4fb --- /dev/null +++ b/shared/protos/monitor.pb.go @@ -0,0 +1,194 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.10 +// source: protos/monitor.proto + +package protos + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Metrics struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` + Cpu float32 `protobuf:"fixed32,3,opt,name=cpu,proto3" json:"cpu,omitempty"` + Total uint32 `protobuf:"varint,4,opt,name=total,proto3" json:"total,omitempty"` + Free uint32 `protobuf:"varint,5,opt,name=free,proto3" json:"free,omitempty"` + Metrics map[string]float32 `protobuf:"bytes,6,rep,name=metrics,proto3" json:"metrics,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed32,2,opt,name=value,proto3"` +} + +func (x *Metrics) Reset() { + *x = Metrics{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_monitor_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metrics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metrics) ProtoMessage() {} + +func (x *Metrics) ProtoReflect() protoreflect.Message { + mi := &file_protos_monitor_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Metrics.ProtoReflect.Descriptor instead. +func (*Metrics) Descriptor() ([]byte, []int) { + return file_protos_monitor_proto_rawDescGZIP(), []int{0} +} + +func (x *Metrics) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *Metrics) GetCpu() float32 { + if x != nil { + return x.Cpu + } + return 0 +} + +func (x *Metrics) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *Metrics) GetFree() uint32 { + if x != nil { + return x.Free + } + return 0 +} + +func (x *Metrics) GetMetrics() map[string]float32 { + if x != nil { + return x.Metrics + } + return nil +} + +var File_protos_monitor_proto protoreflect.FileDescriptor + +var file_protos_monitor_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xce, 0x01, 0x0a, 0x07, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, + 0x03, 0x63, 0x70, 0x75, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, + 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x72, 0x65, 0x65, 0x12, 0x2f, + 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, + 0x3a, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0x27, 0x0a, 0x07, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x08, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protos_monitor_proto_rawDescOnce sync.Once + file_protos_monitor_proto_rawDescData = file_protos_monitor_proto_rawDesc +) + +func file_protos_monitor_proto_rawDescGZIP() []byte { + file_protos_monitor_proto_rawDescOnce.Do(func() { + file_protos_monitor_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_monitor_proto_rawDescData) + }) + return file_protos_monitor_proto_rawDescData +} + +var file_protos_monitor_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_protos_monitor_proto_goTypes = []interface{}{ + (*Metrics)(nil), // 0: Metrics + nil, // 1: Metrics.MetricsEntry + (*Empty)(nil), // 2: Empty +} +var file_protos_monitor_proto_depIdxs = []int32{ + 1, // 0: Metrics.metrics:type_name -> Metrics.MetricsEntry + 0, // 1: Monitor.Report:input_type -> Metrics + 2, // 2: Monitor.Report:output_type -> Empty + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_protos_monitor_proto_init() } +func file_protos_monitor_proto_init() { + if File_protos_monitor_proto != nil { + return + } + file_protos_empty_proto_init() + if !protoimpl.UnsafeEnabled { + file_protos_monitor_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Metrics); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protos_monitor_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_protos_monitor_proto_goTypes, + DependencyIndexes: file_protos_monitor_proto_depIdxs, + MessageInfos: file_protos_monitor_proto_msgTypes, + }.Build() + File_protos_monitor_proto = out.File + file_protos_monitor_proto_rawDesc = nil + file_protos_monitor_proto_goTypes = nil + file_protos_monitor_proto_depIdxs = nil +} diff --git a/shared/protos/monitor_grpc.pb.go b/shared/protos/monitor_grpc.pb.go new file mode 100644 index 0000000..0c29671 --- /dev/null +++ b/shared/protos/monitor_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.10 +// source: protos/monitor.proto + +package protos + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// MonitorClient is the client API for Monitor service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MonitorClient interface { + Report(ctx context.Context, in *Metrics, opts ...grpc.CallOption) (*Empty, error) +} + +type monitorClient struct { + cc grpc.ClientConnInterface +} + +func NewMonitorClient(cc grpc.ClientConnInterface) MonitorClient { + return &monitorClient{cc} +} + +func (c *monitorClient) Report(ctx context.Context, in *Metrics, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/Monitor/Report", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MonitorServer is the server API for Monitor service. +// All implementations must embed UnimplementedMonitorServer +// for forward compatibility +type MonitorServer interface { + Report(context.Context, *Metrics) (*Empty, error) + mustEmbedUnimplementedMonitorServer() +} + +// UnimplementedMonitorServer must be embedded to have forward compatible implementations. +type UnimplementedMonitorServer struct { +} + +func (UnimplementedMonitorServer) Report(context.Context, *Metrics) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Report not implemented") +} +func (UnimplementedMonitorServer) mustEmbedUnimplementedMonitorServer() {} + +// UnsafeMonitorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MonitorServer will +// result in compilation errors. +type UnsafeMonitorServer interface { + mustEmbedUnimplementedMonitorServer() +} + +func RegisterMonitorServer(s grpc.ServiceRegistrar, srv MonitorServer) { + s.RegisterService(&Monitor_ServiceDesc, srv) +} + +func _Monitor_Report_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Metrics) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MonitorServer).Report(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Monitor/Report", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MonitorServer).Report(ctx, req.(*Metrics)) + } + return interceptor(ctx, in, info, handler) +} + +// Monitor_ServiceDesc is the grpc.ServiceDesc for Monitor service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Monitor_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "Monitor", + HandlerType: (*MonitorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Report", + Handler: _Monitor_Report_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "protos/monitor.proto", +} diff --git a/shared/protos/operation.pb.go b/shared/protos/operation.pb.go new file mode 100644 index 0000000..7dda84b --- /dev/null +++ b/shared/protos/operation.pb.go @@ -0,0 +1,589 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.10 +// source: protos/operation.proto + +package protos + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ProcessState int32 + +const ( + ProcessState_Stopped ProcessState = 0 + ProcessState_Stopping ProcessState = 1 + ProcessState_Running ProcessState = 2 + ProcessState_Error ProcessState = 3 +) + +// Enum value maps for ProcessState. +var ( + ProcessState_name = map[int32]string{ + 0: "Stopped", + 1: "Stopping", + 2: "Running", + 3: "Error", + } + ProcessState_value = map[string]int32{ + "Stopped": 0, + "Stopping": 1, + "Running": 2, + "Error": 3, + } +) + +func (x ProcessState) Enum() *ProcessState { + p := new(ProcessState) + *p = x + return p +} + +func (x ProcessState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProcessState) Descriptor() protoreflect.EnumDescriptor { + return file_protos_operation_proto_enumTypes[0].Descriptor() +} + +func (ProcessState) Type() protoreflect.EnumType { + return &file_protos_operation_proto_enumTypes[0] +} + +func (x ProcessState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProcessState.Descriptor instead. +func (ProcessState) EnumDescriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{0} +} + +type VersionAndArgs struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"` +} + +func (x *VersionAndArgs) Reset() { + *x = VersionAndArgs{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_operation_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionAndArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionAndArgs) ProtoMessage() {} + +func (x *VersionAndArgs) ProtoReflect() protoreflect.Message { + mi := &file_protos_operation_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionAndArgs.ProtoReflect.Descriptor instead. +func (*VersionAndArgs) Descriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{0} +} + +func (x *VersionAndArgs) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *VersionAndArgs) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +type DeployedVersions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Versions []*VersionAndArgs `protobuf:"bytes,2,rep,name=versions,proto3" json:"versions,omitempty"` +} + +func (x *DeployedVersions) Reset() { + *x = DeployedVersions{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_operation_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeployedVersions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeployedVersions) ProtoMessage() {} + +func (x *DeployedVersions) ProtoReflect() protoreflect.Message { + mi := &file_protos_operation_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeployedVersions.ProtoReflect.Descriptor instead. +func (*DeployedVersions) Descriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{1} +} + +func (x *DeployedVersions) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeployedVersions) GetVersions() []*VersionAndArgs { + if x != nil { + return x.Versions + } + return nil +} + +type OperationQueryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` + Procs []*ProcessDescription `protobuf:"bytes,2,rep,name=procs,proto3" json:"procs,omitempty"` + Deploys []*DeployedVersions `protobuf:"bytes,3,rep,name=deploys,proto3" json:"deploys,omitempty"` +} + +func (x *OperationQueryRequest) Reset() { + *x = OperationQueryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_operation_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OperationQueryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OperationQueryRequest) ProtoMessage() {} + +func (x *OperationQueryRequest) ProtoReflect() protoreflect.Message { + mi := &file_protos_operation_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OperationQueryRequest.ProtoReflect.Descriptor instead. +func (*OperationQueryRequest) Descriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{2} +} + +func (x *OperationQueryRequest) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *OperationQueryRequest) GetProcs() []*ProcessDescription { + if x != nil { + return x.Procs + } + return nil +} + +func (x *OperationQueryRequest) GetDeploys() []*DeployedVersions { + if x != nil { + return x.Deploys + } + return nil +} + +type ProcessDescription struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + State ProcessState `protobuf:"varint,4,opt,name=state,proto3,enum=ProcessState" json:"state,omitempty"` + Pid int32 `protobuf:"varint,5,opt,name=pid,proto3" json:"pid,omitempty"` + StdoutSize int32 `protobuf:"varint,6,opt,name=stdout_size,json=stdoutSize,proto3" json:"stdout_size,omitempty"` + StderrSize int32 `protobuf:"varint,7,opt,name=stderr_size,json=stderrSize,proto3" json:"stderr_size,omitempty"` +} + +func (x *ProcessDescription) Reset() { + *x = ProcessDescription{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_operation_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessDescription) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessDescription) ProtoMessage() {} + +func (x *ProcessDescription) ProtoReflect() protoreflect.Message { + mi := &file_protos_operation_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessDescription.ProtoReflect.Descriptor instead. +func (*ProcessDescription) Descriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{3} +} + +func (x *ProcessDescription) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProcessDescription) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *ProcessDescription) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ProcessDescription) GetState() ProcessState { + if x != nil { + return x.State + } + return ProcessState_Stopped +} + +func (x *ProcessDescription) GetPid() int32 { + if x != nil { + return x.Pid + } + return 0 +} + +func (x *ProcessDescription) GetStdoutSize() int32 { + if x != nil { + return x.StdoutSize + } + return 0 +} + +func (x *ProcessDescription) GetStderrSize() int32 { + if x != nil { + return x.StderrSize + } + return 0 +} + +type OperationQueryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"` + Args map[string]string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *OperationQueryResponse) Reset() { + *x = OperationQueryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_operation_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OperationQueryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OperationQueryResponse) ProtoMessage() {} + +func (x *OperationQueryResponse) ProtoReflect() protoreflect.Message { + mi := &file_protos_operation_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OperationQueryResponse.ProtoReflect.Descriptor instead. +func (*OperationQueryResponse) Descriptor() ([]byte, []int) { + return file_protos_operation_proto_rawDescGZIP(), []int{4} +} + +func (x *OperationQueryResponse) GetOperation() string { + if x != nil { + return x.Operation + } + return "" +} + +func (x *OperationQueryResponse) GetArgs() map[string]string { + if x != nil { + return x.Args + } + return nil +} + +var File_protos_operation_proto protoreflect.FileDescriptor + +var file_protos_operation_proto_rawDesc = []byte{ + 0x0a, 0x16, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x0e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x22, 0x53, 0x0a, 0x10, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x41, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x15, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x63, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x70, 0x72, 0x6f, + 0x63, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x73, 0x22, + 0xcf, 0x01, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, + 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x53, 0x69, 0x7a, + 0x65, 0x22, 0xa6, 0x01, 0x0a, 0x16, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x72, + 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x41, 0x0a, 0x0c, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x74, + 0x6f, 0x70, 0x70, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, 0x32, 0x78, 0x0a, + 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x05, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x16, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protos_operation_proto_rawDescOnce sync.Once + file_protos_operation_proto_rawDescData = file_protos_operation_proto_rawDesc +) + +func file_protos_operation_proto_rawDescGZIP() []byte { + file_protos_operation_proto_rawDescOnce.Do(func() { + file_protos_operation_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_operation_proto_rawDescData) + }) + return file_protos_operation_proto_rawDescData +} + +var file_protos_operation_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_protos_operation_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_protos_operation_proto_goTypes = []interface{}{ + (ProcessState)(0), // 0: ProcessState + (*VersionAndArgs)(nil), // 1: VersionAndArgs + (*DeployedVersions)(nil), // 2: DeployedVersions + (*OperationQueryRequest)(nil), // 3: OperationQueryRequest + (*ProcessDescription)(nil), // 4: ProcessDescription + (*OperationQueryResponse)(nil), // 5: OperationQueryResponse + nil, // 6: OperationQueryResponse.ArgsEntry + (*Empty)(nil), // 7: Empty +} +var file_protos_operation_proto_depIdxs = []int32{ + 1, // 0: DeployedVersions.versions:type_name -> VersionAndArgs + 4, // 1: OperationQueryRequest.procs:type_name -> ProcessDescription + 2, // 2: OperationQueryRequest.deploys:type_name -> DeployedVersions + 0, // 3: ProcessDescription.state:type_name -> ProcessState + 6, // 4: OperationQueryResponse.args:type_name -> OperationQueryResponse.ArgsEntry + 3, // 5: Operation.Query:input_type -> OperationQueryRequest + 3, // 6: Operation.Refresh:input_type -> OperationQueryRequest + 5, // 7: Operation.Query:output_type -> OperationQueryResponse + 7, // 8: Operation.Refresh:output_type -> Empty + 7, // [7:9] is the sub-list for method output_type + 5, // [5:7] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_protos_operation_proto_init() } +func file_protos_operation_proto_init() { + if File_protos_operation_proto != nil { + return + } + file_protos_empty_proto_init() + if !protoimpl.UnsafeEnabled { + file_protos_operation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionAndArgs); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_operation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeployedVersions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_operation_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OperationQueryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_operation_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessDescription); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_operation_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OperationQueryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protos_operation_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_protos_operation_proto_goTypes, + DependencyIndexes: file_protos_operation_proto_depIdxs, + EnumInfos: file_protos_operation_proto_enumTypes, + MessageInfos: file_protos_operation_proto_msgTypes, + }.Build() + File_protos_operation_proto = out.File + file_protos_operation_proto_rawDesc = nil + file_protos_operation_proto_goTypes = nil + file_protos_operation_proto_depIdxs = nil +} diff --git a/shared/protos/operation_grpc.pb.go b/shared/protos/operation_grpc.pb.go new file mode 100644 index 0000000..d767a29 --- /dev/null +++ b/shared/protos/operation_grpc.pb.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.10 +// source: protos/operation.proto + +package protos + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// OperationClient is the client API for Operation service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type OperationClient interface { + Query(ctx context.Context, opts ...grpc.CallOption) (Operation_QueryClient, error) + Refresh(ctx context.Context, in *OperationQueryRequest, opts ...grpc.CallOption) (*Empty, error) +} + +type operationClient struct { + cc grpc.ClientConnInterface +} + +func NewOperationClient(cc grpc.ClientConnInterface) OperationClient { + return &operationClient{cc} +} + +func (c *operationClient) Query(ctx context.Context, opts ...grpc.CallOption) (Operation_QueryClient, error) { + stream, err := c.cc.NewStream(ctx, &Operation_ServiceDesc.Streams[0], "/Operation/Query", opts...) + if err != nil { + return nil, err + } + x := &operationQueryClient{stream} + return x, nil +} + +type Operation_QueryClient interface { + Send(*OperationQueryRequest) error + Recv() (*OperationQueryResponse, error) + grpc.ClientStream +} + +type operationQueryClient struct { + grpc.ClientStream +} + +func (x *operationQueryClient) Send(m *OperationQueryRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *operationQueryClient) Recv() (*OperationQueryResponse, error) { + m := new(OperationQueryResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *operationClient) Refresh(ctx context.Context, in *OperationQueryRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/Operation/Refresh", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// OperationServer is the server API for Operation service. +// All implementations must embed UnimplementedOperationServer +// for forward compatibility +type OperationServer interface { + Query(Operation_QueryServer) error + Refresh(context.Context, *OperationQueryRequest) (*Empty, error) + mustEmbedUnimplementedOperationServer() +} + +// UnimplementedOperationServer must be embedded to have forward compatible implementations. +type UnimplementedOperationServer struct { +} + +func (UnimplementedOperationServer) Query(Operation_QueryServer) error { + return status.Errorf(codes.Unimplemented, "method Query not implemented") +} +func (UnimplementedOperationServer) Refresh(context.Context, *OperationQueryRequest) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Refresh not implemented") +} +func (UnimplementedOperationServer) mustEmbedUnimplementedOperationServer() {} + +// UnsafeOperationServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to OperationServer will +// result in compilation errors. +type UnsafeOperationServer interface { + mustEmbedUnimplementedOperationServer() +} + +func RegisterOperationServer(s grpc.ServiceRegistrar, srv OperationServer) { + s.RegisterService(&Operation_ServiceDesc, srv) +} + +func _Operation_Query_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(OperationServer).Query(&operationQueryServer{stream}) +} + +type Operation_QueryServer interface { + Send(*OperationQueryResponse) error + Recv() (*OperationQueryRequest, error) + grpc.ServerStream +} + +type operationQueryServer struct { + grpc.ServerStream +} + +func (x *operationQueryServer) Send(m *OperationQueryResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *operationQueryServer) Recv() (*OperationQueryRequest, error) { + m := new(OperationQueryRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Operation_Refresh_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OperationQueryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OperationServer).Refresh(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Operation/Refresh", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OperationServer).Refresh(ctx, req.(*OperationQueryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Operation_ServiceDesc is the grpc.ServiceDesc for Operation service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Operation_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "Operation", + HandlerType: (*OperationServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Refresh", + Handler: _Operation_Refresh_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Query", + Handler: _Operation_Query_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "protos/operation.proto", +}