216 lines
4.4 KiB
Go
216 lines
4.4 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"sync/atomic"
|
|
|
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
"repositories.action2quare.com/ayo/houston/client"
|
|
"repositories.action2quare.com/ayo/houston/shared"
|
|
"repositories.action2quare.com/ayo/houston/shared/protos"
|
|
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// protoc --go_out=. --go-grpc_out=. protos/*.proto
|
|
type HoustonServer interface {
|
|
Start() error
|
|
Stop()
|
|
Operation() Operation
|
|
}
|
|
|
|
type serverConfig struct {
|
|
GrpcPort int `json:"grpc_port"`
|
|
StorageRoot string `json:"storage_path"`
|
|
RunAsClient bool `json:"run_as_client"`
|
|
}
|
|
|
|
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 MakeStopProcessRequest(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 loadServerConfig() serverConfig {
|
|
configFile, err := os.Open("config.json")
|
|
if err != nil {
|
|
logger.Println(err)
|
|
return serverConfig{
|
|
GrpcPort: 8080,
|
|
}
|
|
}
|
|
defer configFile.Close()
|
|
|
|
var config struct {
|
|
Houston *struct {
|
|
Server serverConfig `json:"server"`
|
|
} `json:"houston"`
|
|
}
|
|
|
|
dec := json.NewDecoder(configFile)
|
|
err = dec.Decode(&config)
|
|
if err != nil {
|
|
logger.Println(err)
|
|
return serverConfig{
|
|
GrpcPort: 8080,
|
|
}
|
|
}
|
|
|
|
if config.Houston == nil {
|
|
logger.Println(`"houston" object is missing in config.json`)
|
|
return serverConfig{
|
|
GrpcPort: 8080,
|
|
}
|
|
}
|
|
|
|
return config.Houston.Server
|
|
}
|
|
|
|
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,
|
|
port: loadServerConfig().GrpcPort,
|
|
}
|
|
}
|
|
|
|
type houstonServer struct {
|
|
rpcServer *grpc.Server
|
|
os *operationServer
|
|
ms *monitorServer
|
|
port int
|
|
}
|
|
|
|
func (hs *houstonServer) Start() error {
|
|
logger.Println("houston server is started at port", hs.port)
|
|
lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", hs.port))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
closeCount := int32(0)
|
|
var hc client.HoustonClient
|
|
if loadServerConfig().RunAsClient {
|
|
hc, err = client.NewClient(false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
hc.Start()
|
|
logger.Println("houstonClient is finished")
|
|
if atomic.AddInt32(&closeCount, 1) == 1 {
|
|
logger.Println("try stop houstonServer")
|
|
hs.Stop()
|
|
}
|
|
}()
|
|
}
|
|
|
|
err = hs.rpcServer.Serve(lis)
|
|
if atomic.AddInt32(&closeCount, 1) == 1 {
|
|
if hc != nil {
|
|
logger.Println("try stop houstonClient")
|
|
hc.Shutdown()
|
|
}
|
|
}
|
|
logger.Println("houstonServer is finished")
|
|
|
|
return err
|
|
}
|
|
|
|
func (hs *houstonServer) Stop() {
|
|
hs.rpcServer.GracefulStop()
|
|
}
|
|
|
|
func (hs *houstonServer) Operation() Operation {
|
|
return hs.os
|
|
}
|