github.com/rumpl/bof@v23.0.0-rc.2+incompatible/daemon/runtime_unix.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package daemon 5 6 import ( 7 "fmt" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 13 v2runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/daemon/config" 16 "github.com/docker/docker/errdefs" 17 "github.com/pkg/errors" 18 "github.com/sirupsen/logrus" 19 ) 20 21 const ( 22 defaultRuntimeName = "runc" 23 24 linuxShimV2 = "io.containerd.runc.v2" 25 ) 26 27 func configureRuntimes(conf *config.Config) { 28 if conf.DefaultRuntime == "" { 29 conf.DefaultRuntime = config.StockRuntimeName 30 } 31 if conf.Runtimes == nil { 32 conf.Runtimes = make(map[string]types.Runtime) 33 } 34 conf.Runtimes[config.LinuxV2RuntimeName] = types.Runtime{Path: defaultRuntimeName, Shim: defaultV2ShimConfig(conf, defaultRuntimeName)} 35 conf.Runtimes[config.StockRuntimeName] = conf.Runtimes[config.LinuxV2RuntimeName] 36 } 37 38 func defaultV2ShimConfig(conf *config.Config, runtimePath string) *types.ShimConfig { 39 return &types.ShimConfig{ 40 Binary: linuxShimV2, 41 Opts: &v2runcoptions.Options{ 42 BinaryName: runtimePath, 43 Root: filepath.Join(conf.ExecRoot, "runtime-"+defaultRuntimeName), 44 SystemdCgroup: UsingSystemd(conf), 45 NoPivotRoot: os.Getenv("DOCKER_RAMDISK") != "", 46 }, 47 } 48 } 49 50 func (daemon *Daemon) loadRuntimes() error { 51 return daemon.initRuntimes(daemon.configStore.Runtimes) 52 } 53 54 func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error) { 55 runtimeDir := filepath.Join(daemon.configStore.Root, "runtimes") 56 // Remove old temp directory if any 57 os.RemoveAll(runtimeDir + "-old") 58 tmpDir, err := os.MkdirTemp(daemon.configStore.Root, "gen-runtimes") 59 if err != nil { 60 return errors.Wrap(err, "failed to get temp dir to generate runtime scripts") 61 } 62 defer func() { 63 if err != nil { 64 if err1 := os.RemoveAll(tmpDir); err1 != nil { 65 logrus.WithError(err1).WithField("dir", tmpDir). 66 Warn("failed to remove tmp dir") 67 } 68 return 69 } 70 71 if err = os.Rename(runtimeDir, runtimeDir+"-old"); err != nil { 72 return 73 } 74 if err = os.Rename(tmpDir, runtimeDir); err != nil { 75 err = errors.Wrap(err, "failed to setup runtimes dir, new containers may not start") 76 return 77 } 78 if err = os.RemoveAll(runtimeDir + "-old"); err != nil { 79 logrus.WithError(err).WithField("dir", tmpDir). 80 Warn("failed to remove old runtimes dir") 81 } 82 }() 83 84 for name, rt := range runtimes { 85 if len(rt.Args) > 0 { 86 script := filepath.Join(tmpDir, name) 87 content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " ")) 88 if err := os.WriteFile(script, []byte(content), 0700); err != nil { 89 return err 90 } 91 } 92 if rt.Shim == nil { 93 rt.Shim = defaultV2ShimConfig(daemon.configStore, rt.Path) 94 } 95 } 96 return nil 97 } 98 99 // rewriteRuntimePath is used for runtimes which have custom arguments supplied. 100 // This is needed because the containerd API only calls the OCI runtime binary, there is no options for extra arguments. 101 // To support this case, the daemon wraps the specified runtime in a script that passes through those arguments. 102 func (daemon *Daemon) rewriteRuntimePath(name, p string, args []string) (string, error) { 103 if len(args) == 0 { 104 return p, nil 105 } 106 107 // Check that the runtime path actually exists here so that we can return a well known error. 108 if _, err := exec.LookPath(p); err != nil { 109 return "", errors.Wrap(err, "error while looking up the specified runtime path") 110 } 111 112 return filepath.Join(daemon.configStore.Root, "runtimes", name), nil 113 } 114 115 func (daemon *Daemon) getRuntime(name string) (*types.Runtime, error) { 116 rt := daemon.configStore.GetRuntime(name) 117 if rt == nil { 118 if !config.IsPermissibleC8dRuntimeName(name) { 119 return nil, errdefs.InvalidParameter(errors.Errorf("unknown or invalid runtime name: %s", name)) 120 } 121 return &types.Runtime{Shim: &types.ShimConfig{Binary: name}}, nil 122 } 123 124 if len(rt.Args) > 0 { 125 p, err := daemon.rewriteRuntimePath(name, rt.Path, rt.Args) 126 if err != nil { 127 return nil, err 128 } 129 rt.Path = p 130 rt.Args = nil 131 } 132 133 if rt.Shim == nil { 134 rt.Shim = defaultV2ShimConfig(daemon.configStore, rt.Path) 135 } 136 137 return rt, nil 138 }