Add exec functionality to shim
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
		
							
								
								
									
										1264
									
								
								api/shim/shim.pb.go
									
									
									
									
									
								
							
							
						
						
									
										1264
									
								
								api/shim/shim.pb.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -5,7 +5,7 @@ package containerd.v1; | ||||
| import "google/protobuf/empty.proto"; | ||||
| import "gogoproto/gogo.proto"; | ||||
|  | ||||
| service ShimService { | ||||
| service Shim { | ||||
|     rpc Create(CreateRequest) returns (CreateResponse); | ||||
|     rpc Start(StartRequest) returns (google.protobuf.Empty); | ||||
|     rpc Delete(DeleteRequest) returns (DeleteResponse); | ||||
| @@ -14,7 +14,7 @@ service ShimService { | ||||
| } | ||||
|  | ||||
| message CreateRequest { | ||||
| 	string id = 1 [(gogoproto.customname) = "ID"]; | ||||
|     string id = 1 [(gogoproto.customname) = "ID"]; | ||||
|     string bundle = 2; | ||||
|     string runtime = 3; | ||||
|     bool no_pivot = 4; | ||||
| @@ -40,7 +40,32 @@ message DeleteResponse { | ||||
| } | ||||
|  | ||||
| message ExecRequest { | ||||
|     string id = 1 [(gogoproto.customname) = "ID"]; | ||||
|     bool terminal = 2; | ||||
|     string stdin = 3; | ||||
|     string stdout = 4; | ||||
|     string stderr = 5; | ||||
|     User user = 6; | ||||
|     repeated string args = 7; | ||||
|     repeated string env = 8; | ||||
|     string cwd = 9; | ||||
|     repeated string capabilities = 10; | ||||
|     repeated Rlimit rlimits = 11; | ||||
|     bool no_new_privileges = 12; | ||||
|     string apparmor_profile = 13; | ||||
|     string selinux_label = 14; | ||||
| } | ||||
|  | ||||
| message User { | ||||
|     uint32 uid = 1; | ||||
|     uint32 gid = 2; | ||||
|     repeated uint32 additional_gids = 3; | ||||
| } | ||||
|  | ||||
| message Rlimit { | ||||
|     string type = 1; | ||||
|     uint64 hard = 2; | ||||
|     uint64 soft = 3; | ||||
| } | ||||
|  | ||||
| message ExecResponse { | ||||
| @@ -49,6 +74,6 @@ message ExecResponse { | ||||
|  | ||||
| message PtyRequest { | ||||
|     uint32 pid = 1; | ||||
| 	uint32 width = 2; | ||||
| 	uint32 height = 3; | ||||
|     uint32 width = 2; | ||||
|     uint32 height = 3; | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,127 @@ | ||||
| package main | ||||
|  | ||||
| func newExecProcess(id, bundle, runtimeName string) (process, error) { | ||||
| 	return nil, nil | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"sync" | ||||
|  | ||||
| 	runc "github.com/crosbymichael/go-runc" | ||||
| 	"github.com/docker/containerd/api/shim" | ||||
| 	specs "github.com/opencontainers/runtime-spec/specs-go" | ||||
| ) | ||||
|  | ||||
| type execProcess struct { | ||||
| 	sync.WaitGroup | ||||
|  | ||||
| 	id      string | ||||
| 	console *runc.Console | ||||
| 	io      runc.IO | ||||
| 	status  int | ||||
| 	pid     int | ||||
|  | ||||
| 	parent *initProcess | ||||
| } | ||||
|  | ||||
| func newExecProcess(context context.Context, r *shim.ExecRequest, parent *initProcess) (process, error) { | ||||
| 	cwd, err := os.Getwd() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	e := &execProcess{ | ||||
| 		id:     r.ID, | ||||
| 		parent: parent, | ||||
| 	} | ||||
| 	var ( | ||||
| 		socket  *runc.ConsoleSocket | ||||
| 		io      runc.IO | ||||
| 		pidfile = filepath.Join(cwd, fmt.Sprintf("%s.pid", r.ID)) | ||||
| 	) | ||||
| 	if r.Terminal { | ||||
| 		if socket, err = runc.NewConsoleSocket(filepath.Join(cwd, "pty.sock")); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else { | ||||
| 		// TODO: get uid/gid | ||||
| 		if io, err = runc.NewPipeIO(0, 0); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		e.io = io | ||||
| 	} | ||||
| 	opts := &runc.ExecOpts{ | ||||
| 		PidFile:       pidfile, | ||||
| 		ConsoleSocket: socket, | ||||
| 		IO:            io, | ||||
| 		Detach:        true, | ||||
| 		Tty:           socket != nil, | ||||
| 	} | ||||
| 	if err := parent.runc.Exec(context, r.ID, processFromRequest(r), opts); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	pid, err := runc.ReadPidFile(opts.PidFile) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	e.pid = pid | ||||
| 	return e, nil | ||||
| } | ||||
|  | ||||
| func processFromRequest(r *shim.ExecRequest) specs.Process { | ||||
| 	return specs.Process{ | ||||
| 		Terminal: r.Terminal, | ||||
| 		User: specs.User{ | ||||
| 			UID:            r.User.Uid, | ||||
| 			GID:            r.User.Gid, | ||||
| 			AdditionalGids: r.User.AdditionalGids, | ||||
| 		}, | ||||
| 		Rlimits:         rlimits(r.Rlimits), | ||||
| 		Args:            r.Args, | ||||
| 		Env:             r.Env, | ||||
| 		Cwd:             r.Cwd, | ||||
| 		Capabilities:    r.Capabilities, | ||||
| 		NoNewPrivileges: r.NoNewPrivileges, | ||||
| 		ApparmorProfile: r.ApparmorProfile, | ||||
| 		SelinuxLabel:    r.SelinuxLabel, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func rlimits(rr []*shim.Rlimit) (o []specs.LinuxRlimit) { | ||||
| 	for _, r := range rr { | ||||
| 		o = append(o, specs.LinuxRlimit{ | ||||
| 			Type: r.Type, | ||||
| 			Hard: r.Hard, | ||||
| 			Soft: r.Soft, | ||||
| 		}) | ||||
| 	} | ||||
| 	return o | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Pid() int { | ||||
| 	return e.pid | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Status() int { | ||||
| 	return e.status | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Exited(status int) { | ||||
| 	e.status = status | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Start(_ context.Context) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Delete(context context.Context) error { | ||||
| 	e.Wait() | ||||
| 	e.io.Close() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (e *execProcess) Resize(ws runc.WinSize) error { | ||||
| 	if e.console == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return e.console.Resize(ws) | ||||
| } | ||||
|   | ||||
| @@ -52,9 +52,10 @@ func newInitProcess(context context.Context, r *shim.CreateRequest) (process, er | ||||
| 		if io, err = runc.NewPipeIO(0, 0); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		p.io = io | ||||
| 	} | ||||
| 	opts := &runc.CreateOpts{ | ||||
| 		PidFile:       filepath.Join(cwd, "pid"), | ||||
| 		PidFile:       filepath.Join(cwd, "init.pid"), | ||||
| 		ConsoleSocket: socket, | ||||
| 		IO:            io, | ||||
| 		NoPivot:       r.NoPivot, | ||||
|   | ||||
| @@ -56,7 +56,7 @@ func main() { | ||||
| 				processes: make(map[int]process), | ||||
| 			} | ||||
| 		) | ||||
| 		shim.RegisterShimServiceServer(server, sv) | ||||
| 		shim.RegisterShimServer(server, sv) | ||||
| 		l, err := utils.CreateUnixSocket("shim.sock") | ||||
| 		if err != nil { | ||||
| 			return err | ||||
|   | ||||
| @@ -62,7 +62,17 @@ func (s *service) Delete(ctx context.Context, r *shim.DeleteRequest) (*shim.Dele | ||||
| } | ||||
|  | ||||
| func (s *service) Exec(ctx context.Context, r *shim.ExecRequest) (*shim.ExecResponse, error) { | ||||
| 	return nil, nil | ||||
| 	s.mu.Lock() | ||||
| 	defer s.mu.Unlock() | ||||
| 	process, err := newExecProcess(ctx, r, s.processes[s.initPid].(*initProcess)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	pid := process.Pid() | ||||
| 	s.processes[pid] = process | ||||
| 	return &shim.ExecResponse{ | ||||
| 		Pid: uint32(pid), | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (s *service) Pty(ctx context.Context, r *shim.PtyRequest) (*google_protobuf.Empty, error) { | ||||
|   | ||||
| @@ -104,7 +104,7 @@ var shimDeleteCommand = cli.Command{ | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| func getShimService() (shim.ShimServiceClient, error) { | ||||
| func getShimService() (shim.ShimClient, error) { | ||||
| 	bindSocket := "shim.sock" | ||||
|  | ||||
| 	// reset the logger for grpc to log to dev/null so that it does not mess with our stdio | ||||
| @@ -119,6 +119,6 @@ func getShimService() (shim.ShimServiceClient, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return shim.NewShimServiceClient(conn), nil | ||||
| 	return shim.NewShimClient(conn), nil | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Crosby
					Michael Crosby