mirror of
https://github.com/containerd/containerd.git
synced 2026-11-06 13:27:16 +00:00
160 lines
4.5 KiB
Go
160 lines
4.5 KiB
Go
/*
|
|
Copyright The containerd Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package v2
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
bootapi "github.com/containerd/containerd/api/runtime/bootstrap/v1"
|
|
"github.com/containerd/containerd/v2/pkg/namespaces"
|
|
"github.com/containerd/containerd/v2/pkg/protobuf/proto"
|
|
"github.com/containerd/containerd/v2/pkg/protobuf/types"
|
|
"github.com/containerd/containerd/v2/version"
|
|
"github.com/containerd/log"
|
|
)
|
|
|
|
// Environment variables passed to the shim binary.
|
|
//
|
|
// TODO: Remove in a future release in favor of Bootstrap protocol.
|
|
const (
|
|
ttrpcAddressEnv = "TTRPC_ADDRESS"
|
|
grpcAddressEnv = "GRPC_ADDRESS"
|
|
namespaceEnv = "NAMESPACE"
|
|
maxVersionEnv = "MAX_SHIM_VERSION"
|
|
)
|
|
|
|
type commandConfig struct {
|
|
ID string
|
|
RuntimePath string
|
|
BundlePath string
|
|
GRPCAddress string
|
|
TTRPCAddress string
|
|
WorkDir string
|
|
Args []string
|
|
Opts *types.Any
|
|
Env []string
|
|
LogLevel log.Level
|
|
Action string // Either "start" or "delete"
|
|
SocketDir string
|
|
}
|
|
|
|
// command returns the shim command with the provided args and configuration.
|
|
//
|
|
// It is used to invoke the shim binary for "start" and "delete" actions during the
|
|
// shim lifecycle, and encodes launch internals: backwards compatibility with older
|
|
// shim models and the new Bootstrap protocol used by 2.3+ shims.
|
|
func command(ctx context.Context, config *commandConfig) (*exec.Cmd, error) {
|
|
ns, err := namespaces.NamespaceRequired(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
self, err := os.Executable()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// TODO: Remove in a future release in favor of Bootstrap protocol.
|
|
args := []string{
|
|
"-namespace", ns,
|
|
"-address", config.GRPCAddress,
|
|
"-publish-binary", self,
|
|
"-id", config.ID,
|
|
}
|
|
if config.BundlePath != "" {
|
|
args = append(args, "-bundle", config.BundlePath)
|
|
}
|
|
switch config.LogLevel {
|
|
case log.DebugLevel, log.TraceLevel:
|
|
args = append(args, "-debug")
|
|
}
|
|
if config.Action == "" {
|
|
return nil, errors.New("action must be specified in commandConfig")
|
|
}
|
|
|
|
args = append(args, config.Action)
|
|
|
|
if len(config.Args) > 0 {
|
|
args = append(args, config.Args...)
|
|
}
|
|
|
|
cmd := exec.CommandContext(ctx, config.RuntimePath, args...)
|
|
cmd.Dir = config.WorkDir
|
|
cmd.Env = append(
|
|
os.Environ(),
|
|
"GOMAXPROCS=2",
|
|
fmt.Sprintf("%s=2", maxVersionEnv),
|
|
// TODO: Remove in a future release in favor of Bootstrap protocol.
|
|
fmt.Sprintf("%s=%s", ttrpcAddressEnv, config.TTRPCAddress),
|
|
fmt.Sprintf("%s=%s", grpcAddressEnv, config.GRPCAddress),
|
|
fmt.Sprintf("%s=%s", namespaceEnv, ns),
|
|
)
|
|
if len(config.Env) > 0 {
|
|
cmd.Env = append(cmd.Env, config.Env...)
|
|
}
|
|
cmd.SysProcAttr = getSysProcAttr()
|
|
|
|
// Special path when upgrading from 1.7 shims to 2.x containerd.
|
|
// v1 shims would fail if passed wrong stdin data.
|
|
// TODO: Remove in a future release in favor of Bootstrap protocol.
|
|
execName := filepath.Base(config.RuntimePath)
|
|
if strings.Contains(execName, "shim-runc-v1") || strings.Contains(execName, "shim-runhcs-v1") {
|
|
if config.Opts != nil {
|
|
d, err := proto.Marshal(config.Opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd.Stdin = bytes.NewReader(d)
|
|
}
|
|
} else if config.Action == "start" {
|
|
// Use the new Bootstrap protocol for all newer shims.
|
|
params := bootapi.BootstrapParams{
|
|
InstanceID: config.ID,
|
|
Namespace: ns,
|
|
LogLevel: bootapi.LogLevelFromString(config.LogLevel.String()),
|
|
ContainerdVersion: version.Version,
|
|
ContainerdGrpcAddress: config.GRPCAddress,
|
|
ContainerdTtrpcAddress: config.TTRPCAddress,
|
|
ContainerdBinary: self,
|
|
}
|
|
if config.SocketDir != "" {
|
|
params.SocketDir = &config.SocketDir
|
|
}
|
|
|
|
if config.Opts != nil {
|
|
if err := params.AddExtension(config.Opts); err != nil {
|
|
return nil, fmt.Errorf("unable to add runtime options extensions: %w", err)
|
|
}
|
|
}
|
|
|
|
data, err := proto.Marshal(¶ms)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to marshal bootstrap params: %w", err)
|
|
}
|
|
|
|
cmd.Stdin = bytes.NewReader(data)
|
|
}
|
|
|
|
return cmd, nil
|
|
}
|