mirror of
https://github.com/kemko/nomad.git
synced 2026-01-03 17:05:43 +03:00
executor: use grpc instead of netrpc as plugin protocol
* Added protobuf spec for executor * Seperated executor structs into their own package
This commit is contained in:
145
plugins/executor/client.go
Normal file
145
plugins/executor/client.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/LK4D4/joincontext"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
cstructs "github.com/hashicorp/nomad/client/structs"
|
||||
"github.com/hashicorp/nomad/drivers/shared/executor/structs"
|
||||
"github.com/hashicorp/nomad/plugins/drivers"
|
||||
"github.com/hashicorp/nomad/plugins/executor/proto"
|
||||
)
|
||||
|
||||
var _ structs.Executor = (*grpcExecutorClient)(nil)
|
||||
|
||||
type grpcExecutorClient struct {
|
||||
client proto.ExecutorClient
|
||||
|
||||
// doneCtx is close when the plugin exits
|
||||
doneCtx context.Context
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Launch(cmd *structs.ExecCommand) (*structs.ProcessState, error) {
|
||||
ctx := context.Background()
|
||||
req := &proto.LaunchRequest{
|
||||
Cmd: cmd.Cmd,
|
||||
Args: cmd.Args,
|
||||
Resources: resourcesToProto(cmd.Resources),
|
||||
StdoutPath: cmd.StdoutPath,
|
||||
StderrPath: cmd.StderrPath,
|
||||
Env: cmd.Env,
|
||||
User: cmd.User,
|
||||
TaskDir: cmd.TaskDir,
|
||||
ResourceLimits: cmd.ResourceLimits,
|
||||
BasicProcessCgroup: cmd.BasicProcessCgroup,
|
||||
}
|
||||
resp, err := c.client.Launch(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ps, err := processStateFromProto(resp.Process)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Wait(ctx context.Context) (*structs.ProcessState, error) {
|
||||
// Join the passed context and the shutdown context
|
||||
ctx, _ = joincontext.Join(ctx, c.doneCtx)
|
||||
|
||||
resp, err := c.client.Wait(ctx, &proto.WaitRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ps, err := processStateFromProto(resp.Process)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Shutdown(signal string, gracePeriod time.Duration) error {
|
||||
ctx := context.Background()
|
||||
req := &proto.ShutdownRequest{
|
||||
Signal: signal,
|
||||
GracePeriod: gracePeriod.Nanoseconds(),
|
||||
}
|
||||
if _, err := c.client.Shutdown(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) UpdateResources(r *structs.Resources) error {
|
||||
ctx := context.Background()
|
||||
req := &proto.UpdateResourcesRequest{Resources: resourcesToProto(r)}
|
||||
if _, err := c.client.UpdateResources(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Version() (*structs.ExecutorVersion, error) {
|
||||
ctx := context.Background()
|
||||
resp, err := c.client.Version(ctx, &proto.VersionRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &structs.ExecutorVersion{Version: resp.Version}, nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Stats() (*cstructs.TaskResourceUsage, error) {
|
||||
ctx := context.Background()
|
||||
resp, err := c.client.Stats(ctx, &proto.StatsRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats, err := drivers.TaskStatsFromProto(resp.Stats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return stats, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Signal(s os.Signal) error {
|
||||
ctx := context.Background()
|
||||
req := &proto.SignalRequest{
|
||||
Signal: s.String(),
|
||||
}
|
||||
if _, err := c.client.Signal(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *grpcExecutorClient) Exec(deadline time.Time, cmd string, args []string) ([]byte, int, error) {
|
||||
ctx := context.Background()
|
||||
pbDeadline, err := ptypes.TimestampProto(deadline)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
req := &proto.ExecRequest{
|
||||
Deadline: pbDeadline,
|
||||
Cmd: cmd,
|
||||
Args: args,
|
||||
}
|
||||
|
||||
resp, err := c.client.Exec(ctx, req)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return resp.Output, int(resp.ExitCode), nil
|
||||
}
|
||||
@@ -1,185 +1,34 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"net/rpc"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"context"
|
||||
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-plugin"
|
||||
cstructs "github.com/hashicorp/nomad/client/structs"
|
||||
"github.com/hashicorp/nomad/drivers/shared/executor"
|
||||
"github.com/hashicorp/nomad/plugins/executor/proto"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Registering these types since we have to serialize and de-serialize the Task
|
||||
// structs over the wire between drivers and the executor.
|
||||
func init() {
|
||||
gob.Register([]interface{}{})
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]map[string]string{})
|
||||
gob.Register([]map[string]int{})
|
||||
gob.Register(syscall.Signal(0x1))
|
||||
}
|
||||
|
||||
type ExecutorRPC struct {
|
||||
client *rpc.Client
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
// LaunchCmdArgs wraps a user command and the args for the purposes of RPC
|
||||
type LaunchArgs struct {
|
||||
Cmd *executor.ExecCommand
|
||||
}
|
||||
|
||||
// ShutdownArgs wraps shutdown signal and grace period
|
||||
type ShutdownArgs struct {
|
||||
Signal string
|
||||
GracePeriod time.Duration
|
||||
}
|
||||
|
||||
type ExecArgs struct {
|
||||
Deadline time.Time
|
||||
Name string
|
||||
Args []string
|
||||
}
|
||||
|
||||
type ExecReturn struct {
|
||||
Output []byte
|
||||
Code int
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Launch(cmd *executor.ExecCommand) (*executor.ProcessState, error) {
|
||||
var ps *executor.ProcessState
|
||||
err := e.client.Call("Plugin.Launch", LaunchArgs{Cmd: cmd}, &ps)
|
||||
return ps, err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Wait() (*executor.ProcessState, error) {
|
||||
var ps executor.ProcessState
|
||||
err := e.client.Call("Plugin.Wait", new(interface{}), &ps)
|
||||
return &ps, err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Kill() error {
|
||||
return e.client.Call("Plugin.Kill", new(interface{}), new(interface{}))
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Shutdown(signal string, grace time.Duration) error {
|
||||
return e.client.Call("Plugin.Shutdown", &ShutdownArgs{signal, grace}, new(interface{}))
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) UpdateResources(resources *executor.Resources) error {
|
||||
return e.client.Call("Plugin.UpdateResources", resources, new(interface{}))
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Version() (*executor.ExecutorVersion, error) {
|
||||
var version executor.ExecutorVersion
|
||||
err := e.client.Call("Plugin.Version", new(interface{}), &version)
|
||||
return &version, err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Stats() (*cstructs.TaskResourceUsage, error) {
|
||||
var resourceUsage cstructs.TaskResourceUsage
|
||||
err := e.client.Call("Plugin.Stats", new(interface{}), &resourceUsage)
|
||||
return &resourceUsage, err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Signal(s os.Signal) error {
|
||||
return e.client.Call("Plugin.Signal", &s, new(interface{}))
|
||||
}
|
||||
|
||||
func (e *ExecutorRPC) Exec(deadline time.Time, name string, args []string) ([]byte, int, error) {
|
||||
req := ExecArgs{
|
||||
Deadline: deadline,
|
||||
Name: name,
|
||||
Args: args,
|
||||
}
|
||||
var resp *ExecReturn
|
||||
err := e.client.Call("Plugin.Exec", req, &resp)
|
||||
if resp == nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return resp.Output, resp.Code, err
|
||||
}
|
||||
|
||||
type ExecutorRPCServer struct {
|
||||
Impl executor.Executor
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Launch(args LaunchArgs, ps *executor.ProcessState) error {
|
||||
state, err := e.Impl.Launch(args.Cmd)
|
||||
if state != nil {
|
||||
*ps = *state
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Wait(args interface{}, ps *executor.ProcessState) error {
|
||||
state, err := e.Impl.Wait()
|
||||
if state != nil {
|
||||
*ps = *state
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Shutdown(args ShutdownArgs, resp *interface{}) error {
|
||||
return e.Impl.Shutdown(args.Signal, args.GracePeriod)
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) UpdateResources(args *executor.Resources, resp *interface{}) error {
|
||||
return e.Impl.UpdateResources(args)
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Version(args interface{}, version *executor.ExecutorVersion) error {
|
||||
ver, err := e.Impl.Version()
|
||||
if ver != nil {
|
||||
*version = *ver
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Stats(args interface{}, resourceUsage *cstructs.TaskResourceUsage) error {
|
||||
ru, err := e.Impl.Stats()
|
||||
if ru != nil {
|
||||
*resourceUsage = *ru
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Signal(args os.Signal, resp *interface{}) error {
|
||||
return e.Impl.Signal(args)
|
||||
}
|
||||
|
||||
func (e *ExecutorRPCServer) Exec(args ExecArgs, result *ExecReturn) error {
|
||||
out, code, err := e.Impl.Exec(args.Deadline, args.Name, args.Args)
|
||||
ret := &ExecReturn{
|
||||
Output: out,
|
||||
Code: code,
|
||||
}
|
||||
*result = *ret
|
||||
return err
|
||||
}
|
||||
|
||||
type ExecutorPlugin struct {
|
||||
// TODO: support backwards compatability with pre 0.9 NetRPC plugin
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
logger hclog.Logger
|
||||
fsIsolation bool
|
||||
Impl *ExecutorRPCServer
|
||||
}
|
||||
|
||||
func (p *ExecutorPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
|
||||
if p.Impl == nil {
|
||||
if p.fsIsolation {
|
||||
p.Impl = &ExecutorRPCServer{Impl: executor.NewExecutorWithIsolation(p.logger), logger: p.logger}
|
||||
} else {
|
||||
p.Impl = &ExecutorRPCServer{Impl: executor.NewExecutor(p.logger), logger: p.logger}
|
||||
}
|
||||
func (p *ExecutorPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
if p.fsIsolation {
|
||||
proto.RegisterExecutorServer(s, &grpcExecutorServer{impl: executor.NewExecutorWithIsolation(p.logger)})
|
||||
} else {
|
||||
proto.RegisterExecutorServer(s, &grpcExecutorServer{impl: executor.NewExecutor(p.logger)})
|
||||
}
|
||||
return p.Impl, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ExecutorPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
||||
return &ExecutorRPC{client: c, logger: p.logger}, nil
|
||||
func (p *ExecutorPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
return &grpcExecutorClient{
|
||||
client: proto.NewExecutorClient(c),
|
||||
doneCtx: ctx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
1201
plugins/executor/proto/executor.pb.go
Normal file
1201
plugins/executor/proto/executor.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
96
plugins/executor/proto/executor.proto
Normal file
96
plugins/executor/proto/executor.proto
Normal file
@@ -0,0 +1,96 @@
|
||||
syntax = "proto3";
|
||||
package hashicorp.nomad.plugins.executor.proto;
|
||||
option go_package = "proto";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "github.com/hashicorp/nomad/plugins/drivers/proto/driver.proto";
|
||||
|
||||
service Executor {
|
||||
rpc Launch(LaunchRequest) returns (LaunchResponse) {}
|
||||
rpc Wait(WaitRequest) returns (WaitResponse) {}
|
||||
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse) {}
|
||||
rpc UpdateResources(UpdateResourcesRequest) returns (UpdateResourcesResponse) {}
|
||||
rpc Version(VersionRequest) returns (VersionResponse) {}
|
||||
rpc Stats(StatsRequest) returns (StatsResponse) {}
|
||||
rpc Signal(SignalRequest) returns (SignalResponse) {}
|
||||
rpc Exec(ExecRequest) returns (ExecResponse) {}
|
||||
}
|
||||
|
||||
message LaunchRequest {
|
||||
string cmd = 1;
|
||||
repeated string args = 2;
|
||||
Resources resources = 3;
|
||||
string stdout_path = 4;
|
||||
string stderr_path = 5;
|
||||
repeated string env = 6;
|
||||
string user = 7;
|
||||
string task_dir = 8;
|
||||
bool resource_limits = 9;
|
||||
bool basic_process_cgroup = 10;
|
||||
}
|
||||
|
||||
message LaunchResponse {
|
||||
ProcessState process = 1;
|
||||
}
|
||||
|
||||
message WaitRequest {}
|
||||
|
||||
message WaitResponse{
|
||||
ProcessState process = 1;
|
||||
}
|
||||
|
||||
message ShutdownRequest {
|
||||
string signal = 1;
|
||||
int64 grace_period = 2;
|
||||
}
|
||||
|
||||
message ShutdownResponse {}
|
||||
|
||||
message UpdateResourcesRequest{
|
||||
Resources resources = 1;
|
||||
}
|
||||
|
||||
message UpdateResourcesResponse {}
|
||||
|
||||
message VersionRequest {}
|
||||
|
||||
message VersionResponse{
|
||||
string version = 1;
|
||||
}
|
||||
|
||||
message StatsRequest {}
|
||||
|
||||
message StatsResponse {
|
||||
hashicorp.nomad.plugins.drivers.proto.TaskStats stats = 1;
|
||||
}
|
||||
|
||||
message SignalRequest {
|
||||
string signal = 1;
|
||||
}
|
||||
|
||||
message SignalResponse {}
|
||||
|
||||
message ExecRequest {
|
||||
google.protobuf.Timestamp deadline = 1;
|
||||
string cmd = 2;
|
||||
repeated string args = 3;
|
||||
}
|
||||
|
||||
message ExecResponse {
|
||||
bytes output = 1;
|
||||
int32 exit_code = 2;
|
||||
}
|
||||
|
||||
message Resources {
|
||||
int32 cpu = 1;
|
||||
int32 memoryMB = 2;
|
||||
int32 diskMB = 3;
|
||||
int32 iops = 4;
|
||||
}
|
||||
|
||||
message ProcessState {
|
||||
int32 pid = 1;
|
||||
int32 exit_code = 2;
|
||||
int32 signal = 3;
|
||||
google.protobuf.Timestamp time = 4;
|
||||
}
|
||||
132
plugins/executor/server.go
Normal file
132
plugins/executor/server.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/hashicorp/consul-template/signals"
|
||||
"github.com/hashicorp/nomad/drivers/shared/executor/structs"
|
||||
"github.com/hashicorp/nomad/plugins/drivers"
|
||||
"github.com/hashicorp/nomad/plugins/executor/proto"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type grpcExecutorServer struct {
|
||||
impl structs.Executor
|
||||
doneCtx context.Context
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Launch(ctx context.Context, req *proto.LaunchRequest) (*proto.LaunchResponse, error) {
|
||||
ps, err := s.impl.Launch(&structs.ExecCommand{
|
||||
Cmd: req.Cmd,
|
||||
Args: req.Args,
|
||||
Resources: resourcesFromProto(req.Resources),
|
||||
StdoutPath: req.StdoutPath,
|
||||
StderrPath: req.StderrPath,
|
||||
Env: req.Env,
|
||||
User: req.User,
|
||||
TaskDir: req.TaskDir,
|
||||
ResourceLimits: req.ResourceLimits,
|
||||
BasicProcessCgroup: req.BasicProcessCgroup,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
process, err := processStateToProto(ps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.LaunchResponse{
|
||||
Process: process,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Wait(ctx context.Context, req *proto.WaitRequest) (*proto.WaitResponse, error) {
|
||||
ps, err := s.impl.Wait(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
process, err := processStateToProto(ps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.WaitResponse{
|
||||
Process: process,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Shutdown(ctx context.Context, req *proto.ShutdownRequest) (*proto.ShutdownResponse, error) {
|
||||
if err := s.impl.Shutdown(req.Signal, time.Duration(req.GracePeriod)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.ShutdownResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) UpdateResources(ctx context.Context, req *proto.UpdateResourcesRequest) (*proto.UpdateResourcesResponse, error) {
|
||||
if err := s.impl.UpdateResources(resourcesFromProto(req.Resources)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.UpdateResourcesResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Version(context.Context, *proto.VersionRequest) (*proto.VersionResponse, error) {
|
||||
v, err := s.impl.Version()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.VersionResponse{
|
||||
Version: v.Version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Stats(context.Context, *proto.StatsRequest) (*proto.StatsResponse, error) {
|
||||
stats, err := s.impl.Stats()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pbStats, err := drivers.TaskStatsToProto(stats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.StatsResponse{
|
||||
Stats: pbStats,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Signal(ctx context.Context, req *proto.SignalRequest) (*proto.SignalResponse, error) {
|
||||
if sig, ok := signals.SignalLookup[req.Signal]; ok {
|
||||
if err := s.impl.Signal(sig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.SignalResponse{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid signal sent by client")
|
||||
}
|
||||
|
||||
func (s *grpcExecutorServer) Exec(ctx context.Context, req *proto.ExecRequest) (*proto.ExecResponse, error) {
|
||||
deadline, err := ptypes.Timestamp(req.Deadline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out, exit, err := s.impl.Exec(deadline, req.Cmd, req.Args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.ExecResponse{
|
||||
Output: out,
|
||||
ExitCode: int32(exit),
|
||||
}, nil
|
||||
}
|
||||
62
plugins/executor/utils.go
Normal file
62
plugins/executor/utils.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/hashicorp/nomad/drivers/shared/executor/structs"
|
||||
"github.com/hashicorp/nomad/plugins/executor/proto"
|
||||
)
|
||||
|
||||
func processStateToProto(ps *structs.ProcessState) (*proto.ProcessState, error) {
|
||||
timestamp, err := ptypes.TimestampProto(ps.Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pb := &proto.ProcessState{
|
||||
Pid: int32(ps.Pid),
|
||||
ExitCode: int32(ps.ExitCode),
|
||||
Signal: int32(ps.Signal),
|
||||
Time: timestamp,
|
||||
}
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
||||
func processStateFromProto(pb *proto.ProcessState) (*structs.ProcessState, error) {
|
||||
timestamp, err := ptypes.Timestamp(pb.Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &structs.ProcessState{
|
||||
Pid: int(pb.Pid),
|
||||
ExitCode: int(pb.ExitCode),
|
||||
Signal: int(pb.Signal),
|
||||
Time: timestamp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resourcesToProto(r *structs.Resources) *proto.Resources {
|
||||
if r == nil {
|
||||
return &proto.Resources{}
|
||||
}
|
||||
|
||||
return &proto.Resources{
|
||||
Cpu: int32(r.CPU),
|
||||
MemoryMB: int32(r.MemoryMB),
|
||||
DiskMB: int32(r.DiskMB),
|
||||
Iops: int32(r.IOPS),
|
||||
}
|
||||
}
|
||||
|
||||
func resourcesFromProto(pb *proto.Resources) *structs.Resources {
|
||||
if pb == nil {
|
||||
return &structs.Resources{}
|
||||
}
|
||||
|
||||
return &structs.Resources{
|
||||
CPU: int(pb.Cpu),
|
||||
MemoryMB: int(pb.MemoryMB),
|
||||
DiskMB: int(pb.DiskMB),
|
||||
IOPS: int(pb.Iops),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user