mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-26 18:44:47 +01:00
It'll be much clear to unmarshal Protobuf.Any using UnmarshalAny(). Fixes: #1130 Signed-off-by: fupan <lifupan@gmail.com>
136 lines
2.7 KiB
Go
136 lines
2.7 KiB
Go
// Copyright (c) 2018 HyperHQ Inc.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package containerdshim
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/containerd/containerd/api/types/task"
|
|
"github.com/containerd/containerd/errdefs"
|
|
"github.com/containerd/typeurl"
|
|
googleProtobuf "github.com/gogo/protobuf/types"
|
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
type exec struct {
|
|
container *container
|
|
cmds *types.Cmd
|
|
tty *tty
|
|
ttyio *ttyIO
|
|
id string
|
|
|
|
exitCode int32
|
|
|
|
status task.Status
|
|
|
|
exitIOch chan struct{}
|
|
exitCh chan uint32
|
|
|
|
exitTime time.Time
|
|
}
|
|
|
|
type tty struct {
|
|
stdin string
|
|
stdout string
|
|
stderr string
|
|
height uint32
|
|
width uint32
|
|
terminal bool
|
|
}
|
|
|
|
func getEnvs(envs []string) []types.EnvVar {
|
|
var vcEnvs = []types.EnvVar{}
|
|
var env types.EnvVar
|
|
|
|
for _, v := range envs {
|
|
pair := strings.SplitN(v, "=", 2)
|
|
|
|
if len(pair) == 2 {
|
|
env = types.EnvVar{Var: pair[0], Value: pair[1]}
|
|
} else if len(pair) == 1 {
|
|
env = types.EnvVar{Var: pair[0], Value: ""}
|
|
}
|
|
|
|
vcEnvs = append(vcEnvs, env)
|
|
}
|
|
|
|
return vcEnvs
|
|
}
|
|
|
|
func newExec(c *container, stdin, stdout, stderr string, terminal bool, jspec *googleProtobuf.Any) (*exec, error) {
|
|
var height uint32
|
|
var width uint32
|
|
|
|
if jspec == nil {
|
|
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "googleProtobuf.Any points to nil")
|
|
}
|
|
|
|
// process exec request
|
|
var spec *specs.Process
|
|
v, err := typeurl.UnmarshalAny(jspec)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
spec, ok := v.(*specs.Process)
|
|
if !ok {
|
|
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "Get an invalid spec type")
|
|
}
|
|
|
|
if spec.ConsoleSize != nil {
|
|
height = uint32(spec.ConsoleSize.Height)
|
|
width = uint32(spec.ConsoleSize.Width)
|
|
}
|
|
|
|
tty := &tty{
|
|
stdin: stdin,
|
|
stdout: stdout,
|
|
stderr: stderr,
|
|
height: height,
|
|
width: width,
|
|
terminal: terminal,
|
|
}
|
|
|
|
cmds := &types.Cmd{
|
|
Args: spec.Args,
|
|
Envs: getEnvs(spec.Env),
|
|
User: fmt.Sprintf("%d", spec.User.UID),
|
|
PrimaryGroup: fmt.Sprintf("%d", spec.User.GID),
|
|
WorkDir: spec.Cwd,
|
|
Interactive: terminal,
|
|
Detach: !terminal,
|
|
NoNewPrivileges: spec.NoNewPrivileges,
|
|
}
|
|
|
|
exec := &exec{
|
|
container: c,
|
|
cmds: cmds,
|
|
tty: tty,
|
|
exitCode: exitCode255,
|
|
exitIOch: make(chan struct{}),
|
|
exitCh: make(chan uint32, 1),
|
|
status: task.StatusCreated,
|
|
}
|
|
|
|
return exec, nil
|
|
}
|
|
|
|
func (c *container) getExec(id string) (*exec, error) {
|
|
if c.execs == nil {
|
|
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "exec does not exist %s", id)
|
|
}
|
|
|
|
exec := c.execs[id]
|
|
|
|
if exec == nil {
|
|
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "exec does not exist %s", id)
|
|
}
|
|
|
|
return exec, nil
|
|
}
|