github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/drivers/shared/executor/server.go (about) 1 package executor 2 3 import ( 4 "fmt" 5 "syscall" 6 "time" 7 8 "github.com/golang/protobuf/ptypes" 9 "github.com/hashicorp/nomad/drivers/shared/executor/proto" 10 "github.com/hashicorp/nomad/nomad/structs" 11 "github.com/hashicorp/nomad/plugins/drivers" 12 sproto "github.com/hashicorp/nomad/plugins/shared/structs/proto" 13 "golang.org/x/net/context" 14 "google.golang.org/grpc/codes" 15 "google.golang.org/grpc/status" 16 ) 17 18 type grpcExecutorServer struct { 19 impl Executor 20 } 21 22 func (s *grpcExecutorServer) Launch(ctx context.Context, req *proto.LaunchRequest) (*proto.LaunchResponse, error) { 23 ps, err := s.impl.Launch(&ExecCommand{ 24 Cmd: req.Cmd, 25 Args: req.Args, 26 Resources: drivers.ResourcesFromProto(req.Resources), 27 StdoutPath: req.StdoutPath, 28 StderrPath: req.StderrPath, 29 Env: req.Env, 30 User: req.User, 31 TaskDir: req.TaskDir, 32 ResourceLimits: req.ResourceLimits, 33 BasicProcessCgroup: req.BasicProcessCgroup, 34 NoPivotRoot: req.NoPivotRoot, 35 Mounts: drivers.MountsFromProto(req.Mounts), 36 Devices: drivers.DevicesFromProto(req.Devices), 37 NetworkIsolation: drivers.NetworkIsolationSpecFromProto(req.NetworkIsolation), 38 }) 39 40 if err != nil { 41 return nil, err 42 } 43 44 process, err := processStateToProto(ps) 45 if err != nil { 46 return nil, err 47 } 48 49 return &proto.LaunchResponse{ 50 Process: process, 51 }, nil 52 } 53 54 func (s *grpcExecutorServer) Wait(ctx context.Context, req *proto.WaitRequest) (*proto.WaitResponse, error) { 55 ps, err := s.impl.Wait(ctx) 56 if err != nil { 57 return nil, err 58 } 59 60 process, err := processStateToProto(ps) 61 if err != nil { 62 return nil, err 63 } 64 65 return &proto.WaitResponse{ 66 Process: process, 67 }, nil 68 } 69 70 func (s *grpcExecutorServer) Shutdown(ctx context.Context, req *proto.ShutdownRequest) (*proto.ShutdownResponse, error) { 71 if err := s.impl.Shutdown(req.Signal, time.Duration(req.GracePeriod)); err != nil { 72 return nil, err 73 } 74 75 return &proto.ShutdownResponse{}, nil 76 } 77 78 func (s *grpcExecutorServer) UpdateResources(ctx context.Context, req *proto.UpdateResourcesRequest) (*proto.UpdateResourcesResponse, error) { 79 if err := s.impl.UpdateResources(drivers.ResourcesFromProto(req.Resources)); err != nil { 80 return nil, err 81 } 82 83 return &proto.UpdateResourcesResponse{}, nil 84 } 85 86 func (s *grpcExecutorServer) Version(context.Context, *proto.VersionRequest) (*proto.VersionResponse, error) { 87 v, err := s.impl.Version() 88 if err != nil { 89 return nil, err 90 } 91 92 return &proto.VersionResponse{ 93 Version: v.Version, 94 }, nil 95 } 96 97 func (s *grpcExecutorServer) Stats(req *proto.StatsRequest, stream proto.Executor_StatsServer) error { 98 interval := time.Duration(req.Interval) 99 if interval == 0 { 100 interval = time.Second 101 } 102 103 outCh, err := s.impl.Stats(stream.Context(), interval) 104 if err != nil { 105 if rec, ok := err.(structs.Recoverable); ok { 106 st := status.New(codes.FailedPrecondition, rec.Error()) 107 st, err := st.WithDetails(&sproto.RecoverableError{Recoverable: rec.IsRecoverable()}) 108 if err != nil { 109 // If this error, it will always error 110 panic(err) 111 } 112 return st.Err() 113 } 114 return err 115 } 116 117 for resp := range outCh { 118 pbStats, err := drivers.TaskStatsToProto(resp) 119 if err != nil { 120 return err 121 } 122 123 presp := &proto.StatsResponse{ 124 Stats: pbStats, 125 } 126 127 // Send the stats 128 if err := stream.Send(presp); err != nil { 129 return err 130 } 131 } 132 133 return nil 134 } 135 136 func (s *grpcExecutorServer) Signal(ctx context.Context, req *proto.SignalRequest) (*proto.SignalResponse, error) { 137 sig := syscall.Signal(req.Signal) 138 if err := s.impl.Signal(sig); err != nil { 139 return nil, err 140 } 141 return &proto.SignalResponse{}, nil 142 } 143 144 func (s *grpcExecutorServer) Exec(ctx context.Context, req *proto.ExecRequest) (*proto.ExecResponse, error) { 145 deadline, err := ptypes.Timestamp(req.Deadline) 146 if err != nil { 147 return nil, err 148 } 149 150 out, exit, err := s.impl.Exec(deadline, req.Cmd, req.Args) 151 if err != nil { 152 return nil, err 153 } 154 155 return &proto.ExecResponse{ 156 Output: out, 157 ExitCode: int32(exit), 158 }, nil 159 } 160 161 func (s *grpcExecutorServer) ExecStreaming(server proto.Executor_ExecStreamingServer) error { 162 msg, err := server.Recv() 163 if err != nil { 164 return fmt.Errorf("failed to receive initial message: %v", err) 165 } 166 167 if msg.Setup == nil { 168 return fmt.Errorf("first message should always be setup") 169 } 170 171 return s.impl.ExecStreaming(server.Context(), 172 msg.Setup.Command, msg.Setup.Tty, 173 server) 174 }