github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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 ModePID: req.DefaultPidMode, 39 ModeIPC: req.DefaultIpcMode, 40 }) 41 42 if err != nil { 43 return nil, err 44 } 45 46 process, err := processStateToProto(ps) 47 if err != nil { 48 return nil, err 49 } 50 51 return &proto.LaunchResponse{ 52 Process: process, 53 }, nil 54 } 55 56 func (s *grpcExecutorServer) Wait(ctx context.Context, req *proto.WaitRequest) (*proto.WaitResponse, error) { 57 ps, err := s.impl.Wait(ctx) 58 if err != nil { 59 return nil, err 60 } 61 62 process, err := processStateToProto(ps) 63 if err != nil { 64 return nil, err 65 } 66 67 return &proto.WaitResponse{ 68 Process: process, 69 }, nil 70 } 71 72 func (s *grpcExecutorServer) Shutdown(ctx context.Context, req *proto.ShutdownRequest) (*proto.ShutdownResponse, error) { 73 if err := s.impl.Shutdown(req.Signal, time.Duration(req.GracePeriod)); err != nil { 74 return nil, err 75 } 76 77 return &proto.ShutdownResponse{}, nil 78 } 79 80 func (s *grpcExecutorServer) UpdateResources(ctx context.Context, req *proto.UpdateResourcesRequest) (*proto.UpdateResourcesResponse, error) { 81 if err := s.impl.UpdateResources(drivers.ResourcesFromProto(req.Resources)); err != nil { 82 return nil, err 83 } 84 85 return &proto.UpdateResourcesResponse{}, nil 86 } 87 88 func (s *grpcExecutorServer) Version(context.Context, *proto.VersionRequest) (*proto.VersionResponse, error) { 89 v, err := s.impl.Version() 90 if err != nil { 91 return nil, err 92 } 93 94 return &proto.VersionResponse{ 95 Version: v.Version, 96 }, nil 97 } 98 99 func (s *grpcExecutorServer) Stats(req *proto.StatsRequest, stream proto.Executor_StatsServer) error { 100 interval := time.Duration(req.Interval) 101 if interval == 0 { 102 interval = time.Second 103 } 104 105 outCh, err := s.impl.Stats(stream.Context(), interval) 106 if err != nil { 107 if rec, ok := err.(structs.Recoverable); ok { 108 st := status.New(codes.FailedPrecondition, rec.Error()) 109 st, err := st.WithDetails(&sproto.RecoverableError{Recoverable: rec.IsRecoverable()}) 110 if err != nil { 111 // If this error, it will always error 112 panic(err) 113 } 114 return st.Err() 115 } 116 return err 117 } 118 119 for resp := range outCh { 120 pbStats, err := drivers.TaskStatsToProto(resp) 121 if err != nil { 122 return err 123 } 124 125 presp := &proto.StatsResponse{ 126 Stats: pbStats, 127 } 128 129 // Send the stats 130 if err := stream.Send(presp); err != nil { 131 return err 132 } 133 } 134 135 return nil 136 } 137 138 func (s *grpcExecutorServer) Signal(ctx context.Context, req *proto.SignalRequest) (*proto.SignalResponse, error) { 139 sig := syscall.Signal(req.Signal) 140 if err := s.impl.Signal(sig); err != nil { 141 return nil, err 142 } 143 return &proto.SignalResponse{}, nil 144 } 145 146 func (s *grpcExecutorServer) Exec(ctx context.Context, req *proto.ExecRequest) (*proto.ExecResponse, error) { 147 deadline, err := ptypes.Timestamp(req.Deadline) 148 if err != nil { 149 return nil, err 150 } 151 152 out, exit, err := s.impl.Exec(deadline, req.Cmd, req.Args) 153 if err != nil { 154 return nil, err 155 } 156 157 return &proto.ExecResponse{ 158 Output: out, 159 ExitCode: int32(exit), 160 }, nil 161 } 162 163 func (s *grpcExecutorServer) ExecStreaming(server proto.Executor_ExecStreamingServer) error { 164 msg, err := server.Recv() 165 if err != nil { 166 return fmt.Errorf("failed to receive initial message: %v", err) 167 } 168 169 if msg.Setup == nil { 170 return fmt.Errorf("first message should always be setup") 171 } 172 173 return s.impl.ExecStreaming(server.Context(), 174 msg.Setup.Command, msg.Setup.Tty, 175 server) 176 }