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  }