From ebff37a24cff661fb9294472d30c80cf4bdb9e01 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 10 Nov 2020 21:09:37 +0100 Subject: [PATCH 001/373] Add CrioLXC singleton. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/defs.go | 7 -- cmd/main.go | 117 ++++++++++++++++++++++---------- cmd/utils.go | 65 ------------------ 4 files changed, 268 insertions(+), 108 deletions(-) create mode 100644 cmd/clxc.go delete mode 100644 cmd/defs.go diff --git a/cmd/clxc.go b/cmd/clxc.go new file mode 100644 index 00000000..07edd020 --- /dev/null +++ b/cmd/clxc.go @@ -0,0 +1,187 @@ +package main + +import ( + "fmt" + "github.com/pkg/errors" + "os" + "path/filepath" + "runtime" + "strings" + + "github.com/rs/zerolog" + "gopkg.in/lxc/go-lxc.v2" +) + +// time format used for logger +const TimeFormatLXCMillis = "20060102150405.000" + +var log zerolog.Logger + +var ErrExist = errors.New("container already exists") +var ErrContainerNotExist = errors.New("container does not exist") + +type CrioLXC struct { + *lxc.Container + + Command string + + // [ global settings ] + RuntimeRoot string + ContainerID string + LogFile *os.File + LogFilePath string + LogLevel lxc.LogLevel + LogLevelString string +} + +func (c CrioLXC) VersionString() string { + return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) +} + +// RuntimePath builds an absolute filepath which is relative to the container runtime root. +func (c *CrioLXC) RuntimePath(subPath ...string) string { + return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) +} + +func (c *CrioLXC) LoadContainer() error { + // Check for container existence by looking for config file. + // Otherwise lxc.NewContainer will return an empty container + // struct and we'll report wrong info + _, err := os.Stat(c.RuntimePath("config")) + if os.IsNotExist(err) { + return ErrContainerNotExist + } + if err != nil { + return errors.Wrap(err, "failed to access config file") + } + + container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) + if err != nil { + return errors.Wrap(err, "failed to load container") + } + if err := container.LoadConfigFile(c.RuntimePath("config")); err != nil { + return err + } + c.Container = container + return nil +} + +func (c *CrioLXC) CreateContainer() error { + _, err := os.Stat(c.RuntimePath("config")) + if !os.IsNotExist(err) { + return ErrExist + } + container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) + if err != nil { + return err + } + c.Container = container + if err := os.MkdirAll(c.RuntimePath(), 0770); err != nil { + return errors.Wrap(err, "failed to create container dir") + } + return nil +} + +// Release releases/closes allocated resources (lxc.Container, LogFile) +func (c CrioLXC) Release() { + if c.Container != nil { + c.Container.Release() + } + if c.LogFile != nil { + c.LogFile.Close() + } +} + +func (c CrioLXC) CanConfigure(keys ...string) bool { + for _, key := range keys { + if !lxc.IsSupportedConfigItem(key) { + log.Info().Str("key:", key).Msg("unsupported lxc config item") + return false + } + } + return true +} + +func (c *CrioLXC) GetConfigItem(key string) string { + vals := c.Container.ConfigItem(key) + if len(vals) > 0 { + first := vals[0] + // some lxc config values are set to '(null)' if unset + // eg. lxc.cgroup.dir + if first != "(null)" { + return first + } + } + return "" +} + +func (c *CrioLXC) SetConfigItem(key, value string) error { + err := c.Container.SetConfigItem(key, value) + if err != nil { + log.Error().Err(err).Str("key:", key).Str("value:", value).Msg("lxc config") + } else { + log.Debug().Str("key:", key).Str("value:", value).Msg("lxc config") + } + return errors.Wrap(err, "failed to set lxc config item '%s=%s'") +} + +func (c *CrioLXC) configureLogging() error { + logDir := filepath.Dir(c.LogFilePath) + err := os.MkdirAll(logDir, 0750) + if err != nil { + return errors.Wrapf(err, "failed to create log file directory %s", logDir) + } + + f, err := os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640) + if err != nil { + return errors.Wrapf(err, "failed to open log file %s", c.LogFilePath) + } + c.LogFile = f + + zerolog.TimestampFieldName = "t" + zerolog.LevelFieldName = "p" + zerolog.MessageFieldName = "m" + zerolog.TimeFieldFormat = TimeFormatLXCMillis + + // NOTE It's not possible change the possition of the timestamp. + // The ttimestamp is appended to the to the log output because it is dynamically rendered + // see https://github.com/rs/zerolog/issues/109 + log = zerolog.New(f).With().Timestamp().Str("cmd:", c.Command).Str("cid:", c.ContainerID).Logger() + + level, err := parseLogLevel(c.LogLevelString) + if err != nil { + log.Error().Err(err).Stringer("loglevel:", level).Msg("using fallback log-level") + } + c.LogLevel = level + + switch level { + case lxc.TRACE: + zerolog.SetGlobalLevel(zerolog.TraceLevel) + case lxc.DEBUG: + zerolog.SetGlobalLevel(zerolog.DebugLevel) + case lxc.INFO: + zerolog.SetGlobalLevel(zerolog.InfoLevel) + case lxc.WARN: + zerolog.SetGlobalLevel(zerolog.WarnLevel) + case lxc.ERROR: + zerolog.SetGlobalLevel(zerolog.ErrorLevel) + } + return nil +} + +func parseLogLevel(s string) (lxc.LogLevel, error) { + switch strings.ToLower(s) { + case "trace": + return lxc.TRACE, nil + case "debug": + return lxc.DEBUG, nil + case "info": + return lxc.INFO, nil + case "warn": + return lxc.WARN, nil + case "error": + return lxc.ERROR, nil + default: + return lxc.ERROR, fmt.Errorf("Invalid log-level %s", s) + } +} diff --git a/cmd/defs.go b/cmd/defs.go deleted file mode 100644 index 81a1d731..00000000 --- a/cmd/defs.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -var ( - CURRENT_OCI_VERSION = "0.2.1" - // controlled by --lxc-path arg to main - LXC_PATH = "" -) diff --git a/cmd/main.go b/cmd/main.go index 36a02dcb..b7d6507b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,66 +2,111 @@ package main import ( "fmt" + "github.com/pkg/errors" "os" - "github.com/apex/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -var ( - version = "" - debug = false +const ( + // IMPORTANT should be synced with the runtime-spec dependency in go.mod + // github.com/opencontainers/runtime-spec v1.0.2 + CURRENT_OCI_VERSION = "1.0.2" ) +var version string +var clxc CrioLXC + func main() { app := cli.NewApp() app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" - app.Version = version - app.Commands = []cli.Command{ - stateCmd, - createCmd, - startCmd, - killCmd, - deleteCmd, + app.Version = clxc.VersionString() + app.Commands = []*cli.Command{ + &stateCmd, + &createCmd, + &startCmd, + &killCmd, + &deleteCmd, } app.Flags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug", - Usage: "enable debug mode", - }, - cli.StringFlag{ - Name: "log-level", - Usage: "set log level for LXC", - }, - cli.StringFlag{ - Name: "log-file", - Usage: "log file for LXC", + &cli.StringFlag{ + Name: "log-level", + Usage: "set log level (trace|debug|info|warn|error)", + EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, + Value: "warn", + Destination: &clxc.LogLevelString, }, - cli.StringFlag{ - Name: "lxc-path, root", - Usage: "set the lxc path to use", - Value: "/var/lib/lxc", + &cli.StringFlag{ + Name: "log-file", + Usage: "log file for LXC and crio-lxc (default is per container in lxc-path)", + EnvVars: []string{"CRIO_LXC_LOG_FILE", "LOG_FILE"}, + Value: "/var/log/crio-lxc.log", + Destination: &clxc.LogFilePath, + &cli.StringFlag{ + Name: "root", + Aliases: []string{"lxc-path"}, // 'root' is used by crio/conmon + Usage: "set the root path where container resources are created (logs, init and hook scripts). Must have access permissions", + Value: "/var/lib/lxc", + Destination: &clxc.RuntimeRoot, }, } - app.Before = func(ctx *cli.Context) error { - LXC_PATH = ctx.String("lxc-path") - debug = ctx.Bool("debug") + app.Before = func(ctx *cli.Context) error { + clxc.Command = ctx.Args().Get(0) return nil } - log.SetLevel(log.InfoLevel) + setupCmd := func(ctx *cli.Context) error { + containerID := ctx.Args().Get(0) + if len(containerID) == 0 { + return errors.New("missing container ID") + } + clxc.ContainerID = containerID + clxc.Command = ctx.Command.Name + + if err := clxc.configureLogging(); err != nil { + return err + } - if err := app.Run(os.Args); err != nil { - format := "error: %v\n" - if debug { - format = "error: %+v\n" + for _, env := range os.Environ() { + log.Trace().Str("env:", env).Msg("effective environment variable") } + for _, appFlag := range app.Flags { + name := appFlag.Names()[0] + log.Trace().Str("name:", name).Str("value:", ctx.String(name)).Msg("effective cmdline flag") + } + + log.Info().Strs("args", os.Args).Msg("run cmd") + return nil + } + + // Disable the default error messages for cmdline errors. + // By default the app/cmd help is printed to stdout, which produces garbage in cri-o log output. + // Instead the cmdline is reflected to identify cmdline interface errors + errUsage := func(context *cli.Context, err error, isSubcommand bool) error { + fmt.Fprintf(os.Stderr, "usage error %s: %s\n", err, os.Args) + return err + } + app.OnUsageError = errUsage + + for _, cmd := range app.Commands { + cmd.Before = setupCmd + cmd.OnUsageError = errUsage + } + + app.CommandNotFound = func(ctx *cli.Context, cmd string) { + fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) + } + + err := app.Run(os.Args) - fmt.Fprintf(os.Stderr, format, err) + clxc.Release() + if err != nil { + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) os.Exit(1) } } diff --git a/cmd/utils.go b/cmd/utils.go index aa3a45bc..c83931da 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -2,17 +2,10 @@ package main import ( "encoding/json" - "fmt" "os" - "os/exec" - "path/filepath" - "strings" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/urfave/cli" - - lxc "gopkg.in/lxc/go-lxc.v2" ) func readBundleSpec(specFilePath string) (spec *specs.Spec, err error) { @@ -28,61 +21,3 @@ func readBundleSpec(specFilePath string) (spec *specs.Spec, err error) { return spec, nil } - -func configureLogging(ctx *cli.Context, c *lxc.Container) error { - if ctx.GlobalIsSet("log-level") { - var logLevel lxc.LogLevel - switch ctx.GlobalString("log-level") { - case "trace": - logLevel = lxc.TRACE - case "debug": - logLevel = lxc.DEBUG - case "info": - logLevel = lxc.INFO - case "warn": - logLevel = lxc.WARN - case "", "error": - logLevel = lxc.ERROR - default: - return fmt.Errorf("lxc driver config 'log_level' can only be trace, debug, info, warn or error") - } - c.SetLogLevel(logLevel) - } - - if ctx.GlobalIsSet("log-file") { - c.SetLogFile(ctx.GlobalString("log-file")) - } - return nil -} - -func pathExists(path string) (bool, error) { - _, err := os.Stat(path) - if err == nil { - return true, nil - } - if os.IsNotExist(err) { - return false, nil - } - return true, err -} - -func containerExists(containerID string) (bool, error) { - // check for container existence by looking for config file. - // otherwise NewContainer will return an empty container - // struct and we'll report wrong info - configExists, err := pathExists(filepath.Join(LXC_PATH, containerID, "config")) - if err != nil { - return false, errors.Wrap(err, "failed to check path existence of config") - } - - return configExists, nil -} - -func RunCommand(args ...string) error { - cmd := exec.Command(args[0], args[1:]...) - output, err := cmd.CombinedOutput() - if err != nil { - return errors.Errorf("%s: %s: %s", strings.Join(args, " "), err, string(output)) - } - return nil -} From f836176f550182180cc88bb5b95bbb9a58391268 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 11 Nov 2020 12:33:00 +0100 Subject: [PATCH 002/373] Add internal package. Signed-off-by: Ruben Jenster --- cmd/internal/internal.go | 39 +++++++++++++++++++++++++++++++++++++++ cmd/utils.go | 23 ----------------------- 2 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 cmd/internal/internal.go delete mode 100644 cmd/utils.go diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go new file mode 100644 index 00000000..a5f0949a --- /dev/null +++ b/cmd/internal/internal.go @@ -0,0 +1,39 @@ +package internal + +import ( + "encoding/json" + "github.com/opencontainers/runtime-spec/specs-go" + "os" +) + +const ( + // CFG_DIR is bind mounted (readonly) to container + CFG_DIR = "/.crio-lxc" + SYNC_FIFO_PATH = CFG_DIR + "/syncfifo" + SYNC_FIFO_CONTENT = "meshuggah rocks" + INIT_CMD = CFG_DIR + "/init" + INIT_SPEC = CFG_DIR + "/spec.json" +) + +func ReadSpec(specFilePath string) (*specs.Spec, error) { + specFile, err := os.Open(specFilePath) + if err != nil { + return nil, err + } + defer specFile.Close() + spec := &specs.Spec{} + err = json.NewDecoder(specFile).Decode(spec) + if err != nil { + return nil, err + } + return spec, nil +} + +func WriteSpec(spec *specs.Spec, specFilePath string) error { + f, err := os.OpenFile(specFilePath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0444) + if err != nil { + return err + } + defer f.Close() + return json.NewEncoder(f).Encode(spec) +} diff --git a/cmd/utils.go b/cmd/utils.go deleted file mode 100644 index c83931da..00000000 --- a/cmd/utils.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "encoding/json" - "os" - - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -) - -func readBundleSpec(specFilePath string) (spec *specs.Spec, err error) { - specFile, err := os.Open(specFilePath) - if err != nil { - return nil, errors.Wrapf(err, "failed to open spec file '%s'", specFilePath) - } - defer specFile.Close() - err = json.NewDecoder(specFile).Decode(&spec) - if err != nil { - return nil, errors.Wrapf(err, "failed to decode spec file") - } - - return spec, nil -} From 5b632bec96b81e1f438309ae2b9218cbcd519b4a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 10 Nov 2020 18:35:35 +0100 Subject: [PATCH 003/373] update go module dependencies. Signed-off-by: Ruben Jenster --- go.mod | 23 ++++++--------- go.sum | 89 +++++++++++++++++----------------------------------------- 2 files changed, 34 insertions(+), 78 deletions(-) diff --git a/go.mod b/go.mod index 7f80ccc2..808c5698 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,14 @@ module github.com/lxc/crio-lxc require ( - github.com/apex/log v1.1.1 - github.com/aws/aws-sdk-go v1.20.8 // indirect - github.com/golang/protobuf v1.3.1 // indirect - github.com/onsi/ginkgo v1.8.0 // indirect - github.com/opencontainers/runtime-spec v1.0.1 - github.com/pkg/errors v0.8.1 - github.com/stretchr/objx v0.2.0 // indirect - github.com/urfave/cli v1.20.0 - golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 // indirect - golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 - golang.org/x/text v0.3.2 // indirect - golang.org/x/tools v0.0.0-20190625160430-252024b82959 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - gopkg.in/lxc/go-lxc.v2 v2.0.0-20190625173123-f4822c6bba64 - gopkg.in/yaml.v2 v2.2.2 // indirect + github.com/creack/pty v1.1.11 + github.com/opencontainers/runtime-spec v1.0.2 + github.com/pkg/errors v0.9.1 + github.com/rs/zerolog v1.20.0 + github.com/stretchr/testify v1.3.0 + github.com/urfave/cli/v2 v2.2.0 + golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a + gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b ) replace github.com/vbatts/go-mtree v0.4.4 => github.com/vbatts/go-mtree v0.4.5-0.20190122034725-8b6de6073c1a diff --git a/go.sum b/go.sum index cc4071c6..7e904c93 100644 --- a/go.sum +++ b/go.sum @@ -1,77 +1,40 @@ -github.com/apex/log v1.1.1 h1:BwhRZ0qbjYtTob0I+2M+smavV0kOC8XgcnGZcyL9liA= -github.com/apex/log v1.1.1/go.mod h1:Ls949n1HFtXfbDcjiTTFQqkVUrte0puoIBfO3SVgwOA= -github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= -github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= -github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.20.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ= -github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= +github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= -github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= -github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190625160430-252024b82959/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/lxc/go-lxc.v2 v2.0.0-20190625173123-f4822c6bba64 h1:DU3NyssIxuVNRsE9piaPVHesR/f6KDI+la3s1eQAkTY= -gopkg.in/lxc/go-lxc.v2 v2.0.0-20190625173123-f4822c6bba64/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b h1:nZGkhEMZTXoUuojsilSBJNYZV75IczUo+92qHeXnH8o= +gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 872e2e6af096b85d36b393ef80ca955c08e2f508 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 10 Nov 2020 20:25:03 +0100 Subject: [PATCH 004/373] Load default from environment file /etc/default/crio-lxc Signed-off-by: Ruben Jenster --- cmd/main.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/cmd/main.go b/cmd/main.go index b7d6507b..ae7d1b22 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,7 +3,9 @@ package main import ( "fmt" "github.com/pkg/errors" + "io/ioutil" "os" + "strings" "github.com/urfave/cli/v2" ) @@ -12,6 +14,11 @@ const ( // IMPORTANT should be synced with the runtime-spec dependency in go.mod // github.com/opencontainers/runtime-spec v1.0.2 CURRENT_OCI_VERSION = "1.0.2" + // Environment variables are populated by default from this environment file. + // Existing environment variables are preserved. + EnvFileDefault = "/etc/default/crio-lxc" + // This environment variable can be used to overwrite the path in EnvFileDefault. + EnvFileVar = "CRIO_LXC_DEFAULTS" ) var version string @@ -101,6 +108,15 @@ func main() { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } + envFile := EnvFileDefault + if s, isSet := os.LookupEnv(EnvFileVar); isSet { + envFile = s + } + if err := loadEnvDefaults(envFile); err != nil { + println(err.Error()) + os.Exit(1) + } + err := app.Run(os.Args) clxc.Release() @@ -110,3 +126,37 @@ func main() { os.Exit(1) } } + +// TODO This should be added to the urfave/cli API - create a pull request +func loadEnvDefaults(envFile string) error { + _, err := os.Stat(envFile) + if os.IsNotExist(err) { + return nil + } + if err != nil { + return errors.Wrapf(err, "failed to stat %s", envFile) + } + data, err := ioutil.ReadFile(envFile) + if err != nil { + return errors.Wrap(err, "failed to load env file") + } + lines := strings.Split(string(data), "\n") + for n, line := range lines { + trimmed := strings.TrimSpace(line) + //skip over comments and blank lines + if len(trimmed) == 0 || trimmed[0] == '#' { + continue + } + vals := strings.SplitN(trimmed, "=", 2) + if len(vals) != 2 { + return fmt.Errorf("Invalid environment variable at %s +%d", envFile, n) + } + key := strings.TrimSpace(vals[0]) + val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) + // existing environment variables have precedence + if _, exist := os.LookupEnv(key); !exist { + os.Setenv(key, val) + } + } + return nil +} From cd99e0419d3ff6856e8c1be125eccaa59405352a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 10 Nov 2020 20:26:27 +0100 Subject: [PATCH 005/373] Trace command execution time. Signed-off-by: Ruben Jenster --- cmd/main.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/main.go b/cmd/main.go index ae7d1b22..72e0e5d0 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "strings" + "time" "github.com/urfave/cli/v2" ) @@ -60,6 +61,7 @@ func main() { }, } + startTime := time.Now() app.Before = func(ctx *cli.Context) error { clxc.Command = ctx.Args().Get(0) @@ -118,6 +120,12 @@ func main() { } err := app.Run(os.Args) + cmdDuration := time.Since(startTime) + if err != nil { + log.Error().Err(err).Dur("duration:", cmdDuration).Msg("cmd failed") + } else { + log.Info().Dur("duration:", cmdDuration).Msg("cmd done") + } clxc.Release() if err != nil { From 8137e93500bee7dc990d0e0469e1dc980b82adc5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 10 Nov 2020 21:00:18 +0100 Subject: [PATCH 006/373] Update Makefile Signed-off-by: Ruben Jenster --- Makefile | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 1d8f2b27..752d83cb 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,22 @@ GO_SRC=$(shell find . -name \*.go) -COMMIT_HASH=$(shell git rev-parse HEAD) +COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages +BINS := crio-lxc +PREFIX ?= /usr/local +LDFLAGS=-s -w -X main.version=$(COMMIT) + +all: fmt $(BINS) + +install: all + cp $(BINS) $(PREFIX)/bin lint: golangci-lint run -c ./lint.yaml ./... -crio-lxc: $(GO_SRC) - go build -ldflags "-X main.version=$(COMMIT)" -o crio-lxc ./cmd +crio-lxc: $(GO_SRC) Makefile go.mod + go build -ldflags '$(LDFLAGS)' -o $@ ./cmd # make test TEST=basic will run only the basic test. .PHONY: check @@ -23,4 +31,7 @@ vendorup: .PHONY: clean clean: - -rm -f crio-lxc + -rm -f $(BINS) + +fmt: + go fmt ./... From 85cc15a7a18756a11ae5dea4fd7327d41049cabb Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 11 Nov 2020 12:24:32 +0100 Subject: [PATCH 007/373] Create separate lxc start binary. Signed-off-by: Ruben Jenster --- .gitignore | 1 + Makefile | 7 ++- cmd/internal.go | 117 ------------------------------------- cmd/start/crio-lxc-start.c | 83 ++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 118 deletions(-) delete mode 100644 cmd/internal.go create mode 100644 cmd/start/crio-lxc-start.c diff --git a/.gitignore b/.gitignore index f940ec22..7740d84a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *~ crio-lxc +crio-lxc-start crio-lxc-test* oci/ roots/ diff --git a/Makefile b/Makefile index 752d83cb..42e58ef7 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,10 @@ COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages -BINS := crio-lxc +BINS := crio-lxc crio-lxc-start PREFIX ?= /usr/local +PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig +export PKG_CONFIG_PATH LDFLAGS=-s -w -X main.version=$(COMMIT) all: fmt $(BINS) @@ -18,6 +20,9 @@ lint: crio-lxc: $(GO_SRC) Makefile go.mod go build -ldflags '$(LDFLAGS)' -o $@ ./cmd +crio-lxc-start: cmd/start/crio-lxc-start.c + cc -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) $? -o $@ + # make test TEST=basic will run only the basic test. .PHONY: check check: crio-lxc diff --git a/cmd/internal.go b/cmd/internal.go deleted file mode 100644 index e72b2497..00000000 --- a/cmd/internal.go +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is a little bit strange. The problem is that we want to do - * daemonized containers with liblxc, but we can't spawn containers in threaded - * environments (i.e. golang), with go-lxc. So instead, we embed some C into - * our program that catches execution before golang starts. This way, we can do - * a tiny C program to actually spawn the container. - * - */ -package main - -// #cgo LDFLAGS: -llxc -/* -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include - -static int spawn_container(char *name, char *lxcpath, char *config) -{ - struct lxc_container *c; - - c = lxc_container_new(name, lxcpath); - if (!c) { - fprintf(stderr, "failed to create container %s\n", name); - return -1; - } - - c->clear_config(c); - if (!c->load_config(c, config)) { - fprintf(stderr, "failed to load container config at %s\n", config); - return -1; - } - - c->daemonize = false; - if (!c->start(c, 1, NULL)) { - fprintf(stderr, "failed to start container %s\n", name); - return -1; - } - - return c->error_num; -} - -// main function for the "internal" command. Right now, arguments look like: -// argv[0] internal -__attribute__((constructor)) void internal(void) -{ - int ret, status; - char buf[4096]; - ssize_t size; - char *cur, *name, *lxcpath, *config_path; - - ret = open("/proc/self/cmdline", O_RDONLY); - if (ret < 0) { - perror("error: open"); - exit(96); - } - - if ((size = read(ret, buf, sizeof(buf)-1)) < 0) { - close(ret); - perror("error: read"); - exit(96); - } - close(ret); - - // /proc/self/cmdline is null separated, but let's be real safe - buf[size] = 0; - cur = buf; - -#define ADVANCE_ARG \ - do { \ - while (*cur) { \ - cur++; \ - } \ - cur++; \ - } while (0) - - // skip argv[0] - ADVANCE_ARG; - - // is this really the internal command, if not, continue normal execution - if (strcmp(cur, "internal")) - return; - - ADVANCE_ARG; - name = cur; - ADVANCE_ARG; - lxcpath = cur; - ADVANCE_ARG; - config_path = cur; - - ret = isatty(STDIN_FILENO); - if (ret < 0) { - perror("isatty"); - exit(96); - } - - // If this is non interactive, get rid of our controlling terminal, - // since we don't want lxc's setting of ISIG to ignore user's ^Cs. - if (!ret) - setsid(); - - status = spawn_container(name, lxcpath, config_path); - - // Try and propagate the container's exit code. - if (WIFEXITED(status)) { - exit(WEXITSTATUS(status)); - } else { - kill(0, WTERMSIG(status)); - exit(EXIT_FAILURE); - } -} -*/ -import "C" diff --git a/cmd/start/crio-lxc-start.c b/cmd/start/crio-lxc-start.c new file mode 100644 index 00000000..e74f4dde --- /dev/null +++ b/cmd/start/crio-lxc-start.c @@ -0,0 +1,83 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include + +/* +/ Set to 0 to disable use of lxc-init. +/ The container process should have PID 1. +*/ +#define ENABLE_LXCINIT 0 + +/* NOTE lxc_execute.c was taken as guidline and some lines where copied. */ +int main(int argc, char** argv) +{ + int ret; + struct lxc_container *c; + int err = EXIT_FAILURE; + const char * name; + const char * lxcpath; + const char * rcfile; + + /* Ensure stdout and stderr are line bufferd. */ + setvbuf(stdout, NULL, _IOLBF, -1); + setvbuf(stderr, NULL, _IOLBF, -1); + + if (argc != 4) { + fprintf(stderr, "invalid cmdline: usage %s \n", argv[0]); + exit(err); + } + + ret = isatty(STDIN_FILENO); + if (ret < 0) { + perror("isatty"); + exit(96); + } + + /* + / If this is non interactive, get rid of our controlling terminal, + / since we don't want lxc's setting of ISIG to ignore user's ^Cs. + / Ignore any error - because controlling terminal could be a PTY. + */ + setsid(); + + name = argv[1]; + lxcpath = argv[2]; + rcfile = argv[3]; + + c = lxc_container_new(name, lxcpath); + if (!c) { + fprintf(stderr, "failed to create container"); + exit(err); + } + + c->clear_config(c); + if (!c->load_config(c, rcfile)) { + fprintf(stderr, "failed to load container config file"); + goto out; + } + + /* Do not daemonize - this would null the inherited stdio. */ + c->daemonize = false; + + if (!c->start(c, ENABLE_LXCINIT, NULL)) { + fprintf(stderr, "lxc container failed to start"); + goto out; + } + + if (WIFEXITED(c->error_num)) + err = WEXITSTATUS(c->error_num); + else + /* Try to die with the same signal the task did. */ + kill(0, WTERMSIG(c->error_num)); + +out: + lxc_container_put(c); + exit(err); +} From 6760bab93a9a83db087cd730f3ff79d9a70d3ac9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 11 Nov 2020 12:26:23 +0100 Subject: [PATCH 008/373] Add init binary. Signed-off-by: Ruben Jenster --- .gitignore | 1 + Makefile | 7 ++++- cmd/init/init.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 cmd/init/init.go diff --git a/.gitignore b/.gitignore index 7740d84a..60619c0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ crio-lxc crio-lxc-start +crio-lxc-init crio-lxc-test* oci/ roots/ diff --git a/Makefile b/Makefile index 42e58ef7..b7eb6878 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages -BINS := crio-lxc crio-lxc-start +BINS := crio-lxc crio-lxc-start crio-lxc-init PREFIX ?= /usr/local PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH @@ -23,6 +23,11 @@ crio-lxc: $(GO_SRC) Makefile go.mod crio-lxc-start: cmd/start/crio-lxc-start.c cc -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) $? -o $@ +crio-lxc-init: $(GO_SRC) Makefile go.mod + CGO_ENABLED=0 go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/init + # ensure that crio-lxc-init is statically compiled + ! ldd $@ 2>/dev/null + # make test TEST=basic will run only the basic test. .PHONY: check check: crio-lxc diff --git a/cmd/init/init.go b/cmd/init/init.go new file mode 100644 index 00000000..7dd3edff --- /dev/null +++ b/cmd/init/init.go @@ -0,0 +1,66 @@ +package main + +import ( + "github.com/lxc/crio-lxc/cmd/internal" + "golang.org/x/sys/unix" + "os" + "os/exec" + "os/user" + "strings" +) + +func fail(err error, step string) { + panic("init step [" + step + "] failed: " + err.Error()) +} + +func main() { + spec, err := internal.ReadSpec(internal.INIT_SPEC) + if err != nil { + panic(err) + } + + fifo, err := os.OpenFile(internal.SYNC_FIFO_PATH, os.O_WRONLY, 0) + if err != nil { + fail(err, "open sync fifo") + } + + _, err = fifo.Write([]byte(internal.SYNC_FIFO_CONTENT)) + if err != nil { + fail(err, "write to sync fifo") + } + + env := setHome(spec.Process.Env, spec.Process.User.Username, spec.Process.Cwd) + + if err := unix.Chdir(spec.Process.Cwd); err != nil { + fail(err, "change to cwd") + } + + cmdPath, err := exec.LookPath(spec.Process.Args[0]) + if err != nil { + fail(err, "lookup cmd path") + } + + err = unix.Exec(cmdPath, spec.Process.Args, env) + if err != nil { + fail(err, "exec") + } +} + +func setHome(env []string, userName string, fallback string) []string { + // Use existing HOME environment variable. + for _, kv := range env { + if strings.HasPrefix(kv, "HOME=") { + return env + } + return env + } + // Or lookup users home directory in passwd. + if userName != "" { + u, err := user.Lookup(userName) + if err == nil && u.HomeDir != "" { + return append(env, "HOME="+u.HomeDir) + } + } + // Use the provided fallback path as last resort. + return append(env, "HOME="+fallback) +} From 9f72aa6019b40c665ef8d1060616c652c5feed95 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 11 Nov 2020 12:31:01 +0100 Subject: [PATCH 009/373] Add hook binary. Signed-off-by: Ruben Jenster --- .gitignore | 1 + Makefile | 5 ++- cmd/hook/hook.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 cmd/hook/hook.go diff --git a/.gitignore b/.gitignore index 60619c0d..4a72e3cf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ crio-lxc crio-lxc-start crio-lxc-init +crio-lxc-hook crio-lxc-test* oci/ roots/ diff --git a/Makefile b/Makefile index b7eb6878..7983ebaa 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages -BINS := crio-lxc crio-lxc-start crio-lxc-init +BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-hook PREFIX ?= /usr/local PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH @@ -28,6 +28,9 @@ crio-lxc-init: $(GO_SRC) Makefile go.mod # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null +crio-lxc-hook: $(GO_SRC) Makefile go.mod + go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/hook + # make test TEST=basic will run only the basic test. .PHONY: check check: crio-lxc diff --git a/cmd/hook/hook.go b/cmd/hook/hook.go new file mode 100644 index 00000000..807a2d3d --- /dev/null +++ b/cmd/hook/hook.go @@ -0,0 +1,109 @@ +package main + +import ( + "fmt" + "github.com/lxc/crio-lxc/cmd/internal" + "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" + "os" + "path/filepath" +) + +func fail(err error, details string) { + msg := fmt.Errorf("ERR: %s failed: %s", details, err.Error()) + panic(msg) +} + +func main() { + // get rootfs mountpoint from environment + rootfs := os.Getenv("LXC_ROOTFS_MOUNT") + if rootfs == "" { + panic("LXC_ROOTFS_MOUNT environment is not set") + } + + if _, err := os.Stat(rootfs); err != nil { + fail(err, "stat for rootfs mount failed "+rootfs) + } + + specPath := filepath.Join(rootfs, internal.INIT_SPEC) + spec, err := internal.ReadSpec(specPath) + if err != nil { + fail(err, "parse spec "+specPath) + } + + for _, dev := range spec.Linux.Devices { + dev.Path = filepath.Join(rootfs, dev.Path) + if err := createDevice(spec, dev); err != nil { + fail(err, "failed to create device "+dev.Path) + } + } + + for _, p := range spec.Linux.MaskedPaths { + rp := filepath.Join(rootfs, p) + if err := maskPath(rp); err != nil { + fail(err, "failed to mask path "+rp) + } + } +} + +func getDeviceType(s string) int { + switch s { + case "b": + return unix.S_IFBLK + case "c": + return unix.S_IFCHR + case "p": + return unix.S_IFIFO + // case "u": ? unbuffered character device ? + } + return -1 +} + +func createDevice(spec *specs.Spec, dev specs.LinuxDevice) error { + var mode uint32 = 0660 + if dev.FileMode != nil { + mode |= uint32(*dev.FileMode) + } + devType := getDeviceType(dev.Type) + if devType == -1 { + return fmt.Errorf("unsupported device type: %s", dev.Type) + } + mode |= uint32(devType) + + devMode := 0 + if devType == unix.S_IFBLK || devType == unix.S_IFCHR { + devMode = int(unix.Mkdev(uint32(dev.Major), uint32(dev.Minor))) + } + + os.MkdirAll(filepath.Dir(dev.Path), 0755) + + err := unix.Mknod(dev.Path, mode, devMode) + if err != nil { + return fmt.Errorf("mknod failed: %s", err) + } + + uid := spec.Process.User.UID + if dev.UID != nil { + uid = *dev.UID + } + gid := spec.Process.User.GID + if dev.GID != nil { + gid = *dev.GID + } + err = unix.Chown(dev.Path, int(uid), int(gid)) + if err != nil { + return fmt.Errorf("chown failed: %s", err) + } + return nil +} + +func maskPath(p string) error { + err := unix.Mount("/dev/null", p, "", unix.MS_BIND, "") + if os.IsNotExist(err) { + return nil + } + if err == unix.ENOTDIR { + return unix.Mount("tmpfs", p, "tmpfs", unix.MS_RDONLY, "") + } + return err +} From ccc1990b036d4ffb9f6342cfe72339aa09d87ebc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 11 Nov 2020 12:32:08 +0100 Subject: [PATCH 010/373] bats test fixes Signed-off-by: Ruben Jenster --- .gitignore | 1 + test/crio.conf.in | 9 ++++++--- test/helpers.bash | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 4a72e3cf..d6869080 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ crio-lxc-test* oci/ roots/ .stacker/ +.keeptempdirs diff --git a/test/crio.conf.in b/test/crio.conf.in index eb0c7f89..5331fe7e 100644 --- a/test/crio.conf.in +++ b/test/crio.conf.in @@ -81,7 +81,7 @@ grpc_max_recv_msg_size = 16777216 # default_runtime is the _name_ of the OCI runtime to be used as the default. # The name is matched against the runtimes map below. -default_runtime = "runc" +default_runtime = "lxc" # If true, the runtime will not use pivot_root, but instead use MS_MOVE. no_pivot = false @@ -89,6 +89,9 @@ no_pivot = false # Path to the conmon binary, used for monitoring the OCI runtime. conmon = "PACKAGES_DIR/conmon/bin/conmon" +# Cgroup setting for conmon +#conmon_cgroup = "system.slice" + # Path to pinns. pinns_path = "PACKAGES_DIR/cri-o/bin/pinns" @@ -110,7 +113,7 @@ seccomp_profile = "CRIOLXC_TEST_DIR/seccomp.json" apparmor_profile = "unconfined" # Cgroup management implementation used for the runtime. -cgroup_manager = "cgroupfs" +cgroup_manager = "systemd" # List of default capabilities for containers. If it is empty or commented out, # only the capabilities defined in the containers json file by the user/kube @@ -213,7 +216,7 @@ manage_network_ns_lifecycle = false # If no runtime_handler is provided, the runtime will be picked based on the level # of trust of the workload. -[crio.runtime.runtimes.runc] +[crio.runtime.runtimes.lxc] runtime_path = "CRIOLXC_BINARY" runtime_type = "oci" runtime_root = "CRIOLXC_TEST_DIR/runtime-root" diff --git a/test/helpers.bash b/test/helpers.bash index 2bba1b2b..d8800d1e 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -53,8 +53,7 @@ function cleanup_tempdir { function crictl { # watch out for: https://github.com/kubernetes-sigs/cri-tools/issues/460 # If you need more debug output, set CRICTLDEBUG to -D - CRICTLDEBUG="" - $(which crictl) ${CRICTLDEBUG} --runtime-endpoint "$TEMP_DIR/crio.sock" $@ + $(which crictl) ${CRICTLDEBUG} --runtime-endpoint "unix://$TEMP_DIR/crio.sock" $@ echo "$output" } From ff5834a7fcadaee5aeb3f85bbb986cb66852924f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:47:24 +0100 Subject: [PATCH 011/373] exec: Implement exec commnad. Signed-off-by: Ruben Jenster --- cmd/exec.go | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 cmd/exec.go diff --git a/cmd/exec.go b/cmd/exec.go new file mode 100644 index 00000000..4aea1764 --- /dev/null +++ b/cmd/exec.go @@ -0,0 +1,131 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" + "github.com/urfave/cli/v2" + + "github.com/lxc/crio-lxc/cmd/internal" + lxc "gopkg.in/lxc/go-lxc.v2" +) + +var execCmd = cli.Command{ + Name: "exec", + Usage: "execute a new process in a running container", + ArgsUsage: "", + Action: doExec, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "process", + Aliases: []string{"p"}, + Usage: "path to process json", + Value: "", + }, + &cli.StringFlag{ + Name: "pid-file", + Usage: "file to write the process id to", + Value: "", + }, + &cli.BoolFlag{ + Name: "detach", + Aliases: []string{"d"}, + Usage: "detach from the executed process", + }, + }, +} + +func doExec(ctx *cli.Context) error { + err := clxc.LoadContainer() + if err != nil { + return errors.Wrap(err, "failed to load container") + } + c := clxc.Container + + attachOpts := lxc.AttachOptions{} + + var procArgs []string + specFilePath := ctx.String("process") + + if specFilePath != "" { + log.Debug().Str("spec:", specFilePath).Msg("read process spec") + specData, err := ioutil.ReadFile(specFilePath) + log.Trace().Err(err).RawJSON("spec", specData).Msg("process spec data") + + if err != nil { + return errors.Wrap(err, "failed to read process spec") + } + + var procSpec *specs.Process + err = json.Unmarshal(specData, &procSpec) + if err != nil { + return errors.Wrapf(err, "failed to unmarshal process spec") + } + procArgs = procSpec.Args + attachOpts.UID = int(procSpec.User.UID) + attachOpts.GID = int(procSpec.User.GID) + if n := len(procSpec.User.AdditionalGids); n > 0 { + attachOpts.Groups = make([]int, n) + for i, g := range procSpec.User.AdditionalGids { + attachOpts.Groups[i] = int(g) + } + } + log.Debug().Int("uid:", attachOpts.UID).Int("gid:", attachOpts.GID).Ints("groups", attachOpts.Groups).Msg("process user") + log.Debug().Strs("arg:", procArgs).Msg("process args") + attachOpts.Cwd = procSpec.Cwd + // Use the environment defined by the process spec. + attachOpts.ClearEnv = true + attachOpts.Env = procSpec.Env + + } else { + // Fall back to cmdline arguments. + if ctx.Args().Len() >= 2 { + procArgs = ctx.Args().Slice()[1:] + } + } + + // Load container spec to get the list of supported namespaces. + spec, err := internal.ReadSpec(clxc.RuntimePath(internal.INIT_SPEC)) + if err != nil { + return errors.Wrap(err, "failed to read container runtime spec") + } + for _, ns := range spec.Linux.Namespaces { + n, supported := NamespaceMap[ns.Type] + if !supported { + return fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) + } + attachOpts.Namespaces |= n.CloneFlag + } + + attachOpts.StdinFd = os.Stdin.Fd() + attachOpts.StdoutFd = os.Stdout.Fd() + attachOpts.StderrFd = os.Stderr.Fd() + + detach := ctx.Bool("detach") + log.Debug().Bool("detach", detach).Strs("args", procArgs).Msg("exec cmd") + + if detach { + pidFile := ctx.String("pid-file") + pid, err := c.RunCommandNoWait(procArgs, attachOpts) + if err != nil { + return errors.Wrapf(err, "c.RunCommandNoWait failed") + } + log.Debug().Err(err).Int("pid", pid).Msg("cmd executed detached") + if pidFile == "" { + log.Warn().Msg("detaching process but pid-file value is empty") + return nil + } + return createPidFile(pidFile, pid) + } else { + exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) + if err != nil { + return errors.Wrapf(err, "c.RunCommandStatus returned with exit code %d", exitStatus) + } + log.Debug().Int("exit", exitStatus).Msg("cmd executed synchronous") + } + return nil +} From 994fb0cb535d48672a443cd7db2f025d25e6bf32 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:49:27 +0100 Subject: [PATCH 012/373] refactor: Rebase WIP Signed-off-by: Ruben Jenster --- Makefile | 2 +- README.md | 52 ++++ cmd/cgroup.go | 232 ++++++++++++++ cmd/cgroup_test.go | 12 + cmd/clxc.go | 228 ++++++++++++-- cmd/create.go | 653 +++++++++++++++++++++++++++------------ cmd/delete.go | 169 +++++++--- cmd/exec.go | 19 +- cmd/hook/hook.go | 3 +- cmd/init/init.go | 6 +- cmd/internal/internal.go | 24 +- cmd/kill.go | 83 ++--- cmd/main.go | 111 ++++++- cmd/mount.go | 173 +++++++++++ cmd/mount_test.go | 72 +++++ cmd/namespaces.go | 69 +++++ cmd/seccomp.go | 144 +++++++++ cmd/start.go | 97 +++--- cmd/state.go | 97 +----- cmd/utils.go | 27 ++ go.mod | 11 +- go.sum | 89 ++++++ 22 files changed, 1890 insertions(+), 483 deletions(-) create mode 100644 cmd/cgroup.go create mode 100644 cmd/cgroup_test.go create mode 100644 cmd/mount.go create mode 100644 cmd/mount_test.go create mode 100644 cmd/namespaces.go create mode 100644 cmd/seccomp.go create mode 100644 cmd/utils.go diff --git a/Makefile b/Makefile index 7983ebaa..87eac446 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-hook PREFIX ?= /usr/local PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH -LDFLAGS=-s -w -X main.version=$(COMMIT) +LDFLAGS=-X main.version=$(COMMIT) all: fmt $(BINS) diff --git a/README.md b/README.md index fbce9fd6..b167a8a2 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,28 @@ make Then specify the `crio-lxc` binary you just built as the value for `default_runtime` in the `crio.runtime` section of `/etc/crio/crio.conf`. +#### change liblxc source path + +The installation prefix environment variable is set to `PREFIX=/usr/local` by default. +The library source path for `pkg-config` is set to `$PREFIX/lib/pkg-config` by default. +You can change that by setting the `PKG_CONFIG_PATH` environment variable. + +E.g to install binaries in `/opt/bin` and use liblxc from `/usr/lib`: + + PREFIX=/opt PKG_CONFIG_PATH=/usr/lib/pkgconfig make install + +#### rebuild all libraries + +To rebuild all libraries set `GOFLAGS=-a`. +E.g after an liblxc upgrade the go-lxc library must be rebuild. + + make clean + GOFLAGS=-a make + +### cri-o + +crio-lxc-install + ## Notes Note that you must have a new enough liblxc, one which supports the @@ -51,3 +73,33 @@ You'll also need conntrack installed: ``` apt install conntrack ``` + +You have to install [bats](https://github.com/bats-core/bats-core) to run the tests. +On debian you can install bats with: + + apt-get install bats + + +To keep the tempdir of of a test run, you have to create the lockfile `.keeptempdirs` +in the top-level of this repository. + + touch .keeptempdirs + +To debug `crictl` calls within a test run: + + CRICTLDEBUG="-D" make basic.bats + +`bats` does not show any output when the test was successful. +The logfile is created in /tmp and deleted when the test was successful. +To watch the test output while the test is running: + + tail -f /tmp/bats.*.log + +Expand multi-line output int cri-o log (e.g stacktrace) + +echo "output" | sed 's/\\n\\t/\n/g' + + +# TODO +## generate nice buttons for the project page +https://goreportcard.com diff --git a/cmd/cgroup.go b/cmd/cgroup.go new file mode 100644 index 00000000..64adac9a --- /dev/null +++ b/cmd/cgroup.go @@ -0,0 +1,232 @@ +package main + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" +) + +// https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md +// TODO New spec will contain a property Unified for cgroupv2 properties +// https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#unified +func configureCgroup(spec *specs.Spec) error { + if err := configureCgroupPath(spec.Linux); err != nil { + return errors.Wrap(err, "failed to configure cgroup path") + } + + // lxc.cgroup.root and lxc.cgroup.relative must not be set for cgroup v2 + if err := clxc.setConfigItem("lxc.cgroup.relative", "0"); err != nil { + return err + } + + if devices := spec.Linux.Resources.Devices; devices != nil { + if err := configureDeviceController(spec); err != nil { + return err + } + } + + if mem := spec.Linux.Resources.Memory; mem != nil { + log.Debug().Msg("TODO cgroup memory controller not implemented") + } + + if cpu := spec.Linux.Resources.CPU; cpu != nil { + if err := configureCPUController(cpu); err != nil { + return err + } + } + + if pids := spec.Linux.Resources.Pids; pids != nil { + if err := clxc.setConfigItem("lxc.cgroup2.pids.max", fmt.Sprintf("%d", pids.Limit)); err != nil { + return err + } + } + if blockio := spec.Linux.Resources.BlockIO; blockio != nil { + log.Warn().Msg("TODO cgroup blockio controller not implemented") + } + + if hugetlb := spec.Linux.Resources.HugepageLimits; hugetlb != nil { + // set Hugetlb limit (in bytes) + log.Warn().Msg("TODO cgroup hugetlb controller not implemented") + } + if net := spec.Linux.Resources.Network; net != nil { + log.Warn().Msg("TODO cgroup network controller not implemented") + } + return nil +} + +func configureCgroupPath(linux *specs.Linux) error { + if linux.CgroupsPath == "" { + return fmt.Errorf("empty cgroups path in spec") + } + if !clxc.SystemdCgroup { + return clxc.setConfigItem("lxc.cgroup.dir", linux.CgroupsPath) + } + cgPath := parseSystemdCgroupPath(linux.CgroupsPath) + // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb + // checking for on of the config items shuld be enough, because they were introduced together ... + if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { + if err := clxc.setConfigItem("lxc.cgroup.dir.container", cgPath.String()); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.cgroup.dir.monitor", filepath.Join(clxc.MonitorCgroup, clxc.Container.Name()+".scope")); err != nil { + return err + } + } else { + if err := clxc.setConfigItem("lxc.cgroup.dir", cgPath.String()); err != nil { + return err + } + } + if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := clxc.setConfigItem("lxc.cgroup.dir.monitor.pivot", clxc.MonitorCgroup); err != nil { + return err + } + } + return nil +} + +func configureDeviceController(spec *specs.Spec) error { + devicesAllow := "lxc.cgroup2.devices.allow" + devicesDeny := "lxc.cgroup2.devices.deny" + + if !clxc.CgroupDevices { + log.Warn().Msg("cgroup device controller is disabled (access to all devices is granted)") + // allow read-write-mknod access to all char and block devices + if err := clxc.setConfigItem(devicesAllow, "b *:* rwm"); err != nil { + return err + } + if err := clxc.setConfigItem(devicesAllow, "c *:* rwm"); err != nil { + return err + } + return nil + } + + // Set cgroup device permissions from spec. + // Device rule parsing in LXC is not well documented in lxc.container.conf + // see https://github.com/lxc/lxc/blob/79c66a2af36ee8e967c5260428f8cdb5c82efa94/src/lxc/cgroups/cgfsng.c#L2545 + // Mixing allow/deny is not permitted by lxc.cgroup2.devices. + // Best practise is to build up an allow list to disable access restrict access to new/unhandled devices. + + anyDevice := "" + blockDevice := "b" + charDevice := "c" + + for _, dev := range spec.Linux.Resources.Devices { + key := devicesDeny + if dev.Allow { + key = devicesAllow + } + + maj := "*" + if dev.Major != nil { + maj = fmt.Sprintf("%d", *dev.Major) + } + + min := "*" + if dev.Minor != nil { + min = fmt.Sprintf("%d", *dev.Minor) + } + + switch dev.Type { + case anyDevice: + // do not deny any device, this will also deny access to default devices + if !dev.Allow { + continue + } + // decompose + val := fmt.Sprintf("%s %s:%s %s", blockDevice, maj, min, dev.Access) + if err := clxc.setConfigItem(key, val); err != nil { + return err + } + val = fmt.Sprintf("%s %s:%s %s", charDevice, maj, min, dev.Access) + if err := clxc.setConfigItem(key, val); err != nil { + return err + } + case blockDevice, charDevice: + val := fmt.Sprintf("%s %s:%s %s", dev.Type, maj, min, dev.Access) + if err := clxc.setConfigItem(key, val); err != nil { + return err + } + default: + return fmt.Errorf("Invalid cgroup2 device - invalid type (allow:%t %s %s:%s %s)", dev.Allow, dev.Type, maj, min, dev.Access) + } + } + return nil +} + +func configureCPUController(linux *specs.LinuxCPU) error { + // CPU resource restriction configuration + // use strconv.FormatUint(n, 10) instead of fmt.Sprintf ? + log.Debug().Msg("TODO configure cgroup cpu controller") + /* + if cpu.Shares != nil && *cpu.Shares > 0 { + if err := clxc.setConfigItem("lxc.cgroup2.cpu.shares", fmt.Sprintf("%d", *cpu.Shares)); err != nil { + return err + } + } + if cpu.Quota != nil && *cpu.Quota > 0 { + if err := clxc.setConfigItem("lxc.cgroup2.cpu.cfs_quota_us", fmt.Sprintf("%d", *cpu.Quota)); err != nil { + return err + } + } + if cpu.Period != nil && *cpu.Period != 0 { + if err := clxc.setConfigItem("lxc.cgroup2.cpu.cfs_period_us", fmt.Sprintf("%d", *cpu.Period)); err != nil { + return err + } + } + if cpu.Cpus != "" { + if err := clxc.setConfigItem("lxc.cgroup2.cpuset.cpus", cpu.Cpus); err != nil { + return err + } + } + if cpu.RealtimePeriod != nil && *cpu.RealtimePeriod > 0 { + if err := clxc.setConfigItem("lxc.cgroup2.cpu.rt_period_us", fmt.Sprintf("%d", *cpu.RealtimePeriod)); err != nil { + return err + } + } + if cpu.RealtimeRuntime != nil && *cpu.RealtimeRuntime > 0 { + if err := clxc.setConfigItem("lxc.cgroup2.cpu.rt_runtime_us", fmt.Sprintf("%d", *cpu.RealtimeRuntime)); err != nil { + return err + } + } + */ + // Mems string `json:"mems,omitempty"` + return nil +} + +// https://kubernetes.io/docs/setup/production-environment/container-runtimes/ +// kubelet --cgroup-driver systemd --cgroups-per-qos +type cgroupPath struct { + Slices []string + Scope string +} + +func (cg cgroupPath) String() string { + return filepath.Join(append(cg.Slices, cg.Scope)...) +} + +// kubernetes creates the cgroup hierarchy which can be changed by serveral cgroup related flags. +// kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod87f8bc68_7c18_4a1d_af9f_54eff815f688.slice +// kubepods-burstable-pod9da3b2a14682e1fb23be3c2492753207.slice:crio:fe018d944f87b227b3b7f86226962639020e99eac8991463bf7126ef8e929589 +// https://github.com/cri-o/cri-o/issues/2632 +func parseSystemdCgroupPath(s string) (cg cgroupPath) { + if s == "" { + return cg + } + parts := strings.Split(s, ":") + + slices := parts[0] + for i, r := range slices { + if r == '-' && i > 0 { + slice := slices[0:i] + ".slice" + cg.Slices = append(cg.Slices, slice) + } + } + cg.Slices = append(cg.Slices, slices) + if len(parts) > 0 { + cg.Scope = strings.Join(parts[1:], "-") + ".scope" + } + return cg +} diff --git a/cmd/cgroup_test.go b/cmd/cgroup_test.go new file mode 100644 index 00000000..8aa70262 --- /dev/null +++ b/cmd/cgroup_test.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func TestParseSystemCgroupPath(t *testing.T) { + s := "kubepods-burstable-123.slice:crio:ABC" + cg := parseSystemdCgroupPath(s) + require.Equal(t, "kubepods.slice/kubepods-burstable.slice/kubepods-burstable-123.slice/crio-ABC.scope", cg.String()) +} diff --git a/cmd/clxc.go b/cmd/clxc.go index 07edd020..88cf4698 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -3,25 +3,29 @@ package main import ( "fmt" "github.com/pkg/errors" + "io/ioutil" "os" + "os/exec" "path/filepath" "runtime" "strings" + "time" + "github.com/lxc/crio-lxc/cmd/internal" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" ) // time format used for logger -const TimeFormatLXCMillis = "20060102150405.000" +const timeFormatLXCMillis = "20060102150405.000" var log zerolog.Logger -var ErrExist = errors.New("container already exists") -var ErrContainerNotExist = errors.New("container does not exist") +var errContainerNotExist = errors.New("container does not exist") +var errContainerExist = errors.New("container already exists") -type CrioLXC struct { - *lxc.Container +type crioLXC struct { + Container *lxc.Container Command string @@ -32,24 +36,50 @@ type CrioLXC struct { LogFilePath string LogLevel lxc.LogLevel LogLevelString string + BackupDir string + Backup bool + BackupOnError bool + SystemdCgroup bool + MonitorCgroup string + StartCommand string + InitCommand string + HookCommand string + + // feature gates + Seccomp bool + Capabilities bool + Apparmor bool + CgroupDevices bool + + // create flags + BundlePath string + SpecPath string // BundlePath + "/config.json" + PidFile string + ConsoleSocket string + CreateTimeout time.Duration + + // start flags + StartTimeout time.Duration } -func (c CrioLXC) VersionString() string { +var version string + +func versionString() string { return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) } -// RuntimePath builds an absolute filepath which is relative to the container runtime root. -func (c *CrioLXC) RuntimePath(subPath ...string) string { +// runtimePath builds an absolute filepath which is relative to the container runtime root. +func (c *crioLXC) runtimePath(subPath ...string) string { return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) } -func (c *CrioLXC) LoadContainer() error { +func (c *crioLXC) loadContainer() error { // Check for container existence by looking for config file. // Otherwise lxc.NewContainer will return an empty container // struct and we'll report wrong info - _, err := os.Stat(c.RuntimePath("config")) + _, err := os.Stat(c.runtimePath("config")) if os.IsNotExist(err) { - return ErrContainerNotExist + return errContainerNotExist } if err != nil { return errors.Wrap(err, "failed to access config file") @@ -59,50 +89,53 @@ func (c *CrioLXC) LoadContainer() error { if err != nil { return errors.Wrap(err, "failed to load container") } - if err := container.LoadConfigFile(c.RuntimePath("config")); err != nil { + if err := container.LoadConfigFile(c.runtimePath("config")); err != nil { return err } c.Container = container return nil } -func (c *CrioLXC) CreateContainer() error { - _, err := os.Stat(c.RuntimePath("config")) +func (c *crioLXC) createContainer() error { + _, err := os.Stat(c.runtimePath("config")) if !os.IsNotExist(err) { - return ErrExist + return errContainerExist } container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { return err } c.Container = container - if err := os.MkdirAll(c.RuntimePath(), 0770); err != nil { + if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } return nil } // Release releases/closes allocated resources (lxc.Container, LogFile) -func (c CrioLXC) Release() { +func (c crioLXC) release() error { if c.Container != nil { - c.Container.Release() + if err := c.Container.Release(); err != nil { + log.Error().Err(err).Msg("failed to release container") + } } if c.LogFile != nil { - c.LogFile.Close() + return c.LogFile.Close() } + return nil } -func (c CrioLXC) CanConfigure(keys ...string) bool { +func supportsConfigItem(keys ...string) bool { for _, key := range keys { if !lxc.IsSupportedConfigItem(key) { - log.Info().Str("key:", key).Msg("unsupported lxc config item") + log.Debug().Str("key:", key).Msg("unsupported lxc config item") return false } } return true } -func (c *CrioLXC) GetConfigItem(key string) string { +func (c *crioLXC) getConfigItem(key string) string { vals := c.Container.ConfigItem(key) if len(vals) > 0 { first := vals[0] @@ -115,7 +148,7 @@ func (c *CrioLXC) GetConfigItem(key string) string { return "" } -func (c *CrioLXC) SetConfigItem(key, value string) error { +func (c *crioLXC) setConfigItem(key, value string) error { err := c.Container.SetConfigItem(key, value) if err != nil { log.Error().Err(err).Str("key:", key).Str("value:", value).Msg("lxc config") @@ -125,14 +158,14 @@ func (c *CrioLXC) SetConfigItem(key, value string) error { return errors.Wrap(err, "failed to set lxc config item '%s=%s'") } -func (c *CrioLXC) configureLogging() error { +func (c *crioLXC) configureLogging() error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) if err != nil { return errors.Wrapf(err, "failed to create log file directory %s", logDir) } - f, err := os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640) + f, err := os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { return errors.Wrapf(err, "failed to open log file %s", c.LogFilePath) } @@ -141,7 +174,7 @@ func (c *CrioLXC) configureLogging() error { zerolog.TimestampFieldName = "t" zerolog.LevelFieldName = "p" zerolog.MessageFieldName = "m" - zerolog.TimeFieldFormat = TimeFormatLXCMillis + zerolog.TimeFieldFormat = timeFormatLXCMillis // NOTE It's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered @@ -185,3 +218,146 @@ func parseLogLevel(s string) (lxc.LogLevel, error) { return lxc.ERROR, fmt.Errorf("Invalid log-level %s", s) } } + +// BackupRuntimeResources creates a backup of the container runtime resources. +// It returns the path to the backup directory. +// +// The following resources are backed up: +// - all resources created by crio-lxc (lxc config, init script, device creation script ...) +// - lxc logfiles (if logging is setup per container) +// - the runtime spec +func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { + backupDir = filepath.Join(c.BackupDir, c.ContainerID) + err = os.MkdirAll(c.BackupDir, 0700) + if err != nil { + return "", errors.Wrap(err, "failed to create backup dir") + } + err = runCommand("cp", "-r", "-p", clxc.runtimePath(), backupDir) + if err != nil { + return backupDir, errors.Wrap(err, "failed to copy lxc runtime directory") + } + // remove syncfifo because it is not of any use and blocks 'grep' within the backup directory. + os.Remove(filepath.Join(backupDir, internal.SyncFifoPath)) + err = runCommand("cp", clxc.SpecPath, backupDir) + if err != nil { + return backupDir, errors.Wrap(err, "failed to copy runtime spec to backup dir") + } + return backupDir, nil +} + +// TODO avoid shellout +func runCommand(args ...string) error { + cmd := exec.Command(args[0], args[1:]...) + output, err := cmd.CombinedOutput() + if err != nil { + return errors.Errorf("%s: %s: %s", strings.Join(args, " "), err, string(output)) + } + return nil +} + +// runtime states https://github.com/opencontainers/runtime-spec/blob/v1.0.2/runtime.md +const ( + // the container is being created (step 2 in the lifecycle) + stateCreating = "creating" + // the runtime has finished the create operation (after step 2 in the lifecycle), + // and the container process has neither exited nor executed the user-specified program + stateCreated = "created" + // the container process has executed the user-specified program + // but has not exited (after step 5 in the lifecycle) + stateRunning = "running" + // the container process has exited (step 7 in the lifecycle) + stateStopped = "stopped" + + // crio-lxc-init is started but blocking at the syncfifo + envStateCreated = "CRIO_LXC_STATE=" + stateCreated +) + +func (c *crioLXC) getContainerState() (int, string, error) { + switch state := c.Container.State(); state { + case lxc.STARTING: + return 0, stateCreating, nil + case lxc.STOPPED: + return 0, stateStopped, nil + default: + return c.getContainerInitState() + } +} + +// getContainerInitState returns the runtime state of the container. +// It is used to determine whether the container state is 'created' or 'running'. +// The init process environment contains #envStateCreated if the the container +// is created, but not yet running/started. +// This requires the proc filesystem to be mounted on the host. +func (c *crioLXC) getContainerInitState() (int, string, error) { + pid, proc := c.safeGetInitPid() + if proc != nil { + defer proc.Close() + } + if pid <= 0 { + return 0, stateStopped, nil + } + + envFile := fmt.Sprintf("/proc/%d/environ", pid) + data, err := ioutil.ReadFile(envFile) + if err != nil { + // This is fatal. It should not happen because a filehandle to /proc/%d is open. + return 0, stateStopped, errors.Wrapf(err, "failed to read init process environment %s", envFile) + } + + environ := strings.Split(string(data), "\000") + for _, env := range environ { + if env == envStateCreated { + return pid, stateCreated, nil + } + } + return pid, stateRunning, nil +} + +func (c *crioLXC) safeGetInitPid() (pid int, proc *os.File) { + pid = c.Container.InitPid() + if pid <= 0 { + // Errors returned from safeGetInitPid indicate that the init process has died. + return 0, nil + } + // Open the proc directory of the init process to avoid that + // it's PID is recycled before it receives the signal. + proc, err := os.Open(fmt.Sprintf("/proc/%d", pid)) + + // double check that the init process still exists, and the proc + // directory actually belongs to the init process. + pid2 := c.Container.InitPid() + if pid2 != pid { + if proc != nil { + proc.Close() + } + // init process has died which should only happen if /proc/%d was not opened + return 0, nil + } + + // The init PID still exists, but /proc/{pid} can not be opened. + // The only reason maybe that the proc filesystem is not mounted. + // It's unlikely a permissions problem because crio runs as privileged process. + // This leads to race conditions and should appear in the logs. + if proc == nil { + log.Error().Err(err).Int("pid:", pid).Msg("failed to open /proc directory for init PID - procfs mounted?") + } + + return pid, proc +} + +func (c *crioLXC) waitContainerCreated(timeout time.Duration) error { + deadline := time.Now().Add(timeout) + for time.Now().Before(deadline) { + log.Trace().Msg("poll for container init state") + pid, state, err := c.getContainerInitState() + if err != nil { + return errors.Wrap(err, "failed to wait for container container creation") + } + + if pid > 0 && state == stateCreated { + return nil + } + time.Sleep(time.Millisecond * 50) + } + return fmt.Errorf("timeout (%s) waiting for container creation", timeout) +} diff --git a/cmd/create.go b/cmd/create.go index f0f20a51..045e6b0c 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -2,22 +2,23 @@ package main import ( "fmt" - "golang.org/x/sys/unix" - - "io/ioutil" + "net" "os" "os/exec" - "path" "path/filepath" - "regexp" + "runtime" + "strconv" "strings" "time" - "github.com/apex/log" + "golang.org/x/sys/unix" + + "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" + "github.com/lxc/crio-lxc/cmd/internal" lxc "gopkg.in/lxc/go-lxc.v2" ) @@ -27,301 +28,549 @@ var createCmd = cli.Command{ ArgsUsage: "", Action: doCreate, Flags: []cli.Flag{ - cli.StringFlag{ - Name: "bundle", - Usage: "set bundle directory", - Value: ".", + &cli.StringFlag{ + Name: "bundle", + Usage: "set bundle directory", + Value: ".", + Destination: &clxc.BundlePath, + }, + &cli.StringFlag{ + Name: "console-socket", + Usage: "send container pty master fd to this socket path", + Destination: &clxc.ConsoleSocket, }, - cli.IntFlag{ - Name: "console-socket", - Usage: "pty master FD", // TODO not handled yet + &cli.StringFlag{ + Name: "pid-file", + Usage: "path to write container PID", + Destination: &clxc.PidFile, }, - cli.StringFlag{ - Name: "pid-file", - Usage: "path to write container PID", // TODO not handled yet + &cli.DurationFlag{ + Name: "timeout", + Usage: "timeout for container creation", + EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, + Value: time.Second * 5, + Destination: &clxc.CreateTimeout, }, }, } -// maps from CRIO namespace names to LXC names -var NamespaceMap = map[string]string{ - "cgroup": "cgroup", - "ipc": "ipc", - "mount": "mnt", - "network": "net", - "pid": "pid", - "user": "user", - "uts": "uts", +func doCreate(ctx *cli.Context) error { + err := doCreateInternal() + if clxc.Backup || (err != nil && clxc.BackupOnError) { + backupDir, backupErr := clxc.backupRuntimeResources() + if backupErr == nil { + log.Warn().Str("dir:", backupDir).Msg("runtime backup completed") + } else { + log.Error().Err(backupErr).Str("dir:", backupDir).Msg("runtime backup failed") + } + } + return err } -func ensureShell(rootfs string) error { - shPath := filepath.Join(rootfs, "bin/sh") - if exists, _ := pathExists(shPath); exists { - return nil +func doCreateInternal() error { + // minimal lxc version is 3.1 https://discuss.linuxcontainers.org/t/lxc-3-1-has-been-released/3527 + if !lxc.VersionAtLeast(3, 1, 0) { + return fmt.Errorf("LXC runtime version > 3.1.0 required, but was %s", lxc.Version()) } - var err error - err = RunCommand("mkdir", filepath.Join(rootfs, "bin")) - if err != nil { - return errors.Wrapf(err, "Failed doing mkdir") + + err := clxc.loadContainer() + if err == nil { + return fmt.Errorf("container already exists") } - err = RunCommand("cp", "/bin/busybox", filepath.Join(rootfs, "bin/")) + + err = clxc.createContainer() if err != nil { - return errors.Wrapf(err, "Failed copying busybox") + return errors.Wrap(err, "failed to create container") } - err = RunCommand("ln", filepath.Join(rootfs, "bin/busybox"), filepath.Join(rootfs, "bin/stat")) - if err != nil { - return errors.Wrapf(err, "Failed linking stat") + + if err := clxc.setConfigItem("lxc.log.file", clxc.LogFilePath); err != nil { + return err } - err = RunCommand("ln", filepath.Join(rootfs, "bin/busybox"), filepath.Join(rootfs, "bin/sh")) + + err = clxc.Container.SetLogLevel(clxc.LogLevel) if err != nil { - return errors.Wrapf(err, "Failed linking sh") + return errors.Wrap(err, "failed to set container loglevel") } - err = RunCommand("ln", filepath.Join(rootfs, "bin/busybox"), filepath.Join(rootfs, "bin/tee")) - if err != nil { - return errors.Wrapf(err, "Failed linking tee") + if clxc.LogLevel == lxc.TRACE { + clxc.Container.SetVerbosity(lxc.Verbose) } - return nil -} -const ( - SYNC_FIFO_PATH = "/syncfifo" - SYNC_FIFO_CONTENT = "meshuggah rocks" -) - -func emitFifoWaiter(file string) error { - fifoWaiter := fmt.Sprintf(`#!/bin/sh -stat /syncfifo -echo "%s" | tee /syncfifo -exec $@ -`, SYNC_FIFO_CONTENT) + clxc.SpecPath = filepath.Join(clxc.BundlePath, "config.json") + spec, err := internal.ReadSpec(clxc.SpecPath) + if err != nil { + return errors.Wrap(err, "couldn't load bundle spec") + } - return ioutil.WriteFile(file, []byte(fifoWaiter), 0755) + if err := configureContainer(spec); err != nil { + return errors.Wrap(err, "failed to configure container") + } + return startContainer(spec, clxc.CreateTimeout) } -func configureNamespaces(c *lxc.Container, spec *specs.Spec) error { - procPidPathRE := regexp.MustCompile(`/proc/(\d+)/ns`) +func configureContainer(spec *specs.Spec) error { + if err := configureRootfs(spec); err != nil { + return err + } - var nsToClone []string - var configVal string - seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} - for _, ns := range spec.Linux.Namespaces { - if _, ok := seenNamespaceTypes[ns.Type]; ok { - return fmt.Errorf("duplicate namespace type %s", ns.Type) - } - seenNamespaceTypes[ns.Type] = true - if ns.Path == "" { - nsToClone = append(nsToClone, NamespaceMap[string(ns.Type)]) - } else { - configKey := fmt.Sprintf("lxc.namespace.share.%s", NamespaceMap[string(ns.Type)]) - - matches := procPidPathRE.FindStringSubmatch(ns.Path) - switch len(matches) { - case 0: - configVal = ns.Path - case 1: - return fmt.Errorf("error parsing namespace path. expected /proc/(\\d+)/ns/*, got '%s'", ns.Path) - case 2: - configVal = matches[1] - default: - return fmt.Errorf("error parsing namespace path. expected /proc/(\\d+)/ns/*, got '%s'", ns.Path) - } - - if err := c.SetConfigItem(configKey, configVal); err != nil { - return errors.Wrapf(err, "failed to set namespace config: '%s'='%s'", configKey, configVal) - } - } + if err := configureInit(spec); err != nil { + return err } - if len(nsToClone) > 0 { - configVal = strings.Join(nsToClone, " ") - if err := c.SetConfigItem("lxc.namespace.clone", configVal); err != nil { - return errors.Wrapf(err, "failed to set lxc.namespace.clone=%s", configVal) - } + if err := configureMounts(spec); err != nil { + return err } - return nil -} -func doCreate(ctx *cli.Context) error { - pidfile := ctx.String("pid-file") - containerID := ctx.Args().Get(0) - if len(containerID) == 0 { - fmt.Fprintf(os.Stderr, "missing container ID\n") - cli.ShowCommandHelpAndExit(ctx, "create", 1) + if err := configureReadonlyPaths(spec); err != nil { + return err } - log.Infof("creating container %s", containerID) - exists, err := containerExists(containerID) - if err != nil { - return errors.Wrap(err, "failed to check if container exists") + if err := configureNamespaces(spec.Linux.Namespaces); err != nil { + return errors.Wrap(err, "failed to configure namespaces") } - if exists { - return fmt.Errorf("container '%s' already exists", containerID) + + if spec.Process.OOMScoreAdj != nil { + if err := clxc.setConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *spec.Process.OOMScoreAdj)); err != nil { + return err + } } - c, err := lxc.NewContainer(containerID, LXC_PATH) - if err != nil { - return errors.Wrap(err, "failed to create new container") + if spec.Process.NoNewPrivileges { + if err := clxc.setConfigItem("lxc.no_new_privs", "1"); err != nil { + return err + } } - defer c.Release() - spec, err := readBundleSpec(filepath.Join(ctx.String("bundle"), "config.json")) - if err != nil { - return errors.Wrap(err, "couldn't load bundle spec") + if clxc.Apparmor { + if err := configureApparmor(spec); err != nil { + return errors.Wrap(err, "failed to configure apparmor") + } + } else { + log.Warn().Msg("apparmor is disabled (unconfined)") } - if err := os.MkdirAll(filepath.Join(LXC_PATH, containerID), 0770); err != nil { - return errors.Wrap(err, "failed to create container dir") + if clxc.Seccomp { + if err := configureSeccomp(spec); err != nil { + return errors.Wrap(err, "failed to configure seccomp") + } + } else { + log.Warn().Msg("seccomp is disabled") } - if err := makeSyncFifo(filepath.Join(LXC_PATH, containerID)); err != nil { - return errors.Wrap(err, "failed to make sync fifo") + if clxc.Capabilities { + if err := configureCapabilities(spec); err != nil { + return errors.Wrap(err, "failed to configure capabilities") + } + } else { + log.Warn().Msg("capabilities are disabled") } - if err := configureContainer(ctx, c, spec); err != nil { - return errors.Wrap(err, "failed to configure container") + // TODO extract all uid/gid related settings into separate function configureUserAndGroups + if err := clxc.setConfigItem("lxc.init.uid", fmt.Sprintf("%d", spec.Process.User.UID)); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.init.gid", fmt.Sprintf("%d", spec.Process.User.GID)); err != nil { + return err } - log.Infof("created syncfifo, executing %#v", spec.Process.Args) + // TODO ensure that the user namespace is enabled + // See `man lxc.container.conf` lxc.idmap. + for _, m := range spec.Linux.UIDMappings { + if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + return err + } + } - if err := startContainer(c, spec); err != nil { - return errors.Wrap(err, "failed to start the container init") + for _, m := range spec.Linux.GIDMappings { + if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + return err + } } - if pidfile != "" { - err := os.MkdirAll(path.Dir(pidfile), 0755) - if err != nil { - return errors.Wrapf(err, "Couldn't create pid file directory for %s", pidfile) + if len(spec.Process.User.AdditionalGids) > 0 && supportsConfigItem("lxc.init.groups") { + a := make([]string, 0, len(spec.Process.User.AdditionalGids)) + for _, gid := range spec.Process.User.AdditionalGids { + a = append(a, strconv.FormatUint(uint64(gid), 10)) } - err = ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d", c.InitPid())), 0755) - if err != nil { - return errors.Wrapf(err, "Couldn't create pid file %s", pidfile) + if err := clxc.setConfigItem("lxc.init.groups", strings.Join(a, " ")); err != nil { + return err } } - log.Infof("created container %s in lxcdir %s", containerID, LXC_PATH) - return nil -} - -func configureContainer(ctx *cli.Context, c *lxc.Container, spec *specs.Spec) error { - if ctx.Bool("debug") { - c.SetVerbosity(lxc.Verbose) + if err := setHostname(spec); err != nil { + return errors.Wrap(err, "set hostname") } - if err := configureLogging(ctx, c); err != nil { - return errors.Wrap(err, "failed to configure logging") + if err := ensureDefaultDevices(spec); err != nil { + return errors.Wrap(err, "failed to add default devices") } - // rootfs - // todo Root.Readonly? - use lxc.rootfs.options - if err := c.SetConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { - return errors.Wrapf(err, "failed to set rootfs: '%s'", spec.Root.Path) - } - if err := c.SetConfigItem("lxc.rootfs.managed", "0"); err != nil { - return errors.Wrap(err, "failed to set rootfs.managed to 0") + if err := configureCgroup(spec); err != nil { + return errors.Wrap(err, "failed to configure cgroups") } - for _, envVar := range spec.Process.Env { - if err := c.SetConfigItem("lxc.environment", envVar); err != nil { - return fmt.Errorf("error setting environment variable '%s': %v", envVar, err) + for key, val := range spec.Linux.Sysctl { + if err := clxc.setConfigItem("lxc.sysctl."+key, val); err != nil { + return err } } - for _, ms := range spec.Mounts { - opts := strings.Join(ms.Options, ",") - mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, opts) - if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { - return errors.Wrap(err, "failed to set mount config") + for _, limit := range spec.Process.Rlimits { + name := strings.TrimPrefix(strings.ToLower(limit.Type), "rlimit_") + val := fmt.Sprintf("%d:%d", limit.Soft, limit.Hard) + if err := clxc.setConfigItem("lxc.prlimit."+name, val); err != nil { + return err } } + return nil +} - mnt := fmt.Sprintf("%s %s none ro,bind,create=file", path.Join(LXC_PATH, c.Name(), SYNC_FIFO_PATH), strings.Trim(SYNC_FIFO_PATH, "/")) - if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { - return errors.Wrap(err, "failed to set syncfifo mount config entry") +func configureRootfs(spec *specs.Spec) error { + if err := clxc.setConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.rootfs.managed", "0"); err != nil { + return err } - err := emitFifoWaiter(path.Join(spec.Root.Path, "fifo-wait")) - if err != nil { - return errors.Wrapf(err, "couldn't write wrapper init") + // Resources not created by the container runtime MUST NOT be deleted by it. + if err := clxc.setConfigItem("lxc.ephemeral", "0"); err != nil { + return err } - if err := ensureShell(spec.Root.Path); err != nil { - return errors.Wrap(err, "couldn't ensure a shell exists in container") + rootfsOptions := []string{} + if spec.Linux.RootfsPropagation != "" { + rootfsOptions = append(rootfsOptions, spec.Linux.RootfsPropagation) + } + if spec.Root.Readonly { + rootfsOptions = append(rootfsOptions, "ro") + } + if err := clxc.setConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { + return err } + return nil +} - if err := c.SetConfigItem("lxc.init.cwd", spec.Process.Cwd); err != nil { - return errors.Wrap(err, "failed to set CWD") +func configureInit(spec *specs.Spec) error { + err := os.MkdirAll(filepath.Join(spec.Root.Path, internal.ConfigDir), 0) + if err != nil { + return errors.Wrapf(err, "Failed creating %s in rootfs", internal.ConfigDir) + } + err = os.MkdirAll(clxc.runtimePath(internal.ConfigDir), 0755) + if err != nil { + return errors.Wrapf(err, "Failed creating %s in lxc container dir", internal.ConfigDir) } - if err := c.SetConfigItem("lxc.uts.name", spec.Hostname); err != nil { - return errors.Wrap(err, "failed to set hostname") + // create named fifo in lxcpath and mount it into the container + if err := makeSyncFifo(clxc.runtimePath(internal.SyncFifoPath)); err != nil { + return errors.Wrapf(err, "failed to make sync fifo") } - argsString := "/fifo-wait " + strings.Join(spec.Process.Args, " ") - if err := c.SetConfigItem("lxc.execute.cmd", argsString); err != nil { - return errors.Wrap(err, "failed to set lxc.execute.cmd") + spec.Mounts = append(spec.Mounts, specs.Mount{ + Source: clxc.runtimePath(internal.ConfigDir), + Destination: strings.Trim(internal.ConfigDir, "/"), + Type: "bind", + Options: []string{"bind", "ro", "nodev", "nosuid"}, + }) + // pass context information as environment variables to hook scripts + if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { + return err } - if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { - return errors.Wrap(err, "failed to set hook version") + if err := clxc.setConfigItem("lxc.hook.mount", clxc.HookCommand); err != nil { + return err } - if err := configureNamespaces(c, spec); err != nil { - return errors.Wrap(err, "failed to configure namespaces") + path := "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + for _, kv := range spec.Process.Env { + if strings.HasPrefix(kv, "PATH=") { + path = kv + } + } + if err := clxc.setConfigItem("lxc.environment", path); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.environment", envStateCreated); err != nil { + return err } - // capabilities? - - // if !spec.Process.Terminal { - // passFdsToContainer() - // } + // create destination file for bind mount + initBin := clxc.runtimePath(internal.InitCmd) + err = touchFile(initBin, 0) + if err != nil { + return errors.Wrapf(err, "failed to create %s", initBin) + } + spec.Mounts = append(spec.Mounts, specs.Mount{ + Source: clxc.InitCommand, + Destination: internal.InitCmd, + Type: "bind", + Options: []string{"bind", "ro", "nosuid"}, + }) + return clxc.setConfigItem("lxc.init.cmd", internal.InitCmd) +} - // Write out final config file for debugging and use with lxc-attach: - // Do not edit config after this. - savedConfigFile := filepath.Join(LXC_PATH, c.Name(), "config") - if err := c.SaveConfigFile(savedConfigFile); err != nil { - return errors.Wrapf(err, "failed to save config file to '%s'", savedConfigFile) +func touchFile(filePath string, perm os.FileMode) error { + f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDONLY, perm) + if err == nil { + return f.Close() } + return err +} +func configureReadonlyPaths(spec *specs.Spec) error { + rootmnt := clxc.getConfigItem("lxc.rootfs.mount") + if rootmnt == "" { + return errors.New("lxc.rootfs.mount unavailable") + } + for _, p := range spec.Linux.ReadonlyPaths { + mnt := fmt.Sprintf("%s %s %s %s", filepath.Join(rootmnt, p), strings.TrimPrefix(p, "/"), "bind", "bind,ro,optional") + if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { + return errors.Wrap(err, "failed to make path readonly") + } + } return nil } -func makeSyncFifo(dir string) error { - fifoFilename := filepath.Join(dir, "syncfifo") +func makeSyncFifo(fifoFilename string) error { prevMask := unix.Umask(0000) defer unix.Umask(prevMask) - if err := unix.Mkfifo(fifoFilename, 0622); err != nil { + if err := unix.Mkfifo(fifoFilename, 0666); err != nil { return errors.Wrapf(err, "failed to make fifo '%s'", fifoFilename) } return nil } -func startContainer(c *lxc.Container, spec *specs.Spec) error { - binary, err := os.Readlink("/proc/self/exe") - if err != nil { +func configureContainerSecurity(c *lxc.Container, spec *specs.Spec) error { + return nil +} + +func configureApparmor(spec *specs.Spec) error { + // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. + aaprofile := spec.Process.ApparmorProfile + if aaprofile == "" { + aaprofile = "unconfined" + } + return clxc.setConfigItem("lxc.apparmor.profile", aaprofile) +} + +// configureCapabilities configures the linux capabilities / privileges granted to the container processes. +// See `man lxc.container.conf` lxc.cap.drop and lxc.cap.keep for details. +// https://blog.container-solutions.com/linux-capabilities-in-practice +// https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work +func configureCapabilities(spec *specs.Spec) error { + keepCaps := "none" + if spec.Process.Capabilities != nil { + var caps []string + for _, c := range spec.Process.Capabilities.Permitted { + lcCapName := strings.TrimPrefix(strings.ToLower(c), "cap_") + caps = append(caps, lcCapName) + } + keepCaps = strings.Join(caps, " ") + } + + return clxc.setConfigItem("lxc.cap.keep", keepCaps) +} + +func isDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) bool { + for _, specDev := range spec.Linux.Devices { + if specDev.Path == dev.Path { + return true + } + } + return false +} + +func addDevice(spec *specs.Spec, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { + dev.FileMode = &mode + dev.UID = &uid + dev.GID = &gid + spec.Linux.Devices = append(spec.Linux.Devices, dev) + + addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) +} + +func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64, access string) { + devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) +} + +// ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) +// to the given container spec if required. +// crio can add devices to containers, but this does not work for privileged containers. +// See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 +// TODO file an issue on cri-o (at least for support) +func ensureDefaultDevices(spec *specs.Spec) error { + // make sure autodev is disabled + if err := clxc.setConfigItem("lxc.autodev", "0"); err != nil { return err } - cmd := exec.Command( - binary, - "internal", - c.Name(), - LXC_PATH, - filepath.Join(LXC_PATH, c.Name(), "config"), - ) + mode := os.FileMode(0666) + var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID + + devices := []specs.LinuxDevice{ + specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, + specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, + specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, + specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, + specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, + specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, + // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? + // `man 2 mount` | devpts + // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. + // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` + } + + ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} + addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx + + pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} + addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] + + // add missing default devices + for _, dev := range devices { + if !isDeviceEnabled(spec, dev) { + addDevice(spec, dev, mode, uid, gid, "rwm") + } + } + return nil +} +func startContainer(spec *specs.Spec, timeout time.Duration) error { + configFilePath := clxc.runtimePath("config") + cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, configFilePath) + // Start container with a clean environment. + // LXC will export variables defined in the config lxc.environment. + // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. + // This is required because environment variables defined by containers contain newlines and other tokens + // that can not be handled properly by lxc. + cmd.Env = []string{} + + if clxc.ConsoleSocket != "" { + if err := saveConfig(configFilePath); err != nil { + return err + } + return startConsole(cmd, clxc.ConsoleSocket) + } if !spec.Process.Terminal { + // Inherit stdio from calling process (conmon). + // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc + if err := clxc.setConfigItem("lxc.console.path", "none"); err != nil { + return errors.Wrap(err, "failed to disable PTY") + } cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr } - cmdErr := cmd.Start() + if err := saveConfig(configFilePath); err != nil { + return err + } + + if err := internal.WriteSpec(spec, clxc.runtimePath(internal.InitSpec)); err != nil { + return errors.Wrapf(err, "failed to write init spec") + } + + err := cmd.Start() + if err != nil { + return err + } - if cmdErr == nil { - if !c.Wait(lxc.RUNNING, 30*time.Second) { - cmdErr = fmt.Errorf("Container failed to initialize") + if clxc.PidFile != "" { + log.Debug().Str("path:", clxc.PidFile).Msg("creating PID file") + err := createPidFile(clxc.PidFile, cmd.Process.Pid) + if err != nil { + return err } } - return cmdErr + log.Debug().Msg("waiting for container creation") + return clxc.waitContainerCreated(timeout) +} + +func saveConfig(configFilePath string) error { + // Write out final config file for debugging and use with lxc-attach: + // Do not edit config after this. + err := clxc.Container.SaveConfigFile(configFilePath) + log.Debug().Err(err).Str("config", configFilePath).Msg("save config file") + if err != nil { + return errors.Wrapf(err, "failed to save config file to '%s'", configFilePath) + } + return nil +} + +func startConsole(cmd *exec.Cmd, consoleSocket string) error { + addr, err := net.ResolveUnixAddr("unix", consoleSocket) + if err != nil { + return errors.Wrap(err, "failed to resolve console socket") + } + conn, err := net.DialUnix("unix", nil, addr) + if err != nil { + return errors.Wrap(err, "connecting to console socket failed") + } + defer conn.Close() + deadline := time.Now().Add(time.Second * 10) + err = conn.SetDeadline(deadline) + if err != nil { + return errors.Wrap(err, "failed to set connection deadline") + } + + sockFile, err := conn.File() + if err != nil { + return errors.Wrap(err, "failed to get file from unix connection") + } + ptmx, err := pty.Start(cmd) + if err != nil { + return errors.Wrap(err, "failed to start with pty") + } + + // Send the pty file descriptor over the console socket (to the 'conmon' process) + // For technical backgrounds see: + // man sendmsg 2', 'man unix 3', 'man cmsg 1' + // see https://blog.cloudflare.com/know-your-scm_rights/ + oob := unix.UnixRights(int(ptmx.Fd())) + // Don't know whether 'terminal' is the right data to send, but conmon doesn't care anyway. + err = unix.Sendmsg(int(sockFile.Fd()), []byte("terminal"), oob, nil, 0) + if err != nil { + return errors.Wrap(err, "failed to send console fd") + } + return ptmx.Close() +} + +func setHostname(spec *specs.Spec) error { + if spec.Hostname == "" { + return nil + } + + if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { + return err + } + + // lxc does not set the hostname on shared namespaces + for _, ns := range spec.Linux.Namespaces { + if ns.Type != specs.UTSNamespace { + continue + } + + // namespace is not shared + if ns.Path == "" { + return nil + } + + f, err := os.Open(ns.Path) + if err != nil { + return errors.Wrapf(err, "failed to open uts namespace %s", ns.Path) + } + defer f.Close() + + // setns only affects the current thread + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err = unix.Setns(int(f.Fd()), unix.CLONE_NEWUTS) + if err != nil { + return err + } + return unix.Sethostname([]byte(spec.Hostname)) + } + return nil } diff --git a/cmd/delete.go b/cmd/delete.go index 02b6a69e..5a37b724 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -2,13 +2,17 @@ package main import ( "fmt" + "io/ioutil" "os" "path/filepath" + "strconv" + "strings" + "time" - "github.com/apex/log" "github.com/pkg/errors" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" + "golang.org/x/sys/unix" lxc "gopkg.in/lxc/go-lxc.v2" ) @@ -21,7 +25,7 @@ var deleteCmd = cli.Command{ is the ID of the container to delete `, Flags: []cli.Flag{ - cli.BoolFlag{ + &cli.BoolFlag{ Name: "force", Usage: "force deletion", }, @@ -29,59 +33,146 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { - containerID := ctx.Args().Get(0) - if len(containerID) == 0 { - fmt.Fprintf(os.Stderr, "missing container ID\n") - cli.ShowCommandHelpAndExit(ctx, "state", 1) + err := clxc.loadContainer() + if err == errContainerNotExist && ctx.Bool("force") { + return nil } - - exists, err := containerExists(containerID) if err != nil { - return errors.Wrap(err, "failed to check if container exists") + return err } - if !exists { - return fmt.Errorf("container '%s' not found", containerID) + c := clxc.Container + + state := c.State() + if state != lxc.STOPPED { + if !ctx.Bool("force") { + return fmt.Errorf("container must be stopped before delete (current state is %s)", state) + } + + if err := c.Stop(); err != nil { + return errors.Wrap(err, "failed to stop container") + } } - c, err := lxc.NewContainer(containerID, LXC_PATH) - if err != nil { - return errors.Wrap(err, "failed to load container") + if err := c.Destroy(); err != nil { + return errors.Wrap(err, "failed to delete container") } - defer c.Release() - if err := configureLogging(ctx, c); err != nil { - return errors.Wrap(err, "failed to configure logging") + if dir := clxc.getConfigItem("lxc.cgroup.dir"); dir != "" { + if err := tryRemoveAllCgroupDir(c, dir, true); err != nil { + log.Warn().Err(err).Msg("remove lxc.cgroup.dir failed") + } else { + // try to remove outer directory, in case this is the POD that is deleted + // FIXME crio should delete the kubepods slice + tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) + } + } + if dir := clxc.getConfigItem("lxc.cgroup.dir.container"); dir != "" { + if err := tryRemoveAllCgroupDir(c, dir, true); err != nil { + log.Warn().Err(err).Msg("remove lxc.cgroup.dir.container failed") + } else { + // try to remove outer directory, in case this is the POD that is deleted + // FIXME crio should delete the kubepods slice + tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) + } } - force := ctx.Bool("force") - if c.Running() { - if checkHackyPreStart(c) == "started" && !force { - return fmt.Errorf("container '%s' is running, cannot delete.", containerID) + // "Note that resources associated with the container, + // but not created by this container, MUST NOT be deleted." + // TODO - because we set rootfs.managed=0, Destroy() doesn't + // delete the /var/lib/lxc/$containerID/config file: + return os.RemoveAll(clxc.runtimePath()) +} + +func tryRemoveAllCgroupDir(c *lxc.Container, cgroupPath string, killProcs bool) error { + dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) + dir, err := os.Open(dirName) + if os.IsNotExist(err) { + return nil + } + if err != nil { + return err + } + if killProcs { + err := loopKillCgroupProcs(dirName, time.Second*2) + if err != nil { + log.Trace().Err(err).Str("dir:", dirName).Msg("failed to kill cgroup procs") } - if err := c.Stop(); err != nil { - log.Warnf("Failed to stop pre-started container %s: %v", containerID, err) + } + entries, err := dir.Readdir(-1) + if err != nil { + return err + } + // leftover lxc.pivot path + for _, i := range entries { + if i.IsDir() && i.Name() != "." && i.Name() != ".." { + fullPath := filepath.Join(dirName, i.Name()) + if err := unix.Rmdir(fullPath); err != nil { + return errors.Wrapf(err, "failed rmdir %s", fullPath) + } } } + return unix.Rmdir(dirName) +} - // TODO: lxc-destroy deletes the rootfs. - // this appears to contradict the runtime spec: - - // "Note that resources associated with the container, - // but not created by this container, MUST NOT be deleted.Note - // that resources associated with the container, but not - // created by this container, MUST NOT be deleted. +// loopKillCgroupProcs loops over PIDs in cgroup.procs and sends +// each PID the kill signal until there are no more PIDs left. +// Looping is required because processes that have been created (forked / exec) +// may not 'yet' be visible in cgroup.procs. +func loopKillCgroupProcs(scope string, timeout time.Duration) error { + timer := time.NewTimer(timeout) + defer timer.Stop() + for { + select { + case <-timer.C: + return fmt.Errorf("timeout killing processes") + default: + nprocs, err := killCgroupProcs(scope) + if err != nil { + return err + } + if nprocs == 0 { + return nil + } + time.Sleep(time.Millisecond * 50) + } + } +} - if err := c.Destroy(); err != nil { - return errors.Wrap(err, "failed to delete container.") +// getCgroupProcs returns the PIDs for all processes which are in the +// same control group as the process for which the PID is given. +func killCgroupProcs(scope string) (int, error) { + cgroupProcsPath := filepath.Join(scope, "cgroup.procs") + log.Trace().Str("path:", cgroupProcsPath).Msg("reading control group process list") + procsData, err := ioutil.ReadFile(cgroupProcsPath) + if err != nil { + return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) + } + // cgroup.procs contains one PID per line and is newline separated. + // A trailing newline is always present. + s := strings.TrimSpace(string(procsData)) + if s == "" { + return 0, nil + } + pidStrings := strings.Split(s, "\n") + numPids := len(pidStrings) + if numPids == 0 { + return 0, nil } - // TODO - because we set rootfs.managed=0, Destroy() doesn't - // delete the /var/lib/lxc/$containerID/config file: - configDir := filepath.Join(LXC_PATH, containerID) - if err := os.RemoveAll(configDir); err != nil { - return errors.Wrapf(err, "failed to remove %s", configDir) + // This indicates improper signal handling / termination of the container. + log.Warn().Strs("pids:", pidStrings).Str("cgroup:", scope).Msg("killing left-over container processes") + + for _, s := range pidStrings { + pid, err := strconv.Atoi(s) + if err != nil { + // Reading garbage from cgroup.procs should not happen. + return -1, errors.Wrapf(err, "failed to convert PID %q to number", s) + } + if err := unix.Kill(pid, 9); err != nil { + return -1, errors.Wrapf(err, "failed to kill %d", pid) + } } - return nil + return numPids, nil } diff --git a/cmd/exec.go b/cmd/exec.go index 4aea1764..b241b655 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -40,7 +40,7 @@ var execCmd = cli.Command{ } func doExec(ctx *cli.Context) error { - err := clxc.LoadContainer() + err := clxc.loadContainer() if err != nil { return errors.Wrap(err, "failed to load container") } @@ -89,12 +89,12 @@ func doExec(ctx *cli.Context) error { } // Load container spec to get the list of supported namespaces. - spec, err := internal.ReadSpec(clxc.RuntimePath(internal.INIT_SPEC)) + spec, err := internal.ReadSpec(clxc.runtimePath(internal.InitSpec)) if err != nil { return errors.Wrap(err, "failed to read container runtime spec") } for _, ns := range spec.Linux.Namespaces { - n, supported := NamespaceMap[ns.Type] + n, supported := namespaceMap[ns.Type] if !supported { return fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) } @@ -120,12 +120,13 @@ func doExec(ctx *cli.Context) error { return nil } return createPidFile(pidFile, pid) - } else { - exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) - if err != nil { - return errors.Wrapf(err, "c.RunCommandStatus returned with exit code %d", exitStatus) - } - log.Debug().Int("exit", exitStatus).Msg("cmd executed synchronous") } + + exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) + if err != nil { + return errors.Wrapf(err, "c.RunCommandStatus returned with exit code %d", exitStatus) + } + log.Debug().Int("exit", exitStatus).Msg("cmd executed synchronous") + return nil } diff --git a/cmd/hook/hook.go b/cmd/hook/hook.go index 807a2d3d..5112560a 100644 --- a/cmd/hook/hook.go +++ b/cmd/hook/hook.go @@ -25,7 +25,7 @@ func main() { fail(err, "stat for rootfs mount failed "+rootfs) } - specPath := filepath.Join(rootfs, internal.INIT_SPEC) + specPath := filepath.Join(rootfs, internal.InitSpec) spec, err := internal.ReadSpec(specPath) if err != nil { fail(err, "parse spec "+specPath) @@ -75,6 +75,7 @@ func createDevice(spec *specs.Spec, dev specs.LinuxDevice) error { devMode = int(unix.Mkdev(uint32(dev.Major), uint32(dev.Minor))) } + // ignore error (mknod will fail) os.MkdirAll(filepath.Dir(dev.Path), 0755) err := unix.Mknod(dev.Path, mode, devMode) diff --git a/cmd/init/init.go b/cmd/init/init.go index 7dd3edff..8b6e2d22 100644 --- a/cmd/init/init.go +++ b/cmd/init/init.go @@ -14,17 +14,17 @@ func fail(err error, step string) { } func main() { - spec, err := internal.ReadSpec(internal.INIT_SPEC) + spec, err := internal.ReadSpec(internal.InitSpec) if err != nil { panic(err) } - fifo, err := os.OpenFile(internal.SYNC_FIFO_PATH, os.O_WRONLY, 0) + fifo, err := os.OpenFile(internal.SyncFifoPath, os.O_WRONLY, 0) if err != nil { fail(err, "open sync fifo") } - _, err = fifo.Write([]byte(internal.SYNC_FIFO_CONTENT)) + _, err = fifo.Write([]byte(internal.SyncFifoContent)) if err != nil { fail(err, "write to sync fifo") } diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go index a5f0949a..25f1c140 100644 --- a/cmd/internal/internal.go +++ b/cmd/internal/internal.go @@ -7,14 +7,20 @@ import ( ) const ( - // CFG_DIR is bind mounted (readonly) to container - CFG_DIR = "/.crio-lxc" - SYNC_FIFO_PATH = CFG_DIR + "/syncfifo" - SYNC_FIFO_CONTENT = "meshuggah rocks" - INIT_CMD = CFG_DIR + "/init" - INIT_SPEC = CFG_DIR + "/spec.json" + // ConfigDir is the path to the crio-lxc resources relative to the container rootfs. + ConfigDir = "/.crio-lxc" + // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. + SyncFifoPath = ConfigDir + "/syncfifo" + // SyncFifoContent is the content exchanged through the sync fifo. + SyncFifoContent = "meshuggah rocks" + // InitCmd is the path where the init binary is bind mounted. + InitCmd = ConfigDir + "/init" + // InitSpec is the path where the modified runtime spec is written to. + // The init command loads the spec from this path. + InitSpec = ConfigDir + "/spec.json" ) +// ReadSpec deserializes the JSON encoded runtime spec from the given path. func ReadSpec(specFilePath string) (*specs.Spec, error) { specFile, err := os.Open(specFilePath) if err != nil { @@ -29,11 +35,15 @@ func ReadSpec(specFilePath string) (*specs.Spec, error) { return spec, nil } +// WriteSpec serializes the runtime spec to JSON and writes it to the given path. func WriteSpec(spec *specs.Spec, specFilePath string) error { f, err := os.OpenFile(specFilePath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0444) if err != nil { return err } defer f.Close() - return json.NewEncoder(f).Encode(spec) + if err := json.NewEncoder(f).Encode(spec); err != nil { + return err + } + return f.Sync() } diff --git a/cmd/kill.go b/cmd/kill.go index 3af4ddfe..c645c77e 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -1,36 +1,31 @@ +// +build go1.10 + package main import ( "fmt" - "os" - "syscall" + "strconv" "golang.org/x/sys/unix" - //"github.com/apex/log" "github.com/pkg/errors" - "github.com/urfave/cli" - - lxc "gopkg.in/lxc/go-lxc.v2" + "github.com/urfave/cli/v2" ) var killCmd = cli.Command{ Name: "kill", Usage: "sends a signal to a container", Action: doKill, - ArgsUsage: `[containerID] + ArgsUsage: `[containerID] [signal] is the ID of the container to send a signal to +[signal] name (without SIG) or signal num ? `, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "signal", - Usage: "the signal to send, as a string", - Value: "TERM", - }, - }, } -var signalMap = map[string]syscall.Signal{ + +const sigzero = unix.Signal(0) + +var signalMap = map[string]unix.Signal{ "ABRT": unix.SIGABRT, "ALRM": unix.SIGALRM, "BUS": unix.SIGBUS, @@ -67,39 +62,53 @@ var signalMap = map[string]syscall.Signal{ "XFSZ": unix.SIGXFSZ, } -func doKill(ctx *cli.Context) error { - containerID := ctx.Args().Get(0) - if len(containerID) == 0 { - fmt.Fprintf(os.Stderr, "missing container ID\n") - cli.ShowCommandHelpAndExit(ctx, "state", 1) +// Retrieve the PID from container init process safely. +func getSignal(ctx *cli.Context) (unix.Signal, error) { + sig := ctx.Args().Get(1) + if len(sig) == 0 { + return sigzero, errors.New("missing signal") } - exists, err := containerExists(containerID) - if err != nil { - return errors.Wrap(err, "failed to check if container exists") + // handle numerical signal value + if num, err := strconv.Atoi(sig); err == nil { + for _, signum := range signalMap { + if num == int(signum) { + return signum, nil + } + } + return sigzero, fmt.Errorf("signal %s does not exist", sig) } + + // handle string signal value + signum, exists := signalMap[sig] if !exists { - return fmt.Errorf("container '%s' not found", containerID) + return unix.Signal(0), fmt.Errorf("signal %s does not exist", sig) } + return signum, nil +} - c, err := lxc.NewContainer(containerID, LXC_PATH) +func doKill(ctx *cli.Context) error { + err := clxc.loadContainer() if err != nil { return errors.Wrap(err, "failed to load container") } - defer c.Release() - - if err := configureLogging(ctx, c); err != nil { - return errors.Wrap(err, "failed to configure logging") + // Attempting to send a signal to a container that is neither created nor running + // MUST have no effect on the container and MUST generate an error. + if !clxc.Container.Running() { + return fmt.Errorf("container is not running") } - if c.Running() && checkHackyPreStart(c) == "started" { - pid := c.InitPid() - - if err := unix.Kill(pid, signalMap[ctx.String("signal")]); err != nil { - return errors.Wrap(err, "failed to send signal") - } - return nil + signum, err := getSignal(ctx) + if err != nil { + return errors.Wrap(err, "invalid signal param") + } + pid, proc := clxc.safeGetInitPid() + if proc != nil { + defer proc.Close() + } + if pid <= 0 { + return errors.New("init process is not running") } - return fmt.Errorf("container '%s' is not running", containerID) + return unix.Kill(pid, signum) } diff --git a/cmd/main.go b/cmd/main.go index 72e0e5d0..7ba77e10 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -12,30 +12,27 @@ import ( ) const ( - // IMPORTANT should be synced with the runtime-spec dependency in go.mod - // github.com/opencontainers/runtime-spec v1.0.2 - CURRENT_OCI_VERSION = "1.0.2" // Environment variables are populated by default from this environment file. // Existing environment variables are preserved. - EnvFileDefault = "/etc/default/crio-lxc" - // This environment variable can be used to overwrite the path in EnvFileDefault. - EnvFileVar = "CRIO_LXC_DEFAULTS" + envFileDefault = "/etc/default/crio-lxc" + // This environment variable can be used to overwrite the path in envFileDefault. + envFileVar = "CRIO_LXC_DEFAULTS" ) -var version string -var clxc CrioLXC +var clxc crioLXC func main() { app := cli.NewApp() app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" - app.Version = clxc.VersionString() + app.Version = versionString() app.Commands = []*cli.Command{ &stateCmd, &createCmd, &startCmd, &killCmd, &deleteCmd, + &execCmd, } app.Flags = []cli.Flag{ @@ -52,6 +49,28 @@ func main() { EnvVars: []string{"CRIO_LXC_LOG_FILE", "LOG_FILE"}, Value: "/var/log/crio-lxc.log", Destination: &clxc.LogFilePath, + }, + &cli.StringFlag{ + Name: "backup-dir", + Usage: "directory for container runtime directory backups", + EnvVars: []string{"CRIO_LXC_BACKUP_DIR"}, + Value: "/var/lib/crio-lxc/backup", + Destination: &clxc.BackupDir, + }, + &cli.BoolFlag{ + Name: "backup-on-error", + Usage: "backup container runtime directory when cmd-start fails", + EnvVars: []string{"CRIO_LXC_BACKUP_ON_ERROR"}, + Value: true, + Destination: &clxc.BackupOnError, + }, + &cli.BoolFlag{ + Name: "backup", + Usage: "backup every container runtime before cmd-start is called", + EnvVars: []string{"CRIO_LXC_BACKUP"}, + Value: false, + Destination: &clxc.Backup, + }, &cli.StringFlag{ Name: "root", Aliases: []string{"lxc-path"}, // 'root' is used by crio/conmon @@ -59,6 +78,67 @@ func main() { Value: "/var/lib/lxc", Destination: &clxc.RuntimeRoot, }, + &cli.BoolFlag{ + Name: "systemd-cgroup", + Usage: "enable systemd cgroup", + Destination: &clxc.SystemdCgroup, + }, + &cli.StringFlag{ + Name: "monitor-cgroup", + Usage: "cgroup for LXC monitor processes", + Destination: &clxc.MonitorCgroup, + EnvVars: []string{"CRIO_LXC_MONITOR_CGROUP"}, + Value: "crio-lxc-monitor.slice", + }, + &cli.StringFlag{ + Name: "cmd-init", + Usage: "Absolute path to container init binary", + EnvVars: []string{"CRIO_LXC_CMD_INIT"}, + Value: "/usr/local/bin/crio-lxc-init", + Destination: &clxc.InitCommand, + }, + &cli.StringFlag{ + Name: "cmd-start", + Usage: "Name or path to container start binary", + EnvVars: []string{"CRIO_LXC_CMD_START"}, + Value: "crio-lxc-start", + Destination: &clxc.StartCommand, + }, + &cli.StringFlag{ + Name: "cmd-hook", + Usage: "Name or path to binary executed in lxc.hook.mount", + EnvVars: []string{"CRIO_LXC_CMD_HOOK"}, + Value: "/usr/local/bin/crio-lxc-hook", + Destination: &clxc.HookCommand, + }, + &cli.BoolFlag{ + Name: "seccomp", + Usage: "Generate and apply seccomp profile for lxc from container spec", + Destination: &clxc.Seccomp, + EnvVars: []string{"CRIO_LXC_SECCOMP"}, + Value: true, + }, + &cli.BoolFlag{ + Name: "capabilities", + Usage: "Keep capabilities defined in container spec", + Destination: &clxc.Capabilities, + EnvVars: []string{"CRIO_LXC_CAPABILITIES"}, + Value: true, + }, + &cli.BoolFlag{ + Name: "apparmor", + Usage: "Set apparmor profile defined in container spec", + Destination: &clxc.Apparmor, + EnvVars: []string{"CRIO_LXC_APPARMOR"}, + Value: true, + }, + &cli.BoolFlag{ + Name: "cgroup-devices", + Usage: "Allow only devices permitted by container spec", + Destination: &clxc.CgroupDevices, + EnvVars: []string{"CRIO_LXC_CGROUP_DEVICES"}, + Value: true, + }, } startTime := time.Now() @@ -110,8 +190,8 @@ func main() { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } - envFile := EnvFileDefault - if s, isSet := os.LookupEnv(EnvFileVar); isSet { + envFile := envFileDefault + if s, isSet := os.LookupEnv(envFileVar); isSet { envFile = s } if err := loadEnvDefaults(envFile); err != nil { @@ -127,7 +207,9 @@ func main() { log.Info().Dur("duration:", cmdDuration).Msg("cmd done") } - clxc.Release() + if err := clxc.release(); err != nil { + log.Error().Err(err).Msg("failed to release container") + } if err != nil { // write diagnostics message to stderr for crio/kubelet println(err.Error()) @@ -163,7 +245,10 @@ func loadEnvDefaults(envFile string) error { val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) // existing environment variables have precedence if _, exist := os.LookupEnv(key); !exist { - os.Setenv(key, val) + err := os.Setenv(key, val) + if err != nil { + return errors.Wrap(err, "setenv failed") + } } } return nil diff --git a/cmd/mount.go b/cmd/mount.go new file mode 100644 index 00000000..bd49cb0d --- /dev/null +++ b/cmd/mount.go @@ -0,0 +1,173 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" +) + +func configureMounts(spec *specs.Spec) error { + // excplicitly disable auto-mounting + if err := clxc.setConfigItem("lxc.mount.auto", ""); err != nil { + return err + } + + for i, _ := range spec.Mounts { + ms := spec.Mounts[i] + if ms.Type == "cgroup" { + // TODO check if hieararchy is cgroup v2 only (unified mode) + ms.Type = "cgroup2" + ms.Source = "cgroup2" + // cgroup filesystem is automounted even with lxc.rootfs.managed = 0 + // from 'man lxc.container.conf': + // If cgroup namespaces are enabled, then any cgroup auto-mounting request will be ignored, + // since the container can mount the filesystems itself, and automounting can confuse the container. + } + + // TODO replace with symlink.FollowSymlinkInScope(filepath.Join(rootfs, "/etc/passwd"), rootfs) ? + // "github.com/docker/docker/pkg/symlink" + mountDest, err := resolveMountDestination(spec.Root.Path, ms.Destination) + // Intermediate path resolution failed. This is not an error, since + // the remaining directories / files are automatically created (create=dir|file) + log.Trace().Err(err).Str("dst:", ms.Destination).Str("effective:", mountDest).Msg("resolve mount destination") + + // Check whether the resolved destination of the target link escapes the rootfs. + if !filepath.HasPrefix(mountDest, spec.Root.Path) { + // refuses mount destinations that escape from rootfs + return fmt.Errorf("security violation: resolved mount destination path %s escapes from container root %s", mountDest, spec.Root.Path) + } + ms.Destination = mountDest + + err = createMountDestination(spec, &ms) + if err != nil { + return errors.Wrapf(err, "failed to create mount destination %s", ms.Destination) + } + + mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, strings.Join(ms.Options, ",")) + + if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { + return err + } + } + return nil +} + +// createMountDestination creates non-existent mount destination paths. +// This is required if rootfs is mounted readonly. +// When the source is a file that should be bind mounted a destination file is created. +// In any other case a target directory is created. +// We add 'create=dir' or 'create=file' to mount options because the mount destination +// may be shadowed by a previous mount. In this case lxc will create the mount destination. +// TODO check whether this is desired behaviour in lxc ? +// Shouldn't the rootfs should be mounted readonly after all mounts destination directories have been created ? +// https://github.com/lxc/lxc/issues/1702 +func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { + info, err := os.Stat(ms.Source) + if err != nil && ms.Type == "bind" { + // check if mountpoint is optional ? + return errors.Wrapf(err, "failed to access source %s for bind mount", ms.Source) + } + + if err == nil && !info.IsDir() { + ms.Options = append(ms.Options, "create=file") + // source exists and is not a directory + // create a target file that can be used as target for a bind mount + err := os.MkdirAll(filepath.Dir(ms.Destination), 0750) + log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create parent directory for file bind mount") + if err != nil { + return errors.Wrap(err, "failed to create mount destination dir") + } + f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0440) + log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create file bind mount destination") + if err != nil { + return errors.Wrap(err, "failed to create file mountpoint") + } + return f.Close() + } + ms.Options = append(ms.Options, "create=dir") + // FIXME exclude all directories that are below other mounts + // only directories / files on the readonly rootfs must be created + err = os.MkdirAll(ms.Destination, 0750) + log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create mount destination directory") + if err != nil { + return errors.Wrap(err, "failed to create mount destination") + } + return nil +} + +func resolvePathRelative(rootfs string, currentPath string, subPath string) (string, error) { + log.Trace().Str("current:", currentPath).Str("sub:", subPath).Msg("resolve path relative") + p := filepath.Join(currentPath, subPath) + + stat, err := os.Lstat(p) + if err != nil { + // target does not exist, resolution ends here + return p, err + } + + if stat.Mode()&os.ModeSymlink == 0 { + log.Trace().Str("filepath:", p).Msg("is not a symlink") + return p, nil + } + // resolve symlink + + linkDst, err := os.Readlink(p) + if err != nil { + return p, err + } + + log.Trace().Str("link:", p).Str("dst:", linkDst).Msg("symlink detected") + + // The destination of an absolute link must be prefixed with the rootfs + if filepath.IsAbs(linkDst) { + if filepath.HasPrefix(linkDst, rootfs) { + return p, nil + } + return filepath.Join(rootfs, linkDst), nil + } + + // The link target is relative to currentPath. + return filepath.Clean(filepath.Join(currentPath, linkDst)), nil +} + +// resolveMountDestination resolves mount destination paths for LXC. +// +// Symlinks in mount mount destination paths are not allowed in LXC. +// See CVE-2015-1335: Protect container mounts against symlinks +// and https://github.com/lxc/lxc/commit/592fd47a6245508b79fe6ac819fe6d3b2c1289be +// Mount targets that contain symlinks should be resolved relative to the container rootfs. +// e.g k8s service account tokens are mounted to /var/run/secrets/kubernetes.io/serviceaccount +// but /var/run is (mostly) a symlink to /run, so LXC denies to mount the serviceaccount token. +// +// The mount destination must be either relative to the container root or absolute to +// the directory on the host containing the rootfs. +// LXC simply ignores relative mounts paths to an absolute rootfs. +// See man lxc.container.conf #MOUNT POINTS +// +// The mount option `create=dir` should be set when the error os.ErrNotExist is returned. +// The non-existent directories are then automatically created by LXC. + +// source /var/run/containers/storage/overlay-containers/51230afad17aa3b42901f6d9efcba406511821b7e18b2223a6b4c43f9327ce97/userdata/resolv.conf +// destination /etc/resolv.conf +func resolveMountDestination(rootfs string, dst string) (dstPath string, err error) { + // get path entries + entries := strings.Split(strings.TrimPrefix(dst, "/"), "/") + + currentPath := rootfs + // start path resolution at rootfs + for i, entry := range entries { + currentPath, err = resolvePathRelative(rootfs, currentPath, entry) + log.Trace().Err(err).Str("dst:", currentPath).Msg("path resolved") + if err != nil { + // The already resolved path is concatenated with the remaining path, + // if resolution of path fails at some point. + currentPath = filepath.Join(currentPath, filepath.Join(entries[i+1:]...)) + break + } + } + return currentPath, err +} diff --git a/cmd/mount_test.go b/cmd/mount_test.go new file mode 100644 index 00000000..ca53770b --- /dev/null +++ b/cmd/mount_test.go @@ -0,0 +1,72 @@ +package main + +import ( + "github.com/stretchr/testify/require" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestResolveMountDestination_absolute(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "golang.test") + require.NoError(t, err) + defer os.RemoveAll(tmpdir) + err = os.MkdirAll(filepath.Join(tmpdir, "folder1"), 0750) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(tmpdir, "folder2"), 0750) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(tmpdir, "folder3"), 0750) + require.NoError(t, err) + err = os.Symlink("/folder2", filepath.Join(tmpdir, "folder1", "f2")) + require.NoError(t, err) + err = os.Symlink("/folder3", filepath.Join(tmpdir, "folder2", "f3")) + require.NoError(t, err) + err = ioutil.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) + require.NoError(t, err) + + p, err := resolveMountDestination(tmpdir, "/folder1/f2/f3/test.txt") + require.Equal(t, filepath.Join(tmpdir, "/folder3/test.txt"), p) + require.NoError(t, err) + + p, err = resolveMountDestination(tmpdir, "/folder1/f2/xxxxx/fooo") + require.Equal(t, filepath.Join(tmpdir, "/folder2/xxxxx/fooo"), p) + require.Error(t, err, os.ErrExist) + + p, err = resolveMountDestination(tmpdir, "/folder1/f2/f3/hello.txt") + require.Equal(t, filepath.Join(tmpdir, "/folder3/hello.txt"), p) + require.Error(t, err, os.ErrExist) +} + +func TestResolveMountDestination_relative(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "golang.test") + require.NoError(t, err) + defer os.RemoveAll(tmpdir) + err = os.MkdirAll(filepath.Join(tmpdir, "folder1"), 0750) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(tmpdir, "folder2"), 0750) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(tmpdir, "folder3"), 0750) + require.NoError(t, err) + err = os.Symlink("../folder2", filepath.Join(tmpdir, "folder1", "f2")) + require.NoError(t, err) + err = os.Symlink("../folder3", filepath.Join(tmpdir, "folder2", "f3")) + require.NoError(t, err) + err = ioutil.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) + require.NoError(t, err) + + //err = os.Symlink("../../folder2", filepath.Join(tmpdir, "folder1", "f2")) + //require.NoError(t, err) + + p, err := resolveMountDestination(tmpdir, "/folder1/f2/f3/test.txt") + require.Equal(t, filepath.Join(tmpdir, "/folder3/test.txt"), p) + require.NoError(t, err) + + p, err = resolveMountDestination(tmpdir, "/folder1/f2/xxxxx/fooo") + require.Equal(t, filepath.Join(tmpdir, "/folder2/xxxxx/fooo"), p) + require.Error(t, err, os.ErrExist) + + p, err = resolveMountDestination(tmpdir, "/folder1/f2/f3/hello.txt") + require.Equal(t, filepath.Join(tmpdir, "/folder3/hello.txt"), p) + require.Error(t, err, os.ErrExist) +} diff --git a/cmd/namespaces.go b/cmd/namespaces.go new file mode 100644 index 00000000..41caca58 --- /dev/null +++ b/cmd/namespaces.go @@ -0,0 +1,69 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" +) + +type namespace struct { + Name string + CloneFlag int +} + +// maps from CRIO namespace names to LXC names and clone flags +var namespaceMap = map[specs.LinuxNamespaceType]namespace{ + specs.CgroupNamespace: namespace{"cgroup", unix.CLONE_NEWCGROUP}, + specs.IPCNamespace: namespace{"ipc", unix.CLONE_NEWIPC}, + specs.MountNamespace: namespace{"mnt", unix.CLONE_NEWNS}, + specs.NetworkNamespace: namespace{"net", unix.CLONE_NEWNET}, + specs.PIDNamespace: namespace{"pid", unix.CLONE_NEWPID}, + specs.UserNamespace: namespace{"user", unix.CLONE_NEWUSER}, + specs.UTSNamespace: namespace{"uts", unix.CLONE_NEWUTS}, +} + +func configureNamespaces(namespaces []specs.LinuxNamespace) error { + seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} + for _, ns := range namespaces { + if _, ok := seenNamespaceTypes[ns.Type]; ok { + return fmt.Errorf("duplicate namespace type %s", ns.Type) + } + seenNamespaceTypes[ns.Type] = true + if ns.Path == "" { + continue + } + + n, supported := namespaceMap[ns.Type] + if !supported { + return fmt.Errorf("Unsupported namespace %s", ns.Type) + } + configKey := fmt.Sprintf("lxc.namespace.share.%s", n.Name) + if err := clxc.setConfigItem(configKey, ns.Path); err != nil { + return err + } + } + + // from `man lxc.container.conf` - user and network namespace must be inherited together + if !seenNamespaceTypes[specs.NetworkNamespace] && seenNamespaceTypes[specs.UserNamespace] { + return fmt.Errorf("to inherit the network namespace the user namespace must be inherited as well") + } + + nsToKeep := make([]string, 0, len(namespaceMap)) + for key, n := range namespaceMap { + if !seenNamespaceTypes[key] { + nsToKeep = append(nsToKeep, n.Name) + } + } + return clxc.setConfigItem("lxc.namespace.keep", strings.Join(nsToKeep, " ")) +} + +func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool { + for _, ns := range spec.Linux.Namespaces { + if ns.Type == nsType { + return true + } + } + return false +} diff --git a/cmd/seccomp.go b/cmd/seccomp.go new file mode 100644 index 00000000..12f9b8e0 --- /dev/null +++ b/cmd/seccomp.go @@ -0,0 +1,144 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "os" + "strings" + + "golang.org/x/sys/unix" + + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" +) + +var seccompAction = map[specs.LinuxSeccompAction]string{ + specs.ActKill: "kill", + specs.ActTrap: "trap", + specs.ActErrno: "errno", + specs.ActAllow: "allow", + //specs.ActTrace: "trace", + //specs.ActLog: "log", + //specs.ActKillProcess: "kill_process", +} + +func configureSeccomp(spec *specs.Spec) error { + if spec.Linux.Seccomp == nil || len(spec.Linux.Seccomp.Syscalls) == 0 { + return nil + } + + profilePath := clxc.runtimePath("seccomp.conf") + if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { + return err + } + + return clxc.setConfigItem("lxc.seccomp.profile", profilePath) +} + +// Note seccomp flags (see `man 2 seccomp`) are currently not supported +// https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md#seccomp +func writeSeccompProfile(profilePath string, seccomp *specs.LinuxSeccomp) error { + profile, err := os.OpenFile(profilePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0440) + if err != nil { + return err + } + defer profile.Close() + + w := bufio.NewWriter(profile) + + w.WriteString("2\n") + + action, err := defaultAction(seccomp) + if err != nil { + return err + } + fmt.Fprintf(w, "allowlist %s\n", action) + + platformArchs, err := seccompArchs(seccomp) + if err != nil { + return errors.Wrap(err, "Failed to detect platform architecture") + } + log.Debug().Str("action:", action).Strs("archs:", platformArchs).Msg("create seccomp profile") + for _, arch := range platformArchs { + fmt.Fprintf(w, "[%s]\n", arch) + for _, sc := range seccomp.Syscalls { + if err := writeSeccompSyscall(w, sc); err != nil { + return err + } + } + } + // ensure profile is written to disk without errors + if err := w.Flush(); err != nil { + return err + } + return profile.Sync() +} + +func defaultAction(seccomp *specs.LinuxSeccomp) (string, error) { + switch seccomp.DefaultAction { + case specs.ActKill: + return "kill", nil + case specs.ActTrap: + return "trap", nil + case specs.ActErrno: + return "errno 0", nil + case specs.ActAllow: + return "allow", nil + case specs.ActTrace, specs.ActLog: // Not (yet) supported by lxc + log.Warn().Str("action:", string(seccomp.DefaultAction)).Msg("unsupported seccomp default action") + fallthrough + //case specs.ActKillProcess: fallthrough // specs > 1.0.2 + default: + return "kill", fmt.Errorf("Unsupported seccomp default action %q", seccomp.DefaultAction) + } +} + +func seccompArchs(seccomp *specs.LinuxSeccomp) ([]string, error) { + var uts unix.Utsname + if err := unix.Uname(&uts); err != nil { + return nil, err + } + nativeArch := nullTerminatedString(uts.Machine[:]) + if len(seccomp.Architectures) == 0 { + return []string{nativeArch}, nil + } + archs := make([]string, len(seccomp.Architectures)) + for _, a := range seccomp.Architectures { + s := strings.ToLower(strings.TrimLeft(string(a), "SCMP_ARCH_")) + if strings.ToLower(nativeArch) == s { + // lxc seccomp code automatically adds syscalls to compat architectures + return []string{nativeArch}, nil + } + archs = append(archs, s) + } + return archs, nil +} + +func nullTerminatedString(data []byte) string { + i := bytes.Index(data, []byte{0}) + return string(data[:i]) +} + +func writeSeccompSyscall(w *bufio.Writer, sc specs.LinuxSyscall) error { + for _, name := range sc.Names { + action, ok := seccompAction[sc.Action] + if !ok { + return fmt.Errorf("unsupported seccomp action: %s", sc.Action) + } + if len(sc.Args) == 0 { + fmt.Fprintf(w, "%s %s\n", name, action) + } else { + // Only write a single argument per line - this is required when the same arg.Index is used multiple times. + // from `man 7 seccomp_rule_add_exact_array` + // "When adding syscall argument comparisons to the filter it is important to remember + // that while it is possible to have multiple comparisons in a single rule, + // you can only compare each argument once in a single rule. + // In other words, you can not have multiple comparisons of the 3rd syscall argument in a single rule." + for _, arg := range sc.Args { + fmt.Fprintf(w, "%s %s [%d,%d,%s,%d]\n", name, action, arg.Index, arg.Value, arg.Op, arg.ValueTwo) + } + } + } + return nil +} diff --git a/cmd/start.go b/cmd/start.go index 7e248a24..b5765a51 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -3,14 +3,11 @@ package main import ( "fmt" "os" - "path/filepath" - "github.com/apex/log" - // "github.com/opencontainers/runtime-spec/specs-go" + "github.com/lxc/crio-lxc/cmd/internal" "github.com/pkg/errors" - "github.com/urfave/cli" - - lxc "gopkg.in/lxc/go-lxc.v2" + "github.com/urfave/cli/v2" + "time" ) var startCmd = cli.Command{ @@ -21,68 +18,44 @@ var startCmd = cli.Command{ starts `, + Flags: []cli.Flag{ + &cli.DurationFlag{ + Name: "timeout", + Usage: "timeout for reading from syncfifo", + EnvVars: []string{"CRIO_LXC_TIMEOUT_START"}, + Value: time.Second * 30, + Destination: &clxc.StartTimeout, + }, + }, } -func checkHackyPreStart(c *lxc.Container) string { - hooks := c.ConfigItem("lxc.hook.pre-start") - for _, h := range hooks { - if h == "/bin/true" { - return "started" - } - } - return "prestart" -} - -func setHackyPreStart(c *lxc.Container) { - err := c.SetConfigItem("lxc.hook.pre-start", "/bin/true") - if err != nil { - log.Warnf("Failed to set \"container started\" indicator: %v", err) - } - err = c.SaveConfigFile(filepath.Join(LXC_PATH, c.Name(), "config")) +func doStart(ctx *cli.Context) error { + fifoPath := clxc.runtimePath(internal.SyncFifoPath) + f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) + log.Debug().Err(err).Str("fifo", fifoPath).Msg("open fifo") if err != nil { - log.Warnf("Failed to save \"container started\" indicator: %v", err) + return errors.Wrap(err, "container not started - failed to open sync fifo") } -} + defer f.Close() -func doStart(ctx *cli.Context) error { - containerID := ctx.Args().Get(0) - if len(containerID) == 0 { - fmt.Fprintf(os.Stderr, "missing container ID\n") - cli.ShowCommandHelpAndExit(ctx, "state", 1) - } + done := make(chan error) - log.Infof("about to create container") - c, err := lxc.NewContainer(containerID, LXC_PATH) - if err != nil { - return errors.Wrap(err, "failed to load container") - } - defer c.Release() - log.Infof("checking if running") - if !c.Running() { - return fmt.Errorf("'%s' is not ready", containerID) - } - if checkHackyPreStart(c) == "started" { - return fmt.Errorf("'%s' already running", containerID) - } - log.Infof("not running, can start") - setHackyPreStart(c) - fifoPath := filepath.Join(LXC_PATH, containerID, "syncfifo") - log.Infof("opening fifo '%s'", fifoPath) - f, err := os.OpenFile(fifoPath, os.O_RDWR, 0) - if err != nil { - return errors.Wrap(err, "failed to open sync fifo") - } + go func() { + data := make([]byte, len(internal.SyncFifoContent)) + n, err := f.Read(data) + if err != nil { + done <- errors.Wrapf(err, "problem reading from fifo") + } + if n != len(internal.SyncFifoContent) || string(data) != internal.SyncFifoContent { + done <- errors.Errorf("bad fifo content: %s", string(data)) + } + done <- nil + }() - log.Infof("opened fifo, reading") - data := make([]byte, len(SYNC_FIFO_CONTENT)) - n, err := f.Read(data) - if err != nil { - return errors.Wrapf(err, "problem reading from fifo") + select { + case err := <-done: + return err + case <-time.After(clxc.StartTimeout): + return fmt.Errorf("timeout reading from syncfifo %s", fifoPath) } - if n != len(SYNC_FIFO_CONTENT) || string(data) != SYNC_FIFO_CONTENT { - return errors.Errorf("bad fifo content: %s", string(data)) - } - - log.Infof("read '%s' from fifo, done", data) - return nil } diff --git a/cmd/state.go b/cmd/state.go index c98918e9..3e689e7d 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -3,18 +3,12 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" - "strconv" - "strings" - // "github.com/apex/log" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/urfave/cli" - - lxc "gopkg.in/lxc/go-lxc.v2" + "github.com/urfave/cli/v2" ) var stateCmd = cli.Command{ @@ -29,87 +23,28 @@ var stateCmd = cli.Command{ } func doState(ctx *cli.Context) error { - containerID := ctx.Args().Get(0) - if len(containerID) == 0 { - fmt.Fprintf(os.Stderr, "missing container ID\n") - cli.ShowCommandHelpAndExit(ctx, "state", 1) - } - - exists, err := containerExists(containerID) + err := clxc.loadContainer() if err != nil { - return errors.Wrap(err, "failed to check if container exists") - } - if !exists { - return fmt.Errorf("container '%s' not found", containerID) - } - - c, err := lxc.NewContainer(containerID, LXC_PATH) - if err != nil { - return errors.Wrap(err, "failed to load container") - } - defer c.Release() - - if err := configureLogging(ctx, c); err != nil { - return errors.Wrap(err, "failed to configure logging") - + return errors.Wrapf(err, "failed to load container") } - status := "stopped" - pid := 0 - if c.Running() { - if checkHackyPreStart(c) == "started" { - status = "running" - } - pid = c.InitPid() - - // need to detect 'created' per - // https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc4/runtime.md#state - // it means "the container process has neither exited nor executed the user-specified program" - - // if cmd name of the child of the init pid starts with "/bin/sh /fifo-wait" then we can say it's 'created' - - procChildrenFilename := fmt.Sprintf("/proc/%d/task/%d/children", pid, pid) - childrenStr, err := ioutil.ReadFile(procChildrenFilename) - if err != nil { - return errors.Wrapf(err, "failed to read children from %s", procChildrenFilename) - } - children := strings.Split(strings.TrimSpace(string(childrenStr)), " ") - - if len(children) == 1 { - childPid, err := strconv.Atoi(children[0]) - if err != nil { - return errors.Wrapf(err, "failed to convert child pid") - } - procCmdlineFilename := fmt.Sprintf("/proc/%d/cmdline", childPid) - cmdline, err := ioutil.ReadFile(procCmdlineFilename) - if err != nil { - return errors.Wrapf(err, "failed to read cmdline from %s", procCmdlineFilename) - } + // TODO save BundlePath to init spec + bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") - cmdArgv := strings.Split(string(cmdline), "\x00") - if len(cmdArgv) > 2 && cmdArgv[0] == "/bin/sh" && cmdArgv[1] == "/fifo-wait" { - status = "created" - } - } - } - // bundlePath is the enclosing directory of the rootfs: - // https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc4/bundle.md - bundlePath := filepath.Dir(c.ConfigItem("lxc.rootfs.path")[0]) - annotations := map[string]string{} s := specs.State{ - Version: CURRENT_OCI_VERSION, - ID: containerID, - Status: status, - Pid: pid, - Bundle: bundlePath, - Annotations: annotations, + Version: specs.Version, + ID: clxc.Container.Name(), + Bundle: bundlePath, } - stateJson, err := json.Marshal(s) - if err != nil { + s.Pid, s.Status, err = clxc.getContainerState() + log.Debug().Int("pid:", s.Pid).Str("state:", s.Status).Msg("container state") + + if stateJSON, err := json.Marshal(s); err == nil { + fmt.Fprint(os.Stdout, string(stateJSON)) + log.Trace().RawJSON("state:", stateJSON).Msg("container state") + } else { return errors.Wrap(err, "failed to marshal json") } - fmt.Fprint(os.Stdout, string(stateJson)) - - return nil + return err } diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 00000000..6514972e --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" +) + +// createPidFile atomically creates a pid file for the given pid at the given path +func createPidFile(path string, pid int) error { + tmpDir := filepath.Dir(path) + tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) + + f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0600) + if err != nil { + return err + } + _, err = fmt.Fprintf(f, "%d", pid) + if err != nil { + return err + } + err = f.Close() + if err != nil { + return err + } + return os.Rename(tmpName, path) +} diff --git a/go.mod b/go.mod index 808c5698..fb5c39b6 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,16 @@ require ( github.com/opencontainers/runtime-spec v1.0.2 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.20.0 - github.com/stretchr/testify v1.3.0 + github.com/securego/gosec/v2 v2.5.0 // indirect + github.com/stretchr/testify v1.4.0 + github.com/urfave/cli v1.22.5 // indirect github.com/urfave/cli/v2 v2.2.0 - golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect + golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect + golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 + golang.org/x/text v0.3.4 // indirect + golang.org/x/tools v0.0.0-20201110201400-7099162a900a // indirect gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b ) diff --git a/go.sum b/go.sum index 7e904c93..6f103224 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,36 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= +github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -18,23 +48,82 @@ github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= +github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= +github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M= +golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201110201400-7099162a900a h1:5E6TPwSBG74zT8xSrVc8W59K4ch4NFobVTnh2BYzHyU= +golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b h1:nZGkhEMZTXoUuojsilSBJNYZV75IczUo+92qHeXnH8o= gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 8851c1ef5f58ba6f95b8e29f74d29b72cb5f6b54 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 15:17:00 +0100 Subject: [PATCH 013/373] Logging fixes. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 19 +++++++++---------- cmd/create.go | 6 +++--- cmd/delete.go | 6 +++--- cmd/exec.go | 6 +++--- cmd/main.go | 24 +++++++++++++----------- cmd/mount.go | 16 ++++++++-------- cmd/seccomp.go | 4 ++-- cmd/state.go | 4 ++-- 8 files changed, 43 insertions(+), 42 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 88cf4698..0ef823c8 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -128,7 +128,7 @@ func (c crioLXC) release() error { func supportsConfigItem(keys ...string) bool { for _, key := range keys { if !lxc.IsSupportedConfigItem(key) { - log.Debug().Str("key:", key).Msg("unsupported lxc config item") + log.Debug().Str("lxc.config", key).Msg("unsupported config item") return false } } @@ -151,11 +151,10 @@ func (c *crioLXC) getConfigItem(key string) string { func (c *crioLXC) setConfigItem(key, value string) error { err := c.Container.SetConfigItem(key, value) if err != nil { - log.Error().Err(err).Str("key:", key).Str("value:", value).Msg("lxc config") - } else { - log.Debug().Str("key:", key).Str("value:", value).Msg("lxc config") + return errors.Wrap(err, "failed to set config item '%s=%s'") } - return errors.Wrap(err, "failed to set lxc config item '%s=%s'") + log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") + return nil } func (c *crioLXC) configureLogging() error { @@ -172,18 +171,18 @@ func (c *crioLXC) configureLogging() error { c.LogFile = f zerolog.TimestampFieldName = "t" - zerolog.LevelFieldName = "p" + zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" zerolog.TimeFieldFormat = timeFormatLXCMillis // NOTE It's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 - log = zerolog.New(f).With().Timestamp().Str("cmd:", c.Command).Str("cid:", c.ContainerID).Logger() + log = zerolog.New(f).With().Timestamp().Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() level, err := parseLogLevel(c.LogLevelString) if err != nil { - log.Error().Err(err).Stringer("loglevel:", level).Msg("using fallback log-level") + log.Error().Err(err).Stringer("val", level).Msg("using fallback log-level") } c.LogLevel = level @@ -215,7 +214,7 @@ func parseLogLevel(s string) (lxc.LogLevel, error) { case "error": return lxc.ERROR, nil default: - return lxc.ERROR, fmt.Errorf("Invalid log-level %s", s) + return lxc.INFO, fmt.Errorf("Invalid log-level %s", s) } } @@ -339,7 +338,7 @@ func (c *crioLXC) safeGetInitPid() (pid int, proc *os.File) { // It's unlikely a permissions problem because crio runs as privileged process. // This leads to race conditions and should appear in the logs. if proc == nil { - log.Error().Err(err).Int("pid:", pid).Msg("failed to open /proc directory for init PID - procfs mounted?") + log.Error().Err(err).Int("pid", pid).Msg("failed to open /proc directory for init PID - procfs mounted?") } return pid, proc diff --git a/cmd/create.go b/cmd/create.go index 045e6b0c..62a11fa4 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -59,9 +59,9 @@ func doCreate(ctx *cli.Context) error { if clxc.Backup || (err != nil && clxc.BackupOnError) { backupDir, backupErr := clxc.backupRuntimeResources() if backupErr == nil { - log.Warn().Str("dir:", backupDir).Msg("runtime backup completed") + log.Warn().Str("file", backupDir).Msg("runtime backup completed") } else { - log.Error().Err(backupErr).Str("dir:", backupDir).Msg("runtime backup failed") + log.Error().Err(backupErr).Str("file", backupDir).Msg("runtime backup failed") } } return err @@ -476,7 +476,7 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { } if clxc.PidFile != "" { - log.Debug().Str("path:", clxc.PidFile).Msg("creating PID file") + log.Debug().Str("file", clxc.PidFile).Msg("creating PID file") err := createPidFile(clxc.PidFile, cmd.Process.Pid) if err != nil { return err diff --git a/cmd/delete.go b/cmd/delete.go index 5a37b724..d888fd8d 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -96,7 +96,7 @@ func tryRemoveAllCgroupDir(c *lxc.Container, cgroupPath string, killProcs bool) if killProcs { err := loopKillCgroupProcs(dirName, time.Second*2) if err != nil { - log.Trace().Err(err).Str("dir:", dirName).Msg("failed to kill cgroup procs") + log.Trace().Err(err).Str("file", dirName).Msg("failed to kill cgroup procs") } } entries, err := dir.Readdir(-1) @@ -143,7 +143,7 @@ func loopKillCgroupProcs(scope string, timeout time.Duration) error { // same control group as the process for which the PID is given. func killCgroupProcs(scope string) (int, error) { cgroupProcsPath := filepath.Join(scope, "cgroup.procs") - log.Trace().Str("path:", cgroupProcsPath).Msg("reading control group process list") + log.Trace().Str("file", cgroupProcsPath).Msg("reading control group process list") procsData, err := ioutil.ReadFile(cgroupProcsPath) if err != nil { return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) @@ -161,7 +161,7 @@ func killCgroupProcs(scope string) (int, error) { } // This indicates improper signal handling / termination of the container. - log.Warn().Strs("pids:", pidStrings).Str("cgroup:", scope).Msg("killing left-over container processes") + log.Warn().Strs("pids", pidStrings).Str("cgroup", scope).Msg("killing left-over container processes") for _, s := range pidStrings { pid, err := strconv.Atoi(s) diff --git a/cmd/exec.go b/cmd/exec.go index b241b655..6f8d36b9 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -52,7 +52,7 @@ func doExec(ctx *cli.Context) error { specFilePath := ctx.String("process") if specFilePath != "" { - log.Debug().Str("spec:", specFilePath).Msg("read process spec") + log.Debug().Str("spec", specFilePath).Msg("read process spec") specData, err := ioutil.ReadFile(specFilePath) log.Trace().Err(err).RawJSON("spec", specData).Msg("process spec data") @@ -74,8 +74,8 @@ func doExec(ctx *cli.Context) error { attachOpts.Groups[i] = int(g) } } - log.Debug().Int("uid:", attachOpts.UID).Int("gid:", attachOpts.GID).Ints("groups", attachOpts.Groups).Msg("process user") - log.Debug().Strs("arg:", procArgs).Msg("process args") + log.Debug().Int("uid", attachOpts.UID).Int("gid", attachOpts.GID).Ints("groups", attachOpts.Groups).Msg("process user") + log.Debug().Strs("arg", procArgs).Msg("process args") attachOpts.Cwd = procSpec.Cwd // Use the environment defined by the process spec. attachOpts.ClearEnv = true diff --git a/cmd/main.go b/cmd/main.go index 7ba77e10..fcf38a7e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -160,12 +160,9 @@ func main() { return err } - for _, env := range os.Environ() { - log.Trace().Str("env:", env).Msg("effective environment variable") - } - for _, appFlag := range app.Flags { - name := appFlag.Names()[0] - log.Trace().Str("name:", name).Str("value:", ctx.String(name)).Msg("effective cmdline flag") + for _, f := range app.Flags { + name := f.Names()[0] + log.Debug().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") } log.Info().Strs("args", os.Args).Msg("run cmd") @@ -202,9 +199,9 @@ func main() { err := app.Run(os.Args) cmdDuration := time.Since(startTime) if err != nil { - log.Error().Err(err).Dur("duration:", cmdDuration).Msg("cmd failed") + log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") } else { - log.Info().Dur("duration:", cmdDuration).Msg("cmd done") + log.Info().Dur("duration", cmdDuration).Msg("cmd done") } if err := clxc.release(); err != nil { @@ -217,10 +214,11 @@ func main() { } } -// TODO This should be added to the urfave/cli API - create a pull request +// TODO Maybe this should be added to the urfave/cli API - create a pull request. func loadEnvDefaults(envFile string) error { _, err := os.Stat(envFile) if os.IsNotExist(err) { + log.Warn().Str("file", envFile).Msg("environment file does not exist") return nil } if err != nil { @@ -230,6 +228,7 @@ func loadEnvDefaults(envFile string) error { if err != nil { return errors.Wrap(err, "failed to load env file") } + log.Info().Str("file", envFile).Msg("loaded environment file") lines := strings.Split(string(data), "\n") for n, line := range lines { trimmed := strings.TrimSpace(line) @@ -239,16 +238,19 @@ func loadEnvDefaults(envFile string) error { } vals := strings.SplitN(trimmed, "=", 2) if len(vals) != 2 { - return fmt.Errorf("Invalid environment variable at %s +%d", envFile, n) + return fmt.Errorf("Invalid environment variable at line %s:%d", envFile, n) } key := strings.TrimSpace(vals[0]) val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) // existing environment variables have precedence - if _, exist := os.LookupEnv(key); !exist { + if existVal, exist := os.LookupEnv(key); !exist { err := os.Setenv(key, val) if err != nil { return errors.Wrap(err, "setenv failed") } + log.Trace().Str("env", key).Str("val", val).Msg("using value from environment file") + } else { + log.Trace().Str("env", key).Str("val", existVal).Msg("environment file value overriden by existing environment value") } } return nil diff --git a/cmd/mount.go b/cmd/mount.go index bd49cb0d..834c6f93 100644 --- a/cmd/mount.go +++ b/cmd/mount.go @@ -33,7 +33,7 @@ func configureMounts(spec *specs.Spec) error { mountDest, err := resolveMountDestination(spec.Root.Path, ms.Destination) // Intermediate path resolution failed. This is not an error, since // the remaining directories / files are automatically created (create=dir|file) - log.Trace().Err(err).Str("dst:", ms.Destination).Str("effective:", mountDest).Msg("resolve mount destination") + log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. if !filepath.HasPrefix(mountDest, spec.Root.Path) { @@ -77,12 +77,12 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { // source exists and is not a directory // create a target file that can be used as target for a bind mount err := os.MkdirAll(filepath.Dir(ms.Destination), 0750) - log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create parent directory for file bind mount") + log.Debug().Err(err).Str("file", ms.Destination).Msg("create parent directory for file bind mount") if err != nil { return errors.Wrap(err, "failed to create mount destination dir") } f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0440) - log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create file bind mount destination") + log.Debug().Err(err).Str("file", ms.Destination).Msg("create file bind mount destination") if err != nil { return errors.Wrap(err, "failed to create file mountpoint") } @@ -92,7 +92,7 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { // FIXME exclude all directories that are below other mounts // only directories / files on the readonly rootfs must be created err = os.MkdirAll(ms.Destination, 0750) - log.Debug().Err(err).Str("dst:", ms.Destination).Msg("create mount destination directory") + log.Debug().Err(err).Str("file", ms.Destination).Msg("create mount destination directory") if err != nil { return errors.Wrap(err, "failed to create mount destination") } @@ -100,7 +100,7 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { } func resolvePathRelative(rootfs string, currentPath string, subPath string) (string, error) { - log.Trace().Str("current:", currentPath).Str("sub:", subPath).Msg("resolve path relative") + log.Trace().Str("file", currentPath).Str("sub", subPath).Msg("resolve path relative") p := filepath.Join(currentPath, subPath) stat, err := os.Lstat(p) @@ -110,7 +110,7 @@ func resolvePathRelative(rootfs string, currentPath string, subPath string) (str } if stat.Mode()&os.ModeSymlink == 0 { - log.Trace().Str("filepath:", p).Msg("is not a symlink") + log.Trace().Str("file", p).Msg("is not a symlink") return p, nil } // resolve symlink @@ -120,7 +120,7 @@ func resolvePathRelative(rootfs string, currentPath string, subPath string) (str return p, err } - log.Trace().Str("link:", p).Str("dst:", linkDst).Msg("symlink detected") + log.Trace().Str("link", p).Str("dst", linkDst).Msg("symlink detected") // The destination of an absolute link must be prefixed with the rootfs if filepath.IsAbs(linkDst) { @@ -161,7 +161,7 @@ func resolveMountDestination(rootfs string, dst string) (dstPath string, err err // start path resolution at rootfs for i, entry := range entries { currentPath, err = resolvePathRelative(rootfs, currentPath, entry) - log.Trace().Err(err).Str("dst:", currentPath).Msg("path resolved") + log.Trace().Err(err).Str("file", currentPath).Msg("path resolved") if err != nil { // The already resolved path is concatenated with the remaining path, // if resolution of path fails at some point. diff --git a/cmd/seccomp.go b/cmd/seccomp.go index 12f9b8e0..13a19554 100644 --- a/cmd/seccomp.go +++ b/cmd/seccomp.go @@ -59,7 +59,7 @@ func writeSeccompProfile(profilePath string, seccomp *specs.LinuxSeccomp) error if err != nil { return errors.Wrap(err, "Failed to detect platform architecture") } - log.Debug().Str("action:", action).Strs("archs:", platformArchs).Msg("create seccomp profile") + log.Debug().Str("action", action).Strs("archs", platformArchs).Msg("create seccomp profile") for _, arch := range platformArchs { fmt.Fprintf(w, "[%s]\n", arch) for _, sc := range seccomp.Syscalls { @@ -86,7 +86,7 @@ func defaultAction(seccomp *specs.LinuxSeccomp) (string, error) { case specs.ActAllow: return "allow", nil case specs.ActTrace, specs.ActLog: // Not (yet) supported by lxc - log.Warn().Str("action:", string(seccomp.DefaultAction)).Msg("unsupported seccomp default action") + log.Warn().Str("action", string(seccomp.DefaultAction)).Msg("unsupported seccomp default action") fallthrough //case specs.ActKillProcess: fallthrough // specs > 1.0.2 default: diff --git a/cmd/state.go b/cmd/state.go index 3e689e7d..fc8d9bfd 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -38,11 +38,11 @@ func doState(ctx *cli.Context) error { } s.Pid, s.Status, err = clxc.getContainerState() - log.Debug().Int("pid:", s.Pid).Str("state:", s.Status).Msg("container state") + log.Debug().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") if stateJSON, err := json.Marshal(s); err == nil { fmt.Fprint(os.Stdout, string(stateJSON)) - log.Trace().RawJSON("state:", stateJSON).Msg("container state") + log.Trace().RawJSON("state", stateJSON).Msg("container state") } else { return errors.Wrap(err, "failed to marshal json") } From f9cd8fec8aa56641da62a8efb37c6f2d588a2dc8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 15:34:08 +0100 Subject: [PATCH 014/373] Lint fixes. Signed-off-by: Ruben Jenster --- cmd/mount.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mount.go b/cmd/mount.go index 834c6f93..265e35f8 100644 --- a/cmd/mount.go +++ b/cmd/mount.go @@ -16,7 +16,7 @@ func configureMounts(spec *specs.Spec) error { return err } - for i, _ := range spec.Mounts { + for i := range spec.Mounts { ms := spec.Mounts[i] if ms.Type == "cgroup" { // TODO check if hieararchy is cgroup v2 only (unified mode) From cf0e4cb0865e362f2eb0ab5070129a8b953b6ab5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 16:24:41 +0100 Subject: [PATCH 015/373] Add #nosec comments to ignore gosec false positives. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 3 +++ cmd/create.go | 4 ++++ cmd/delete.go | 4 ++++ cmd/exec.go | 1 + cmd/hook/hook.go | 1 + cmd/internal/internal.go | 4 ++++ cmd/kill.go | 1 + cmd/main.go | 1 + cmd/seccomp.go | 3 +++ cmd/start.go | 2 ++ cmd/utils.go | 1 + 11 files changed, 25 insertions(+) diff --git a/cmd/clxc.go b/cmd/clxc.go index 0ef823c8..473e7c48 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -290,6 +290,7 @@ func (c *crioLXC) getContainerState() (int, string, error) { func (c *crioLXC) getContainerInitState() (int, string, error) { pid, proc := c.safeGetInitPid() if proc != nil { + // #nosec defer proc.Close() } if pid <= 0 { @@ -297,6 +298,7 @@ func (c *crioLXC) getContainerInitState() (int, string, error) { } envFile := fmt.Sprintf("/proc/%d/environ", pid) + // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { // This is fatal. It should not happen because a filehandle to /proc/%d is open. @@ -327,6 +329,7 @@ func (c *crioLXC) safeGetInitPid() (pid int, proc *os.File) { pid2 := c.Container.InitPid() if pid2 != pid { if proc != nil { + // #nosec proc.Close() } // init process has died which should only happen if /proc/%d was not opened diff --git a/cmd/create.go b/cmd/create.go index 62a11fa4..8258e938 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -255,6 +255,7 @@ func configureInit(spec *specs.Spec) error { if err != nil { return errors.Wrapf(err, "Failed creating %s in rootfs", internal.ConfigDir) } + // #nosec err = os.MkdirAll(clxc.runtimePath(internal.ConfigDir), 0755) if err != nil { return errors.Wrapf(err, "Failed creating %s in lxc container dir", internal.ConfigDir) @@ -309,6 +310,7 @@ func configureInit(spec *specs.Spec) error { } func touchFile(filePath string, perm os.FileMode) error { + // #nosec f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDONLY, perm) if err == nil { return f.Close() @@ -437,6 +439,7 @@ func ensureDefaultDevices(spec *specs.Spec) error { func startContainer(spec *specs.Spec, timeout time.Duration) error { configFilePath := clxc.runtimePath("config") + // #nosec cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, configFilePath) // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. @@ -560,6 +563,7 @@ func setHostname(spec *specs.Spec) error { if err != nil { return errors.Wrapf(err, "failed to open uts namespace %s", ns.Path) } + // #nosec defer f.Close() // setns only affects the current thread diff --git a/cmd/delete.go b/cmd/delete.go index d888fd8d..4bea10fb 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -63,6 +63,7 @@ func doDelete(ctx *cli.Context) error { } else { // try to remove outer directory, in case this is the POD that is deleted // FIXME crio should delete the kubepods slice + // #nosec tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) } } @@ -73,6 +74,7 @@ func doDelete(ctx *cli.Context) error { } else { // try to remove outer directory, in case this is the POD that is deleted // FIXME crio should delete the kubepods slice + // #nosec tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) } } @@ -86,6 +88,7 @@ func doDelete(ctx *cli.Context) error { func tryRemoveAllCgroupDir(c *lxc.Container, cgroupPath string, killProcs bool) error { dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) + // #nosec dir, err := os.Open(dirName) if os.IsNotExist(err) { return nil @@ -144,6 +147,7 @@ func loopKillCgroupProcs(scope string, timeout time.Duration) error { func killCgroupProcs(scope string) (int, error) { cgroupProcsPath := filepath.Join(scope, "cgroup.procs") log.Trace().Str("file", cgroupProcsPath).Msg("reading control group process list") + // #nosec procsData, err := ioutil.ReadFile(cgroupProcsPath) if err != nil { return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) diff --git a/cmd/exec.go b/cmd/exec.go index 6f8d36b9..de0c805b 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -53,6 +53,7 @@ func doExec(ctx *cli.Context) error { if specFilePath != "" { log.Debug().Str("spec", specFilePath).Msg("read process spec") + // #nosec specData, err := ioutil.ReadFile(specFilePath) log.Trace().Err(err).RawJSON("spec", specData).Msg("process spec data") diff --git a/cmd/hook/hook.go b/cmd/hook/hook.go index 5112560a..117a2398 100644 --- a/cmd/hook/hook.go +++ b/cmd/hook/hook.go @@ -76,6 +76,7 @@ func createDevice(spec *specs.Spec, dev specs.LinuxDevice) error { } // ignore error (mknod will fail) + // #nosec os.MkdirAll(filepath.Dir(dev.Path), 0755) err := unix.Mknod(dev.Path, mode, devMode) diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go index 25f1c140..d1478636 100644 --- a/cmd/internal/internal.go +++ b/cmd/internal/internal.go @@ -22,10 +22,12 @@ const ( // ReadSpec deserializes the JSON encoded runtime spec from the given path. func ReadSpec(specFilePath string) (*specs.Spec, error) { + // #nosec specFile, err := os.Open(specFilePath) if err != nil { return nil, err } + // #nosec defer specFile.Close() spec := &specs.Spec{} err = json.NewDecoder(specFile).Decode(spec) @@ -37,10 +39,12 @@ func ReadSpec(specFilePath string) (*specs.Spec, error) { // WriteSpec serializes the runtime spec to JSON and writes it to the given path. func WriteSpec(spec *specs.Spec, specFilePath string) error { + // #nosec f, err := os.OpenFile(specFilePath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0444) if err != nil { return err } + // #nosec defer f.Close() if err := json.NewEncoder(f).Encode(spec); err != nil { return err diff --git a/cmd/kill.go b/cmd/kill.go index c645c77e..a8e83f22 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -105,6 +105,7 @@ func doKill(ctx *cli.Context) error { } pid, proc := clxc.safeGetInitPid() if proc != nil { + // #nosec defer proc.Close() } if pid <= 0 { diff --git a/cmd/main.go b/cmd/main.go index fcf38a7e..0fcd7186 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -224,6 +224,7 @@ func loadEnvDefaults(envFile string) error { if err != nil { return errors.Wrapf(err, "failed to stat %s", envFile) } + // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { return errors.Wrap(err, "failed to load env file") diff --git a/cmd/seccomp.go b/cmd/seccomp.go index 13a19554..2585b5a1 100644 --- a/cmd/seccomp.go +++ b/cmd/seccomp.go @@ -39,14 +39,17 @@ func configureSeccomp(spec *specs.Spec) error { // Note seccomp flags (see `man 2 seccomp`) are currently not supported // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md#seccomp func writeSeccompProfile(profilePath string, seccomp *specs.LinuxSeccomp) error { + // #nosec profile, err := os.OpenFile(profilePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0440) if err != nil { return err } + // #nosec defer profile.Close() w := bufio.NewWriter(profile) + // #nosec w.WriteString("2\n") action, err := defaultAction(seccomp) diff --git a/cmd/start.go b/cmd/start.go index b5765a51..05fc38b1 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -31,11 +31,13 @@ starts func doStart(ctx *cli.Context) error { fifoPath := clxc.runtimePath(internal.SyncFifoPath) + // #nosec f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) log.Debug().Err(err).Str("fifo", fifoPath).Msg("open fifo") if err != nil { return errors.Wrap(err, "container not started - failed to open sync fifo") } + // #nosec defer f.Close() done := make(chan error) diff --git a/cmd/utils.go b/cmd/utils.go index 6514972e..0d80a9d5 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -11,6 +11,7 @@ func createPidFile(path string, pid int) error { tmpDir := filepath.Dir(path) tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) + // #nosec f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0600) if err != nil { return err From ec86cb8ccf7304da82424512a4e8f3ac989ed6f0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 16:27:30 +0100 Subject: [PATCH 016/373] Warn if syncfifo can not be removed from runtime backup. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 473e7c48..f0525560 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -231,13 +231,18 @@ func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { if err != nil { return "", errors.Wrap(err, "failed to create backup dir") } - err = runCommand("cp", "-r", "-p", clxc.runtimePath(), backupDir) + err = copyDir(clxc.runtimePath(), backupDir) if err != nil { return backupDir, errors.Wrap(err, "failed to copy lxc runtime directory") } // remove syncfifo because it is not of any use and blocks 'grep' within the backup directory. - os.Remove(filepath.Join(backupDir, internal.SyncFifoPath)) - err = runCommand("cp", clxc.SpecPath, backupDir) + syncFifoPath := filepath.Join(backupDir, internal.SyncFifoPath) + // #nosec + err = os.Remove(syncFifoPath) + if err != nil { + log.Warn().Err(err).Str("file", syncFifoPath).Msg("failed to remove syncfifo from backup dir") + } + err = copyDir(clxc.SpecPath, backupDir) if err != nil { return backupDir, errors.Wrap(err, "failed to copy runtime spec to backup dir") } @@ -245,11 +250,12 @@ func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { } // TODO avoid shellout -func runCommand(args ...string) error { - cmd := exec.Command(args[0], args[1:]...) +func copyDir(src, dst string) error { + // #nosec + cmd := exec.Command("cp", "-r", "-p", src, dst) output, err := cmd.CombinedOutput() if err != nil { - return errors.Errorf("%s: %s: %s", strings.Join(args, " "), err, string(output)) + return errors.Errorf("%s: %s: %s", strings.Join(cmd.Args, " "), err, string(output)) } return nil } From be14cdb4a5ac51265c6c208ee0dad780972d88cc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 16:28:40 +0100 Subject: [PATCH 017/373] Switch back uts namespace after setting hostname on shared namespace. Signed-off-by: Ruben Jenster --- cmd/create.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 8258e938..96909d24 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -559,6 +559,10 @@ func setHostname(spec *specs.Spec) error { return nil } + // setns only affects the current thread + runtime.LockOSThread() + defer runtime.UnlockOSThread() + f, err := os.Open(ns.Path) if err != nil { return errors.Wrapf(err, "failed to open uts namespace %s", ns.Path) @@ -566,15 +570,25 @@ func setHostname(spec *specs.Spec) error { // #nosec defer f.Close() - // setns only affects the current thread - runtime.LockOSThread() - defer runtime.UnlockOSThread() + self, err := os.Open("/proc/self/ns/uts") + if err != nil { + return errors.Wrapf(err, "failed to open %s", "/proc/self/ns/uts") + } + // #nosec + defer self.Close() err = unix.Setns(int(f.Fd()), unix.CLONE_NEWUTS) if err != nil { return err } - return unix.Sethostname([]byte(spec.Hostname)) + err = unix.Sethostname([]byte(spec.Hostname)) + if err != nil { + return err + } + err = unix.Setns(int(self.Fd()), unix.CLONE_NEWUTS) + if err != nil { + return err + } } return nil } From 60849c6d8ba952f6c051bab1464d4d7de5021c87 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 16:29:27 +0100 Subject: [PATCH 018/373] Warn if environment file has invalid file mode. Signed-off-by: Ruben Jenster --- cmd/main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index 0fcd7186..1b935e80 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -216,7 +216,7 @@ func main() { // TODO Maybe this should be added to the urfave/cli API - create a pull request. func loadEnvDefaults(envFile string) error { - _, err := os.Stat(envFile) + stat, err := os.Stat(envFile) if os.IsNotExist(err) { log.Warn().Str("file", envFile).Msg("environment file does not exist") return nil @@ -224,6 +224,9 @@ func loadEnvDefaults(envFile string) error { if err != nil { return errors.Wrapf(err, "failed to stat %s", envFile) } + if (stat.Mode().Perm() &^ 0640) != 0 { + log.Warn().Str("file", envFile).Msg("environment file should have mode 0640") + } // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { From d8192f831070e0a67dc8e6c2c3a74f8f7bdc1cf2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 17:17:32 +0100 Subject: [PATCH 019/373] Add file and line num to logging output. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index f0525560..129809a8 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -8,6 +8,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strconv" "strings" "time" @@ -173,12 +174,16 @@ func (c *crioLXC) configureLogging() error { zerolog.TimestampFieldName = "t" zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" + zerolog.CallerFieldName = "c" zerolog.TimeFieldFormat = timeFormatLXCMillis // NOTE It's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 - log = zerolog.New(f).With().Timestamp().Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() + log = zerolog.New(f).With().Timestamp().Caller().Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() + zerolog.CallerMarshalFunc = func(file string, line int) string { + return filepath.Base(file) + ":" + strconv.Itoa(line) + } level, err := parseLogLevel(c.LogLevelString) if err != nil { From 410f51ce1c59bf5b4be0c69a4df654e54ed36f09 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 17:18:00 +0100 Subject: [PATCH 020/373] Log cmdline flags and backup dir only in trace level. Signed-off-by: Ruben Jenster --- cmd/create.go | 8 ++++---- cmd/main.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 96909d24..ccf02236 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -57,11 +57,11 @@ var createCmd = cli.Command{ func doCreate(ctx *cli.Context) error { err := doCreateInternal() if clxc.Backup || (err != nil && clxc.BackupOnError) { - backupDir, backupErr := clxc.backupRuntimeResources() - if backupErr == nil { - log.Warn().Str("file", backupDir).Msg("runtime backup completed") + dir, err := clxc.backupRuntimeResources() + if err != nil { + log.Error().Err(err).Str("file", dir).Msg("runtime backup failed") } else { - log.Error().Err(backupErr).Str("file", backupDir).Msg("runtime backup failed") + log.Trace().Str("file", dir).Msg("runtime backup created") } } return err diff --git a/cmd/main.go b/cmd/main.go index 1b935e80..090e899f 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -160,9 +160,9 @@ func main() { return err } - for _, f := range app.Flags { + for _, f := range ctx.Command.Flags { name := f.Names()[0] - log.Debug().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") + log.Trace().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") } log.Info().Strs("args", os.Args).Msg("run cmd") From a4260aeb7b90075491a5f680b1a6a42413091f01 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 17:19:00 +0100 Subject: [PATCH 021/373] kill: Log kill signal. Signed-off-by: Ruben Jenster --- cmd/kill.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/kill.go b/cmd/kill.go index a8e83f22..1d529d96 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -111,5 +111,6 @@ func doKill(ctx *cli.Context) error { if pid <= 0 { return errors.New("init process is not running") } + log.Debug().Int("pid", pid).Int("signal", int(signum)).Msg("send kill signal") return unix.Kill(pid, signum) } From cde30c5f9fcbcb8e5a4666dc19e98976339eed27 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 22:59:53 +0100 Subject: [PATCH 022/373] create: Do not wait for container state. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 33 +++++++-------------------------- cmd/create.go | 15 +++++---------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 129809a8..68534c63 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -20,6 +20,8 @@ import ( // time format used for logger const timeFormatLXCMillis = "20060102150405.000" +// The singelton that wraps the lxc.Container +var clxc crioLXC var log zerolog.Logger var errContainerNotExist = errors.New("container does not exist") @@ -282,23 +284,19 @@ const ( envStateCreated = "CRIO_LXC_STATE=" + stateCreated ) +// getContainerInitState returns the runtime state of the container. +// It is used to determine whether the container state is 'created' or 'running'. +// The init process environment contains #envStateCreated if the the container +// is created, but not yet running/started. +// This requires the proc filesystem to be mounted on the host. func (c *crioLXC) getContainerState() (int, string, error) { switch state := c.Container.State(); state { case lxc.STARTING: return 0, stateCreating, nil case lxc.STOPPED: return 0, stateStopped, nil - default: - return c.getContainerInitState() } -} -// getContainerInitState returns the runtime state of the container. -// It is used to determine whether the container state is 'created' or 'running'. -// The init process environment contains #envStateCreated if the the container -// is created, but not yet running/started. -// This requires the proc filesystem to be mounted on the host. -func (c *crioLXC) getContainerInitState() (int, string, error) { pid, proc := c.safeGetInitPid() if proc != nil { // #nosec @@ -357,20 +355,3 @@ func (c *crioLXC) safeGetInitPid() (pid int, proc *os.File) { return pid, proc } - -func (c *crioLXC) waitContainerCreated(timeout time.Duration) error { - deadline := time.Now().Add(timeout) - for time.Now().Before(deadline) { - log.Trace().Msg("poll for container init state") - pid, state, err := c.getContainerInitState() - if err != nil { - return errors.Wrap(err, "failed to wait for container container creation") - } - - if pid > 0 && state == stateCreated { - return nil - } - time.Sleep(time.Millisecond * 50) - } - return fmt.Errorf("timeout (%s) waiting for container creation", timeout) -} diff --git a/cmd/create.go b/cmd/create.go index ccf02236..9fda9d05 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -473,21 +473,16 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { return errors.Wrapf(err, "failed to write init spec") } - err := cmd.Start() - if err != nil { - return err + log.Debug().Strs("args", cmd.Args).Msg("running start cmd") + if err := cmd.Start(); err != nil { + return errors.Wrap(err, "failed to run start cmd") } if clxc.PidFile != "" { log.Debug().Str("file", clxc.PidFile).Msg("creating PID file") - err := createPidFile(clxc.PidFile, cmd.Process.Pid) - if err != nil { - return err - } + return createPidFile(clxc.PidFile, cmd.Process.Pid) } - - log.Debug().Msg("waiting for container creation") - return clxc.waitContainerCreated(timeout) + return nil } func saveConfig(configFilePath string) error { From 0bc0592ecbb0c742632b3318dbe598fe607c0083 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 12 Nov 2020 23:00:54 +0100 Subject: [PATCH 023/373] config: Improve error handling for environment file. Signed-off-by: Ruben Jenster --- cmd/main.go | 96 ++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 090e899f..ff348244 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -11,15 +11,9 @@ import ( "github.com/urfave/cli/v2" ) -const ( - // Environment variables are populated by default from this environment file. - // Existing environment variables are preserved. - envFileDefault = "/etc/default/crio-lxc" - // This environment variable can be used to overwrite the path in envFileDefault. - envFileVar = "CRIO_LXC_DEFAULTS" -) - -var clxc crioLXC +// Environment variables are populated by default from this environment file. +// Existing environment variables are preserved. +var envFile = "/etc/default/crio-lxc" func main() { app := cli.NewApp() @@ -46,7 +40,7 @@ func main() { &cli.StringFlag{ Name: "log-file", Usage: "log file for LXC and crio-lxc (default is per container in lxc-path)", - EnvVars: []string{"CRIO_LXC_LOG_FILE", "LOG_FILE"}, + EnvVars: []string{"CRIO_LXC_LOG_FILE"}, Value: "/var/log/crio-lxc.log", Destination: &clxc.LogFilePath, }, @@ -143,6 +137,18 @@ func main() { startTime := time.Now() + env, envErr := loadEnvFile(envFile) + // Environment variables must be injected from file before app is run, + // Otherwise the values are not set to the crioLXC instance. + if env != nil { + for key, val := range env { + if err := setEnvIfNew(key, val); err != nil { + envErr = err + break + } + } + } + app.Before = func(ctx *cli.Context) error { clxc.Command = ctx.Args().Get(0) return nil @@ -160,12 +166,29 @@ func main() { return err } + if env != nil { + stat, _ := os.Stat(envFile) + if stat != nil && (stat.Mode().Perm()^0640) != 0 { + log.Warn().Str("file", envFile).Stringer("mode", stat.Mode().Perm()).Msgf("environment file should have mode %s", os.FileMode(0640)) + } + for key, val := range env { + log.Trace().Str("env", key).Str("val", val).Msg("environment file value") + } + log.Info().Str("file", envFile).Msg("loaded environment variables from file") + } else { + if os.IsNotExist(envErr) { + log.Warn().Str("file", envFile).Msg("environment file does not exist") + } else { + return errors.Wrapf(envErr, "failed to load env file %s", envFile) + } + } + for _, f := range ctx.Command.Flags { name := f.Names()[0] log.Trace().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") } - log.Info().Strs("args", os.Args).Msg("run cmd") + log.Debug().Strs("args", os.Args).Msg("run cmd") return nil } @@ -187,21 +210,12 @@ func main() { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } - envFile := envFileDefault - if s, isSet := os.LookupEnv(envFileVar); isSet { - envFile = s - } - if err := loadEnvDefaults(envFile); err != nil { - println(err.Error()) - os.Exit(1) - } - err := app.Run(os.Args) cmdDuration := time.Since(startTime) if err != nil { log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") } else { - log.Info().Dur("duration", cmdDuration).Msg("cmd done") + log.Debug().Dur("duration", cmdDuration).Msg("cmd done") } if err := clxc.release(); err != nil { @@ -214,48 +228,34 @@ func main() { } } -// TODO Maybe this should be added to the urfave/cli API - create a pull request. -func loadEnvDefaults(envFile string) error { - stat, err := os.Stat(envFile) - if os.IsNotExist(err) { - log.Warn().Str("file", envFile).Msg("environment file does not exist") - return nil - } - if err != nil { - return errors.Wrapf(err, "failed to stat %s", envFile) - } - if (stat.Mode().Perm() &^ 0640) != 0 { - log.Warn().Str("file", envFile).Msg("environment file should have mode 0640") +func setEnvIfNew(key, val string) error { + if _, exist := os.LookupEnv(key); !exist { + return os.Setenv(key, val) } + return nil +} + +func loadEnvFile(envFile string) (map[string]string, error) { // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { - return errors.Wrap(err, "failed to load env file") + return nil, err } - log.Info().Str("file", envFile).Msg("loaded environment file") lines := strings.Split(string(data), "\n") + env := make(map[string]string, len(lines)) for n, line := range lines { trimmed := strings.TrimSpace(line) - //skip over comments and blank lines + // skip over comments and blank lines if len(trimmed) == 0 || trimmed[0] == '#' { continue } vals := strings.SplitN(trimmed, "=", 2) if len(vals) != 2 { - return fmt.Errorf("Invalid environment variable at line %s:%d", envFile, n) + return nil, fmt.Errorf("Invalid environment variable at line %s:%d", envFile, n+1) } key := strings.TrimSpace(vals[0]) val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) - // existing environment variables have precedence - if existVal, exist := os.LookupEnv(key); !exist { - err := os.Setenv(key, val) - if err != nil { - return errors.Wrap(err, "setenv failed") - } - log.Trace().Str("env", key).Str("val", val).Msg("using value from environment file") - } else { - log.Trace().Str("env", key).Str("val", existVal).Msg("environment file value overriden by existing environment value") - } + env[key] = val } - return nil + return env, nil } From c8203dd936041e3d0726d89b6227aae88b904793 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 13 Nov 2020 17:43:38 +0100 Subject: [PATCH 024/373] Log timestamp in UTC. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/clxc.go b/cmd/clxc.go index 68534c63..b500d2c8 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -179,6 +179,10 @@ func (c *crioLXC) configureLogging() error { zerolog.CallerFieldName = "c" zerolog.TimeFieldFormat = timeFormatLXCMillis + zerolog.TimestampFunc = func() time.Time { + return time.Now().UTC() + } + // NOTE It's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 From 7f272b84f525d4961667744d3dc1e88a427bc0aa Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 13 Nov 2020 19:34:17 +0100 Subject: [PATCH 025/373] Set annotations to specs.State Signed-off-by: Ruben Jenster --- cmd/state.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/state.go b/cmd/state.go index fc8d9bfd..dbb4bd1d 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" + "github.com/lxc/crio-lxc/cmd/internal" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/urfave/cli/v2" @@ -30,6 +31,10 @@ func doState(ctx *cli.Context) error { // TODO save BundlePath to init spec bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") + spec, err := internal.ReadSpec(filepath.Join(bundlePath, "config.json")) + if err != nil { + return errors.Wrapf(err, "failed to load spec from %s", bundlePath) + } s := specs.State{ Version: specs.Version, @@ -37,6 +42,10 @@ func doState(ctx *cli.Context) error { Bundle: bundlePath, } + if spec.Annotations != nil { + s.Annotations = spec.Annotations + } + s.Pid, s.Status, err = clxc.getContainerState() log.Debug().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") From 5840cbff0087ad430ddfff7c47499de1ad57d1d8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 13 Nov 2020 21:24:23 +0100 Subject: [PATCH 026/373] Lowercase error strings. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 2 +- cmd/main.go | 2 +- cmd/namespaces.go | 2 +- cmd/seccomp.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index b500d2c8..354aaa78 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -225,7 +225,7 @@ func parseLogLevel(s string) (lxc.LogLevel, error) { case "error": return lxc.ERROR, nil default: - return lxc.INFO, fmt.Errorf("Invalid log-level %s", s) + return lxc.INFO, fmt.Errorf("invalid log-level %s", s) } } diff --git a/cmd/main.go b/cmd/main.go index ff348244..6af4a26d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -251,7 +251,7 @@ func loadEnvFile(envFile string) (map[string]string, error) { } vals := strings.SplitN(trimmed, "=", 2) if len(vals) != 2 { - return nil, fmt.Errorf("Invalid environment variable at line %s:%d", envFile, n+1) + return nil, fmt.Errorf("invalid environment variable at line %s:%d", envFile, n+1) } key := strings.TrimSpace(vals[0]) val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) diff --git a/cmd/namespaces.go b/cmd/namespaces.go index 41caca58..9deb99bf 100644 --- a/cmd/namespaces.go +++ b/cmd/namespaces.go @@ -37,7 +37,7 @@ func configureNamespaces(namespaces []specs.LinuxNamespace) error { n, supported := namespaceMap[ns.Type] if !supported { - return fmt.Errorf("Unsupported namespace %s", ns.Type) + return fmt.Errorf("unsupported namespace %s", ns.Type) } configKey := fmt.Sprintf("lxc.namespace.share.%s", n.Name) if err := clxc.setConfigItem(configKey, ns.Path); err != nil { diff --git a/cmd/seccomp.go b/cmd/seccomp.go index 2585b5a1..f4c87ae3 100644 --- a/cmd/seccomp.go +++ b/cmd/seccomp.go @@ -93,7 +93,7 @@ func defaultAction(seccomp *specs.LinuxSeccomp) (string, error) { fallthrough //case specs.ActKillProcess: fallthrough // specs > 1.0.2 default: - return "kill", fmt.Errorf("Unsupported seccomp default action %q", seccomp.DefaultAction) + return "kill", fmt.Errorf("unsupported seccomp default action %q", seccomp.DefaultAction) } } From f6768a9108c1732da7eb692f9823e5db17c2a0fe Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 16 Nov 2020 18:24:31 +0100 Subject: [PATCH 027/373] Create config file early. Avoid race conditions. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 37 +++++++++++++++++++++++++++++-------- cmd/create.go | 18 +++--------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 354aaa78..b7d7052d 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -76,11 +76,15 @@ func (c *crioLXC) runtimePath(subPath ...string) string { return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) } +func (c *crioLXC) configFilePath() string { + return c.runtimePath("config") +} + func (c *crioLXC) loadContainer() error { // Check for container existence by looking for config file. // Otherwise lxc.NewContainer will return an empty container // struct and we'll report wrong info - _, err := os.Stat(c.runtimePath("config")) + _, err := os.Stat(clxc.configFilePath()) if os.IsNotExist(err) { return errContainerNotExist } @@ -92,26 +96,43 @@ func (c *crioLXC) loadContainer() error { if err != nil { return errors.Wrap(err, "failed to load container") } - if err := container.LoadConfigFile(c.runtimePath("config")); err != nil { - return err + err = container.LoadConfigFile(clxc.configFilePath()) + if err != nil { + return errors.Wrap(err, "failed to load config file") } c.Container = container return nil } func (c *crioLXC) createContainer() error { - _, err := os.Stat(c.runtimePath("config")) - if !os.IsNotExist(err) { - return errContainerExist + if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { + return errors.Wrap(err, "failed to create container dir") + } + f, err := os.OpenFile(c.runtimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + if err != nil { + return err } + f.Close() container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { return err } c.Container = container - if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { - return errors.Wrap(err, "failed to create container dir") + return nil +} + +func (c *crioLXC) saveConfig() error { + // Write out final config file for debugging and use with lxc-attach: + // Do not edit config after this. + tmpFile := c.runtimePath(".config") + err := clxc.Container.SaveConfigFile(tmpFile) + if err != nil { + return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) + } + if err := os.Rename(tmpFile, clxc.configFilePath()); err != nil { + return errors.Wrap(err, "failed to rename config file") } + log.Debug().Str("file", clxc.configFilePath()).Msg("created lxc config file") return nil } diff --git a/cmd/create.go b/cmd/create.go index 9fda9d05..a12fd7af 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -438,9 +438,8 @@ func ensureDefaultDevices(spec *specs.Spec) error { } func startContainer(spec *specs.Spec, timeout time.Duration) error { - configFilePath := clxc.runtimePath("config") // #nosec - cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, configFilePath) + cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. @@ -449,7 +448,7 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { cmd.Env = []string{} if clxc.ConsoleSocket != "" { - if err := saveConfig(configFilePath); err != nil { + if err := clxc.saveConfig(); err != nil { return err } return startConsole(cmd, clxc.ConsoleSocket) @@ -465,7 +464,7 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { cmd.Stderr = os.Stderr } - if err := saveConfig(configFilePath); err != nil { + if err := clxc.saveConfig(); err != nil { return err } @@ -485,17 +484,6 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { return nil } -func saveConfig(configFilePath string) error { - // Write out final config file for debugging and use with lxc-attach: - // Do not edit config after this. - err := clxc.Container.SaveConfigFile(configFilePath) - log.Debug().Err(err).Str("config", configFilePath).Msg("save config file") - if err != nil { - return errors.Wrapf(err, "failed to save config file to '%s'", configFilePath) - } - return nil -} - func startConsole(cmd *exec.Cmd, consoleSocket string) error { addr, err := net.ResolveUnixAddr("unix", consoleSocket) if err != nil { From ee4c316bcbd765a22a31cbf5a7056bd714186bd7 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 16 Nov 2020 19:41:54 +0100 Subject: [PATCH 028/373] kill: Remove redundant container check. Signed-off-by: Ruben Jenster --- cmd/kill.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/cmd/kill.go b/cmd/kill.go index 1d529d96..f10784f6 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -88,28 +88,23 @@ func getSignal(ctx *cli.Context) (unix.Signal, error) { } func doKill(ctx *cli.Context) error { - err := clxc.loadContainer() + signum, err := getSignal(ctx) if err != nil { - return errors.Wrap(err, "failed to load container") - } - - // Attempting to send a signal to a container that is neither created nor running - // MUST have no effect on the container and MUST generate an error. - if !clxc.Container.Running() { - return fmt.Errorf("container is not running") + return errors.Wrap(err, "invalid signal param") } - signum, err := getSignal(ctx) + err = clxc.loadContainer() if err != nil { - return errors.Wrap(err, "invalid signal param") + return errors.Wrap(err, "failed to load container") } + pid, proc := clxc.safeGetInitPid() if proc != nil { // #nosec defer proc.Close() } if pid <= 0 { - return errors.New("init process is not running") + return errors.New("init process is neither running nor created") } log.Debug().Int("pid", pid).Int("signal", int(signum)).Msg("send kill signal") return unix.Kill(pid, signum) From 7742aae525b32ae95d6d9883aa41636de137cc1e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 16 Nov 2020 20:59:22 +0100 Subject: [PATCH 029/373] start: Fix naming of timeout environment variable. Increase timeout to 60s for both create and start. Signed-off-by: Ruben Jenster --- cmd/create.go | 2 +- cmd/start.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index a12fd7af..d2128106 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -48,7 +48,7 @@ var createCmd = cli.Command{ Name: "timeout", Usage: "timeout for container creation", EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, - Value: time.Second * 5, + Value: time.Second * 60, Destination: &clxc.CreateTimeout, }, }, diff --git a/cmd/start.go b/cmd/start.go index 05fc38b1..7f277b92 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -22,8 +22,8 @@ starts &cli.DurationFlag{ Name: "timeout", Usage: "timeout for reading from syncfifo", - EnvVars: []string{"CRIO_LXC_TIMEOUT_START"}, - Value: time.Second * 30, + EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, + Value: time.Second * 60, Destination: &clxc.StartTimeout, }, }, From f98f23dd86acf2f56a33e99ff99c3edf0f1c5152 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 00:27:30 +0100 Subject: [PATCH 030/373] create: Fix race condition when createContainer is called after saveConfig. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index b7d7052d..5fdc4b51 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -80,10 +80,9 @@ func (c *crioLXC) configFilePath() string { return c.runtimePath("config") } +// loadContainer checks for the existence of the lxc config file. +// It returns an error if the config file does not exist. func (c *crioLXC) loadContainer() error { - // Check for container existence by looking for config file. - // Otherwise lxc.NewContainer will return an empty container - // struct and we'll report wrong info _, err := os.Stat(clxc.configFilePath()) if os.IsNotExist(err) { return errContainerNotExist @@ -104,15 +103,26 @@ func (c *crioLXC) loadContainer() error { return nil } +// createContainer creates a new container. +// It must only be called once during the lifecycle of a container. func (c *crioLXC) createContainer() error { + // avoid creating a container + if _, err := os.Stat(clxc.configFilePath()); err == nil { + return errContainerExist + } + if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } + + // An empty tmpfile is created to ensure that createContainer can only succeed once. + // The config file is atomically activated in saveConfig. f, err := os.OpenFile(c.runtimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) if err != nil { return err } f.Close() + container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { return err @@ -121,18 +131,28 @@ func (c *crioLXC) createContainer() error { return nil } +// saveConfig creates and atomically enables the lxc config file. +// Any config changes via clxc.setConfigItem must be done +// before calling saveConfig. func (c *crioLXC) saveConfig() error { - // Write out final config file for debugging and use with lxc-attach: - // Do not edit config after this. + // Allow it to be called once and only after createContainer. tmpFile := c.runtimePath(".config") + if _, err := os.Stat(tmpFile); err != nil { + return errors.Wrap(err, "failed to stat config tmpfile") + } + // Don't overwrite an existing config. + cfgFile := c.configFilePath() + if _, err := os.Stat(cfgFile); err == nil { + return fmt.Errorf("config file %s already exists", cfgFile) + } err := clxc.Container.SaveConfigFile(tmpFile) if err != nil { return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) } - if err := os.Rename(tmpFile, clxc.configFilePath()); err != nil { + if err := os.Rename(tmpFile, cfgFile); err != nil { return errors.Wrap(err, "failed to rename config file") } - log.Debug().Str("file", clxc.configFilePath()).Msg("created lxc config file") + log.Debug().Str("file", cfgFile).Msg("created lxc config file") return nil } From 6093e8d8da81968a09dec84ac4d030ba8317cce2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 11:15:13 +0100 Subject: [PATCH 031/373] Add support for log level lxc.NOTICE Signed-off-by: Ruben Jenster --- cmd/clxc.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 5fdc4b51..ecbe9c42 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -243,7 +243,8 @@ func (c *crioLXC) configureLogging() error { zerolog.SetGlobalLevel(zerolog.TraceLevel) case lxc.DEBUG: zerolog.SetGlobalLevel(zerolog.DebugLevel) - case lxc.INFO: + case lxc.INFO, lxc.NOTICE: + // zerolog does not support a `notice` log-level notice zerolog.SetGlobalLevel(zerolog.InfoLevel) case lxc.WARN: zerolog.SetGlobalLevel(zerolog.WarnLevel) @@ -261,6 +262,8 @@ func parseLogLevel(s string) (lxc.LogLevel, error) { return lxc.DEBUG, nil case "info": return lxc.INFO, nil + case "notice": + return lxc.NOTICE, nil case "warn": return lxc.WARN, nil case "error": From fc13ace18e32e36396dc89debd7b29f8b15ba335 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 12:27:01 +0100 Subject: [PATCH 032/373] Improve logging. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 6 +++--- cmd/clxc.go | 2 +- cmd/create.go | 10 +++++----- cmd/exec.go | 7 ++++--- cmd/kill.go | 2 +- cmd/main.go | 2 +- cmd/start.go | 1 + cmd/state.go | 2 +- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 64adac9a..700fe7d8 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -44,15 +44,15 @@ func configureCgroup(spec *specs.Spec) error { } } if blockio := spec.Linux.Resources.BlockIO; blockio != nil { - log.Warn().Msg("TODO cgroup blockio controller not implemented") + log.Debug().Msg("TODO cgroup blockio controller not implemented") } if hugetlb := spec.Linux.Resources.HugepageLimits; hugetlb != nil { // set Hugetlb limit (in bytes) - log.Warn().Msg("TODO cgroup hugetlb controller not implemented") + log.Debug().Msg("TODO cgroup hugetlb controller not implemented") } if net := spec.Linux.Resources.Network; net != nil { - log.Warn().Msg("TODO cgroup network controller not implemented") + log.Debug().Msg("TODO cgroup network controller not implemented") } return nil } diff --git a/cmd/clxc.go b/cmd/clxc.go index ecbe9c42..083da719 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -244,7 +244,7 @@ func (c *crioLXC) configureLogging() error { case lxc.DEBUG: zerolog.SetGlobalLevel(zerolog.DebugLevel) case lxc.INFO, lxc.NOTICE: - // zerolog does not support a `notice` log-level notice + // zerolog does not support a `notice` log-level notice zerolog.SetGlobalLevel(zerolog.InfoLevel) case lxc.WARN: zerolog.SetGlobalLevel(zerolog.WarnLevel) diff --git a/cmd/create.go b/cmd/create.go index d2128106..60157129 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -104,7 +104,8 @@ func doCreateInternal() error { if err := configureContainer(spec); err != nil { return errors.Wrap(err, "failed to configure container") } - return startContainer(spec, clxc.CreateTimeout) + log.Info().Msg("start container process") + return runStartCmd(spec, clxc.CreateTimeout) } func configureContainer(spec *specs.Spec) error { @@ -437,14 +438,14 @@ func ensureDefaultDevices(spec *specs.Spec) error { return nil } -func startContainer(spec *specs.Spec, timeout time.Duration) error { +func runStartCmd(spec *specs.Spec, timeout time.Duration) error { // #nosec cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. // This is required because environment variables defined by containers contain newlines and other tokens - // that can not be handled properly by lxc. + // that can not be handled properly within the lxc config file. cmd.Env = []string{} if clxc.ConsoleSocket != "" { @@ -472,9 +473,8 @@ func startContainer(spec *specs.Spec, timeout time.Duration) error { return errors.Wrapf(err, "failed to write init spec") } - log.Debug().Strs("args", cmd.Args).Msg("running start cmd") if err := cmd.Start(); err != nil { - return errors.Wrap(err, "failed to run start cmd") + return errors.Wrap(err, "failed to start container process") } if clxc.PidFile != "" { diff --git a/cmd/exec.go b/cmd/exec.go index de0c805b..8f4566f4 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -75,8 +75,6 @@ func doExec(ctx *cli.Context) error { attachOpts.Groups[i] = int(g) } } - log.Debug().Int("uid", attachOpts.UID).Int("gid", attachOpts.GID).Ints("groups", attachOpts.Groups).Msg("process user") - log.Debug().Strs("arg", procArgs).Msg("process args") attachOpts.Cwd = procSpec.Cwd // Use the environment defined by the process spec. attachOpts.ClearEnv = true @@ -107,7 +105,10 @@ func doExec(ctx *cli.Context) error { attachOpts.StderrFd = os.Stderr.Fd() detach := ctx.Bool("detach") - log.Debug().Bool("detach", detach).Strs("args", procArgs).Msg("exec cmd") + + log.Info().Bool("detach", detach).Strs("args", procArgs). + Int("uid", attachOpts.UID).Int("gid", attachOpts.GID). + Ints("groups", attachOpts.Groups).Msg("attach cmd to container") if detach { pidFile := ctx.String("pid-file") diff --git a/cmd/kill.go b/cmd/kill.go index f10784f6..e7d83734 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -106,6 +106,6 @@ func doKill(ctx *cli.Context) error { if pid <= 0 { return errors.New("init process is neither running nor created") } - log.Debug().Int("pid", pid).Int("signal", int(signum)).Msg("send kill signal") + log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") return unix.Kill(pid, signum) } diff --git a/cmd/main.go b/cmd/main.go index 6af4a26d..5d39d260 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -174,7 +174,7 @@ func main() { for key, val := range env { log.Trace().Str("env", key).Str("val", val).Msg("environment file value") } - log.Info().Str("file", envFile).Msg("loaded environment variables from file") + log.Debug().Str("file", envFile).Msg("loaded environment variables from file") } else { if os.IsNotExist(envErr) { log.Warn().Str("file", envFile).Msg("environment file does not exist") diff --git a/cmd/start.go b/cmd/start.go index 7f277b92..5eb72ddc 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -30,6 +30,7 @@ starts } func doStart(ctx *cli.Context) error { + log.Info().Msg("notify init to start container process") fifoPath := clxc.runtimePath(internal.SyncFifoPath) // #nosec f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) diff --git a/cmd/state.go b/cmd/state.go index dbb4bd1d..c37e9f80 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -47,7 +47,7 @@ func doState(ctx *cli.Context) error { } s.Pid, s.Status, err = clxc.getContainerState() - log.Debug().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") + log.Info().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") if stateJSON, err := json.Marshal(s); err == nil { fmt.Fprint(os.Stdout, string(stateJSON)) From 3e16f5a7ed14f611fb83d6a2da2f9482b254607b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 12:27:26 +0100 Subject: [PATCH 033/373] delete: Move cgroup removal to group file. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 122 ++++++++++++++++++++++++++++++++++++++++++ cmd/delete.go | 145 +++----------------------------------------------- 2 files changed, 130 insertions(+), 137 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 700fe7d8..c8c56b86 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -2,11 +2,16 @@ package main import ( "fmt" + "io/ioutil" + "os" "path/filepath" + "strconv" "strings" + "time" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md @@ -230,3 +235,120 @@ func parseSystemdCgroupPath(s string) (cg cgroupPath) { } return cg } + +func tryRemoveCgroups(c *crioLXC) { + configItems := []string{"lxc.cgroup.dir", "lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor"} + for _, item := range configItems { + dir := clxc.getConfigItem(item) + if dir == "" { + continue + } + err := tryRemoveAllCgroupDir(c, dir, true) + if err != nil { + log.Warn().Err(err).Str("lxc.config", item).Msg("failed to remove cgroup scope") + continue + } + // try to remove outer directory, in case this is the POD that is deleted + // FIXME crio should delete the kubepods slice + outerSlice := filepath.Dir(dir) + err = tryRemoveAllCgroupDir(c, outerSlice, false) + if err != nil { + log.Debug().Err(err).Str("file", outerSlice).Msg("failed to remove cgroup slice") + } + } +} + +func tryRemoveAllCgroupDir(c *crioLXC, cgroupPath string, killProcs bool) error { + dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) + // #nosec + dir, err := os.Open(dirName) + if os.IsNotExist(err) { + return nil + } + if err != nil { + return err + } + if killProcs { + err := loopKillCgroupProcs(dirName, time.Second*2) + if err != nil { + log.Trace().Err(err).Str("file", dirName).Msg("failed to kill cgroup procs") + } + } + entries, err := dir.Readdir(-1) + if err != nil { + return err + } + // leftover lxc.pivot path + for _, i := range entries { + if i.IsDir() && i.Name() != "." && i.Name() != ".." { + fullPath := filepath.Join(dirName, i.Name()) + if err := unix.Rmdir(fullPath); err != nil { + return errors.Wrapf(err, "failed rmdir %s", fullPath) + } + } + } + return unix.Rmdir(dirName) +} + +// loopKillCgroupProcs loops over PIDs in cgroup.procs and sends +// each PID the kill signal until there are no more PIDs left. +// Looping is required because processes that have been created (forked / exec) +// may not 'yet' be visible in cgroup.procs. +func loopKillCgroupProcs(scope string, timeout time.Duration) error { + timer := time.NewTimer(timeout) + defer timer.Stop() + for { + select { + case <-timer.C: + return fmt.Errorf("timeout killing processes") + default: + nprocs, err := killCgroupProcs(scope) + if err != nil { + return err + } + if nprocs == 0 { + return nil + } + time.Sleep(time.Millisecond * 50) + } + } +} + +// getCgroupProcs returns the PIDs for all processes which are in the +// same control group as the process for which the PID is given. +func killCgroupProcs(scope string) (int, error) { + cgroupProcsPath := filepath.Join(scope, "cgroup.procs") + log.Trace().Str("file", cgroupProcsPath).Msg("reading control group process list") + // #nosec + procsData, err := ioutil.ReadFile(cgroupProcsPath) + if err != nil { + return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) + } + // cgroup.procs contains one PID per line and is newline separated. + // A trailing newline is always present. + s := strings.TrimSpace(string(procsData)) + if s == "" { + return 0, nil + } + pidStrings := strings.Split(s, "\n") + numPids := len(pidStrings) + if numPids == 0 { + return 0, nil + } + + // This indicates improper signal handling / termination of the container. + log.Warn().Strs("pids", pidStrings).Str("cgroup", scope).Msg("killing left-over container processes") + + for _, s := range pidStrings { + pid, err := strconv.Atoi(s) + if err != nil { + // Reading garbage from cgroup.procs should not happen. + return -1, errors.Wrapf(err, "failed to convert PID %q to number", s) + } + if err := unix.Kill(pid, 9); err != nil { + return -1, errors.Wrapf(err, "failed to kill %d", pid) + } + } + + return numPids, nil +} diff --git a/cmd/delete.go b/cmd/delete.go index 4bea10fb..4bbdd203 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -2,18 +2,10 @@ package main import ( "fmt" - "io/ioutil" "os" - "path/filepath" - "strconv" - "strings" - "time" "github.com/pkg/errors" "github.com/urfave/cli/v2" - - "golang.org/x/sys/unix" - lxc "gopkg.in/lxc/go-lxc.v2" ) var deleteCmd = cli.Command{ @@ -34,50 +26,24 @@ var deleteCmd = cli.Command{ func doDelete(ctx *cli.Context) error { err := clxc.loadContainer() - if err == errContainerNotExist && ctx.Bool("force") { - return nil - } if err != nil { return err } - c := clxc.Container - state := c.State() - if state != lxc.STOPPED { - if !ctx.Bool("force") { - return fmt.Errorf("container must be stopped before delete (current state is %s)", state) - } - - if err := c.Stop(); err != nil { - return errors.Wrap(err, "failed to stop container") - } + _, state, err := clxc.getContainerState() + if state != stateStopped { + return fmt.Errorf("container is not not stopped, current state is %s", state) } - if err := c.Destroy(); err != nil { - return errors.Wrap(err, "failed to delete container") + if err := clxc.Container.Stop(); err != nil { + return errors.Wrap(err, "failed to stop container") } - if dir := clxc.getConfigItem("lxc.cgroup.dir"); dir != "" { - if err := tryRemoveAllCgroupDir(c, dir, true); err != nil { - log.Warn().Err(err).Msg("remove lxc.cgroup.dir failed") - } else { - // try to remove outer directory, in case this is the POD that is deleted - // FIXME crio should delete the kubepods slice - // #nosec - tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) - } + if err := clxc.Container.Destroy(); err != nil { + return errors.Wrap(err, "failed to delete container") } - if dir := clxc.getConfigItem("lxc.cgroup.dir.container"); dir != "" { - if err := tryRemoveAllCgroupDir(c, dir, true); err != nil { - log.Warn().Err(err).Msg("remove lxc.cgroup.dir.container failed") - } else { - // try to remove outer directory, in case this is the POD that is deleted - // FIXME crio should delete the kubepods slice - // #nosec - tryRemoveAllCgroupDir(c, filepath.Dir(dir), false) - } - } + tryRemoveCgroups(&clxc) // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." @@ -85,98 +51,3 @@ func doDelete(ctx *cli.Context) error { // delete the /var/lib/lxc/$containerID/config file: return os.RemoveAll(clxc.runtimePath()) } - -func tryRemoveAllCgroupDir(c *lxc.Container, cgroupPath string, killProcs bool) error { - dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) - // #nosec - dir, err := os.Open(dirName) - if os.IsNotExist(err) { - return nil - } - if err != nil { - return err - } - if killProcs { - err := loopKillCgroupProcs(dirName, time.Second*2) - if err != nil { - log.Trace().Err(err).Str("file", dirName).Msg("failed to kill cgroup procs") - } - } - entries, err := dir.Readdir(-1) - if err != nil { - return err - } - // leftover lxc.pivot path - for _, i := range entries { - if i.IsDir() && i.Name() != "." && i.Name() != ".." { - fullPath := filepath.Join(dirName, i.Name()) - if err := unix.Rmdir(fullPath); err != nil { - return errors.Wrapf(err, "failed rmdir %s", fullPath) - } - } - } - return unix.Rmdir(dirName) -} - -// loopKillCgroupProcs loops over PIDs in cgroup.procs and sends -// each PID the kill signal until there are no more PIDs left. -// Looping is required because processes that have been created (forked / exec) -// may not 'yet' be visible in cgroup.procs. -func loopKillCgroupProcs(scope string, timeout time.Duration) error { - timer := time.NewTimer(timeout) - defer timer.Stop() - for { - select { - case <-timer.C: - return fmt.Errorf("timeout killing processes") - default: - nprocs, err := killCgroupProcs(scope) - if err != nil { - return err - } - if nprocs == 0 { - return nil - } - time.Sleep(time.Millisecond * 50) - } - } -} - -// getCgroupProcs returns the PIDs for all processes which are in the -// same control group as the process for which the PID is given. -func killCgroupProcs(scope string) (int, error) { - cgroupProcsPath := filepath.Join(scope, "cgroup.procs") - log.Trace().Str("file", cgroupProcsPath).Msg("reading control group process list") - // #nosec - procsData, err := ioutil.ReadFile(cgroupProcsPath) - if err != nil { - return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) - } - // cgroup.procs contains one PID per line and is newline separated. - // A trailing newline is always present. - s := strings.TrimSpace(string(procsData)) - if s == "" { - return 0, nil - } - pidStrings := strings.Split(s, "\n") - numPids := len(pidStrings) - if numPids == 0 { - return 0, nil - } - - // This indicates improper signal handling / termination of the container. - log.Warn().Strs("pids", pidStrings).Str("cgroup", scope).Msg("killing left-over container processes") - - for _, s := range pidStrings { - pid, err := strconv.Atoi(s) - if err != nil { - // Reading garbage from cgroup.procs should not happen. - return -1, errors.Wrapf(err, "failed to convert PID %q to number", s) - } - if err := unix.Kill(pid, 9); err != nil { - return -1, errors.Wrapf(err, "failed to kill %d", pid) - } - } - - return numPids, nil -} From 08b860a6b72aa1a169e9ba37189567f9280392dc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 14:56:38 +0100 Subject: [PATCH 034/373] delete: Fixes. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 4 ++++ cmd/delete.go | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 083da719..e5b2bcd2 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -332,6 +332,10 @@ const ( envStateCreated = "CRIO_LXC_STATE=" + stateCreated ) +func (c *crioLXC) isContainerStopped() bool { + return c.Container.State() == lxc.STOPPED +} + // getContainerInitState returns the runtime state of the container. // It is used to determine whether the container state is 'created' or 'running'. // The init process environment contains #envStateCreated if the the container diff --git a/cmd/delete.go b/cmd/delete.go index 4bbdd203..5cdf0346 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -30,13 +30,13 @@ func doDelete(ctx *cli.Context) error { return err } - _, state, err := clxc.getContainerState() - if state != stateStopped { - return fmt.Errorf("container is not not stopped, current state is %s", state) - } - - if err := clxc.Container.Stop(); err != nil { - return errors.Wrap(err, "failed to stop container") + if !clxc.isContainerStopped() { + if !ctx.Bool("force") { + return fmt.Errorf("container is not not stopped (current state %s)", clxc.Container.State()) + } + if err := clxc.Container.Stop(); err != nil { + return errors.Wrap(err, "failed to stop container") + } } if err := clxc.Container.Destroy(); err != nil { From 2240bb384cdabf8a753e8c7924681984617e3920 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 17 Nov 2020 14:57:27 +0100 Subject: [PATCH 035/373] create: Improve logging. Signed-off-by: Ruben Jenster --- cmd/create.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 60157129..230f9c07 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -104,8 +104,15 @@ func doCreateInternal() error { if err := configureContainer(spec); err != nil { return errors.Wrap(err, "failed to configure container") } - log.Info().Msg("start container process") - return runStartCmd(spec, clxc.CreateTimeout) + + // #nosec + startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) + if err := runStartCmd(startCmd, spec, clxc.CreateTimeout); err != nil { + return err + } + ps := startCmd.ProcessState + log.Info().Int("pid", ps.Pid()).Int("status", ps.ExitCode()).Msg("started container process") + return nil } func configureContainer(spec *specs.Spec) error { @@ -438,9 +445,7 @@ func ensureDefaultDevices(spec *specs.Spec) error { return nil } -func runStartCmd(spec *specs.Spec, timeout time.Duration) error { - // #nosec - cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) +func runStartCmd(cmd *exec.Cmd, spec *specs.Spec, timeout time.Duration) error { // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. @@ -452,7 +457,7 @@ func runStartCmd(spec *specs.Spec, timeout time.Duration) error { if err := clxc.saveConfig(); err != nil { return err } - return startConsole(cmd, clxc.ConsoleSocket) + return runStartCmdConsole(cmd, clxc.ConsoleSocket) } if !spec.Process.Terminal { // Inherit stdio from calling process (conmon). @@ -484,7 +489,7 @@ func runStartCmd(spec *specs.Spec, timeout time.Duration) error { return nil } -func startConsole(cmd *exec.Cmd, consoleSocket string) error { +func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { addr, err := net.ResolveUnixAddr("unix", consoleSocket) if err != nil { return errors.Wrap(err, "failed to resolve console socket") From af8f66b2cb5d0ef28130c3f4751f471d5921ce6f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:40:03 +0100 Subject: [PATCH 036/373] cgroup: Enable cgroup controllers (disabled) Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index c8c56b86..c781b264 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "os" + "os/exec" "path/filepath" "strconv" "strings" @@ -70,6 +71,12 @@ func configureCgroupPath(linux *specs.Linux) error { return clxc.setConfigItem("lxc.cgroup.dir", linux.CgroupsPath) } cgPath := parseSystemdCgroupPath(linux.CgroupsPath) + + /* + if err := enableCgroupControllers(cgPath); err != nil { + return errors.Wrapf(err, "cgroup path error") + } + */ // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb // checking for on of the config items shuld be enough, because they were introduced together ... if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { @@ -212,6 +219,14 @@ func (cg cgroupPath) String() string { return filepath.Join(append(cg.Slices, cg.Scope)...) } +func (cg cgroupPath) SlicePath() string { + return filepath.Join("/sys/fs/cgroup", filepath.Join(cg.Slices...)) +} + +func (cg cgroupPath) ScopePath() string { + return filepath.Join(cg.SlicePath(), cg.Scope) +} + // kubernetes creates the cgroup hierarchy which can be changed by serveral cgroup related flags. // kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod87f8bc68_7c18_4a1d_af9f_54eff815f688.slice // kubepods-burstable-pod9da3b2a14682e1fb23be3c2492753207.slice:crio:fe018d944f87b227b3b7f86226962639020e99eac8991463bf7126ef8e929589 @@ -352,3 +367,51 @@ func killCgroupProcs(scope string) (int, error) { return numPids, nil } + +func enableCgroupControllers(cg cgroupPath) error { + slice := cg.ScopePath() + // #nosec + if err := os.MkdirAll(slice, 755); err != nil { + return err + } + // enable all available controllers in the scope + data, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") + if err != nil { + return errors.Wrap(err, "failed to read cgroup.controllers") + } + controllers := strings.Split(strings.TrimSpace(string(data)), " ") + + var b strings.Builder + for i, c := range controllers { + if i > 0 { + b.WriteByte(' ') + } + b.WriteByte('+') + b.WriteString(c) + } + b.WriteString("\n") + + s := b.String() + + base := "/sys/fs/cgroup" + for _, elem := range cg.Slices { + base = filepath.Join(base, elem) + c := filepath.Join(base, "cgroup.subtree_control") + err := ioutil.WriteFile(c, []byte(s), 0) + if err != nil { + return errors.Wrapf(err, "failed to enable cgroup controllers in %s", base) + } + log.Info().Str("file", base).Str("controllers", s).Msg("cgroup activated") + } + return nil +} + +func auditCgroupSubtreeControl(cg cgroupPath, auditKey string) error { + log.Debug().Str("file", cg.SlicePath()).Str("key", auditKey).Msg("audit cgroup subtree control") + watchPath := filepath.Join(cg.SlicePath(), "cgroup.subtree_control") + out, err := exec.Command("auditctl", "-w", watchPath, "-p", "w", "-k", auditKey).CombinedOutput() + if err != nil { + return errors.Wrapf(err, "auditctl error %s", string(out)) + } + return nil +} From 8cc929d2d6bbce476491dd2194784e856418cf66 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:40:58 +0100 Subject: [PATCH 037/373] Container state fixes. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 51 ++++----------------------------------- cmd/create.go | 34 ++++++++++---------------- cmd/delete.go | 25 +++++++++++++++---- cmd/init/init.go | 11 ++------- cmd/internal/internal.go | 38 +++++++++++++++++++++++++++++ cmd/kill.go | 6 +---- cmd/main.go | 6 ++++- cmd/start.go | 36 ++++----------------------- cmd/state.go | 14 ++++++++++- cmd/utils.go | 22 ++++++++++++++++- crio-lxc-container-hook | Bin 0 -> 16816 bytes 11 files changed, 123 insertions(+), 120 deletions(-) create mode 100755 crio-lxc-container-hook diff --git a/cmd/clxc.go b/cmd/clxc.go index e5b2bcd2..e60c234b 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -111,7 +111,7 @@ func (c *crioLXC) createContainer() error { return errContainerExist } - if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { + if err := os.Mkdir(c.runtimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } @@ -342,27 +342,19 @@ func (c *crioLXC) isContainerStopped() bool { // is created, but not yet running/started. // This requires the proc filesystem to be mounted on the host. func (c *crioLXC) getContainerState() (int, string, error) { - switch state := c.Container.State(); state { - case lxc.STARTING: - return 0, stateCreating, nil - case lxc.STOPPED: + if c.isContainerStopped() { return 0, stateStopped, nil } - pid, proc := c.safeGetInitPid() - if proc != nil { - // #nosec - defer proc.Close() - } - if pid <= 0 { - return 0, stateStopped, nil + pid := c.Container.InitPid() + if pid < 0 { + return 0, stateCreating, nil } envFile := fmt.Sprintf("/proc/%d/environ", pid) // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { - // This is fatal. It should not happen because a filehandle to /proc/%d is open. return 0, stateStopped, errors.Wrapf(err, "failed to read init process environment %s", envFile) } @@ -374,36 +366,3 @@ func (c *crioLXC) getContainerState() (int, string, error) { } return pid, stateRunning, nil } - -func (c *crioLXC) safeGetInitPid() (pid int, proc *os.File) { - pid = c.Container.InitPid() - if pid <= 0 { - // Errors returned from safeGetInitPid indicate that the init process has died. - return 0, nil - } - // Open the proc directory of the init process to avoid that - // it's PID is recycled before it receives the signal. - proc, err := os.Open(fmt.Sprintf("/proc/%d", pid)) - - // double check that the init process still exists, and the proc - // directory actually belongs to the init process. - pid2 := c.Container.InitPid() - if pid2 != pid { - if proc != nil { - // #nosec - proc.Close() - } - // init process has died which should only happen if /proc/%d was not opened - return 0, nil - } - - // The init PID still exists, but /proc/{pid} can not be opened. - // The only reason maybe that the proc filesystem is not mounted. - // It's unlikely a permissions problem because crio runs as privileged process. - // This leads to race conditions and should appear in the logs. - if proc == nil { - log.Error().Err(err).Int("pid", pid).Msg("failed to open /proc directory for init PID - procfs mounted?") - } - - return pid, proc -} diff --git a/cmd/create.go b/cmd/create.go index 230f9c07..7b5aa04f 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -45,10 +45,11 @@ var createCmd = cli.Command{ Destination: &clxc.PidFile, }, &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for container creation", - EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, - Value: time.Second * 60, + Name: "timeout", + Usage: "timeout for sending pty master to socket", + EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, + Value: time.Second * 60, + // TODO rename to console-socket-timeout Destination: &clxc.CreateTimeout, }, }, @@ -107,12 +108,12 @@ func doCreateInternal() error { // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) - if err := runStartCmd(startCmd, spec, clxc.CreateTimeout); err != nil { - return err + if err := runStartCmd(startCmd, spec); err != nil { + return errors.Wrap(err, "failed to start container process") } - ps := startCmd.ProcessState - log.Info().Int("pid", ps.Pid()).Int("status", ps.ExitCode()).Msg("started container process") - return nil + log.Info().Int("pid", startCmd.Process.Pid).Msg("started container process") + return createPidFile(clxc.PidFile, startCmd.Process.Pid) + } func configureContainer(spec *specs.Spec) error { @@ -445,7 +446,7 @@ func ensureDefaultDevices(spec *specs.Spec) error { return nil } -func runStartCmd(cmd *exec.Cmd, spec *specs.Spec, timeout time.Duration) error { +func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. @@ -477,16 +478,7 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec, timeout time.Duration) error { if err := internal.WriteSpec(spec, clxc.runtimePath(internal.InitSpec)); err != nil { return errors.Wrapf(err, "failed to write init spec") } - - if err := cmd.Start(); err != nil { - return errors.Wrap(err, "failed to start container process") - } - - if clxc.PidFile != "" { - log.Debug().Str("file", clxc.PidFile).Msg("creating PID file") - return createPidFile(clxc.PidFile, cmd.Process.Pid) - } - return nil + return cmd.Start() } func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { @@ -499,7 +491,7 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { return errors.Wrap(err, "connecting to console socket failed") } defer conn.Close() - deadline := time.Now().Add(time.Second * 10) + deadline := time.Now().Add(time.Second * clxc.CreateTimeout) err = conn.SetDeadline(deadline) if err != nil { return errors.Wrap(err, "failed to set connection deadline") diff --git a/cmd/delete.go b/cmd/delete.go index 5cdf0346..be17018f 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -6,6 +6,7 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli/v2" + "golang.org/x/sys/unix" ) var deleteCmd = cli.Command{ @@ -30,24 +31,38 @@ func doDelete(ctx *cli.Context) error { return err } + force := ctx.Bool("force") + log.Info().Bool("force", force).Msg("delete container") + if !clxc.isContainerStopped() { - if !ctx.Bool("force") { + if !force { return fmt.Errorf("container is not not stopped (current state %s)", clxc.Container.State()) } - if err := clxc.Container.Stop(); err != nil { - return errors.Wrap(err, "failed to stop container") + + pid := clxc.Container.InitPid() + if pid > 0 { + log.Info().Int("pid", pid).Int("signal", 9).Msg("kill init") + err := unix.Kill(pid, 9) + if err != nil { + return err + } } + // wait for container to be stopped ? + //if ! clxc.Container.Wait(lxc.STOPPED, time.Second*30) { + // return fmt.Errorf("timeout") + // } } if err := clxc.Container.Destroy(); err != nil { - return errors.Wrap(err, "failed to delete container") + return errors.Wrap(err, "failed to destroy container") } - tryRemoveCgroups(&clxc) + //tryRemoveCgroups(&clxc) // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." // TODO - because we set rootfs.managed=0, Destroy() doesn't // delete the /var/lib/lxc/$containerID/config file: + return os.RemoveAll(clxc.runtimePath()) } diff --git a/cmd/init/init.go b/cmd/init/init.go index 8b6e2d22..a8189f00 100644 --- a/cmd/init/init.go +++ b/cmd/init/init.go @@ -3,7 +3,6 @@ package main import ( "github.com/lxc/crio-lxc/cmd/internal" "golang.org/x/sys/unix" - "os" "os/exec" "os/user" "strings" @@ -19,14 +18,8 @@ func main() { panic(err) } - fifo, err := os.OpenFile(internal.SyncFifoPath, os.O_WRONLY, 0) - if err != nil { - fail(err, "open sync fifo") - } - - _, err = fifo.Write([]byte(internal.SyncFifoContent)) - if err != nil { - fail(err, "write to sync fifo") + if err := internal.WriteFifo(); err != nil { + fail(err, "write fifo") } env := setHome(spec.Process.Env, spec.Process.User.Username, spec.Process.Cwd) diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go index d1478636..9c1b2740 100644 --- a/cmd/internal/internal.go +++ b/cmd/internal/internal.go @@ -3,7 +3,9 @@ package internal import ( "encoding/json" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" "os" + "time" ) const ( @@ -51,3 +53,39 @@ func WriteSpec(spec *specs.Spec, specFilePath string) error { } return f.Sync() } + +func WriteFifo() error { + f, err := os.OpenFile(SyncFifoPath, os.O_WRONLY, 0) + if err != nil { + return err + } + _, err = f.Write([]byte(SyncFifoContent)) + if err != nil { + return err + } + return f.Close() +} + +func ReadFifo(fifoPath string, timeout time.Duration) error { + // #nosec + f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) + if err != nil { + return errors.Wrap(err, "failed to open sync fifo") + } + err = f.SetDeadline(time.Now().Add(timeout)) + if err != nil { + return errors.Wrap(err, "failed to set deadline") + } + // #nosec + defer f.Close() + + data := make([]byte, len(SyncFifoContent)) + n, err := f.Read(data) + if err != nil { + return errors.Wrap(err, "problem reading from fifo") + } + if n != len(SyncFifoContent) || string(data) != SyncFifoContent { + return errors.Errorf("bad fifo content: %s", string(data)) + } + return nil +} diff --git a/cmd/kill.go b/cmd/kill.go index e7d83734..afd6c6e3 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -98,11 +98,7 @@ func doKill(ctx *cli.Context) error { return errors.Wrap(err, "failed to load container") } - pid, proc := clxc.safeGetInitPid() - if proc != nil { - // #nosec - defer proc.Close() - } + pid := clxc.Container.InitPid() if pid <= 0 { return errors.New("init process is neither running nor created") } diff --git a/cmd/main.go b/cmd/main.go index 5d39d260..5d8490b7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -20,6 +20,10 @@ func main() { app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" app.Version = versionString() + // The default handler will exit the appp if the command returns an error + // that implements the cli.ExitCoder interface. + // E.g an unwrapped error from os.Exec + app.ExitErrHandler = func(context *cli.Context, err error) {} app.Commands = []*cli.Command{ &stateCmd, &createCmd, @@ -194,7 +198,7 @@ func main() { // Disable the default error messages for cmdline errors. // By default the app/cmd help is printed to stdout, which produces garbage in cri-o log output. - // Instead the cmdline is reflected to identify cmdline interface errors + // Instead the cmdline is printed to stderr to identify cmdline interface errors. errUsage := func(context *cli.Context, err error, isSubcommand bool) error { fmt.Fprintf(os.Stderr, "usage error %s: %s\n", err, os.Args) return err diff --git a/cmd/start.go b/cmd/start.go index 5eb72ddc..755021df 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -1,13 +1,10 @@ package main import ( - "fmt" - "os" + "time" "github.com/lxc/crio-lxc/cmd/internal" - "github.com/pkg/errors" "github.com/urfave/cli/v2" - "time" ) var startCmd = cli.Command{ @@ -31,34 +28,11 @@ starts func doStart(ctx *cli.Context) error { log.Info().Msg("notify init to start container process") - fifoPath := clxc.runtimePath(internal.SyncFifoPath) - // #nosec - f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) - log.Debug().Err(err).Str("fifo", fifoPath).Msg("open fifo") - if err != nil { - return errors.Wrap(err, "container not started - failed to open sync fifo") - } - // #nosec - defer f.Close() - done := make(chan error) - - go func() { - data := make([]byte, len(internal.SyncFifoContent)) - n, err := f.Read(data) - if err != nil { - done <- errors.Wrapf(err, "problem reading from fifo") - } - if n != len(internal.SyncFifoContent) || string(data) != internal.SyncFifoContent { - done <- errors.Errorf("bad fifo content: %s", string(data)) - } - done <- nil - }() - - select { - case err := <-done: + err := clxc.loadContainer() + if err != nil { return err - case <-time.After(clxc.StartTimeout): - return fmt.Errorf("timeout reading from syncfifo %s", fifoPath) } + + return internal.ReadFifo(clxc.runtimePath(internal.SyncFifoPath), clxc.StartTimeout) } diff --git a/cmd/state.go b/cmd/state.go index c37e9f80..5ddf914e 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -30,7 +30,15 @@ func doState(ctx *cli.Context) error { } // TODO save BundlePath to init spec + // TODO create a symlink to the pidfile and config in the runtime path bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") + pidFilePath := filepath.Join(bundlePath, "pidfile") + + pid, err := readPidFile(pidFilePath) + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "failed to load pidfile") + } + spec, err := internal.ReadSpec(filepath.Join(bundlePath, "config.json")) if err != nil { return errors.Wrapf(err, "failed to load spec from %s", bundlePath) @@ -40,13 +48,17 @@ func doState(ctx *cli.Context) error { Version: specs.Version, ID: clxc.Container.Name(), Bundle: bundlePath, + Pid: pid, } if spec.Annotations != nil { s.Annotations = spec.Annotations } - s.Pid, s.Status, err = clxc.getContainerState() + // FIXME do not return the init pid, but the container process PID instead ... + _, status, err := clxc.getContainerState() + s.Status = status + log.Info().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") if stateJSON, err := json.Marshal(s); err == nil { diff --git a/cmd/utils.go b/cmd/utils.go index 0d80a9d5..02f0dcc0 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -2,12 +2,23 @@ package main import ( "fmt" + "io/ioutil" "os" "path/filepath" + "strconv" + "strings" ) -// createPidFile atomically creates a pid file for the given pid at the given path func createPidFile(path string, pid int) error { + return createPidFileSimple(path, pid) +} + +func createPidFileSimple(path string, pid int) error { + return ioutil.WriteFile(path, []byte(strconv.Itoa(pid)), 0640) +} + +// createPidFile atomically creates a pid file for the given pid at the given path +func createPidFileComplex(path string, pid int) error { tmpDir := filepath.Dir(path) tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) @@ -26,3 +37,12 @@ func createPidFile(path string, pid int) error { } return os.Rename(tmpName, path) } + +func readPidFile(path string) (int, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return 0, err + } + s := strings.TrimSpace(string(data)) + return strconv.Atoi(s) +} diff --git a/crio-lxc-container-hook b/crio-lxc-container-hook new file mode 100755 index 0000000000000000000000000000000000000000..ca0f3bec1791069f166d5ebe068c93ef24abcce9 GIT binary patch literal 16816 zcmeHOYmi*Ub?((l=wYN?o>_x!4T1&n&`1I#%L17Z(yp%X>VXiT#AT00^U#j9JF}j- zBP7ZS!mGiWjK`&Bt;YB2={- zo_aHwwR|&uX0DMFD&@8M0;XIw(L>f5pMgW-3$32e zAv%O4RN{H_FWngR{-;U8umyT-f}fvdTc1$Ns>OZD9gF*7i~4ifzD0XhEDtZgHkeHZ zmrDH{J{RHm103v<^Kg6&$Avf~U4Tpg$47B|1P2rQy90-`8}AyR&TEl{vPlEj^@O1Gnt)-eek<|@PG8dLq7Nyd~lvCllk*QAH2l} z|C|s04?g%KKKRud$EdIq3F~7@<2V~<;6L%CMiN|Q-ArFRr3P|tmibt2KqYp@!K4S` zsfeq>;j9~p?g~eHcZCy?WSfn@pz^bmOVrG=+k6 zMh#?=DL0`KG1^n%1hiEm8;ztAD!vDX`qR0Ts}j*(ScJ9co(N?keaSoHs()819iu5X zy-P)V(|4pG*q6?-gyJa4M0-iKqnP@l^fu#$`yNS{O1p%5%Pzv?OG5#J%hG3J(mhs&NWrigCUcn9a*=CJRIV`i38VSNl%1K zj`Cb@B@Km4j<{TV5qT=ae`DtYlhyyHLWZHdcWwWP2bZ;-k|Q46P7#Dv*@N>sVJb~U zU@8Jr5txd=?>7RQw>{ZVL3P>di~`61-U_fn=ZQbp?g6?t9~R8DFB7v!gr zAJY6!$@3DR^04NAM4n53<%s5gNS;f6<&fr2kmpig*{}KUkmqtz8PNQrT*@o$n*SnsF5wlW`8&zCkso^x zKxc+Lm-5Pp=08WCOL*m!=68@koBWXG|A;)7^2)=S-$I^Cc;$%ZZz9j7yK+eLHbsmE^fpR|YhHHF+-4mF=3pf;^Yz%4W?kAkQVa5(4im{k2ng$tf-S)K$1>8hl}_ zj1uJ(Kkk%npVhVW>7LSze?@Sd(%fm3F0FbNp{(piLlbTD*Ro*M&x0g0eoFF*arZo@ zIOCZ`$mfUL+0~J@`TJ?{NlPLBh?ZaW5Xt55IfXIj_$xO!$H!ZpmXpr2@44r~K;9ad zRUI+)i2fUGAA4v2s($FI+%>m4gR8bcQaOcRx^tc4s*S*_=Y;^3qj2%$jI{t-KJ#QE z*f#$F-B3>^>UoY=+NoXHn!3i9 z4mrgTiJ+ODrnpsr?-Z|q^=V0z=GoMT@mEy&q1;UE@aPQP znND%Tc+9!-Og((v8Rd6i=;QxY5|j)c0<_5DJ7C6moUfU_1(-1dffpfZte?ipGn`)t>$Uv7~4%l!?N6*!y zbdDy6$4H8{Q7_MON{?LvPP&mH6FpgN<4AU4XrbE8P8V7$6DCDn&(BM)2 zSKAIehlSQKGu;)%!$ga^wR%8bR&#C{)otB~&!y}KJ@0%E26zfXQBGlGo!Ti(rjTc( zcnXsg4QEc_-@z^hXrP92{QnzPYvc8?|3XYIHdQbRZO4WN#}n@5_`7S#;P?)A=HPhL zoi}>PaQ-S3tL;jSZm{_P@~dqg=gjCbxM^%WRXofNMV*R7H}ycR&YMuDX&axhTgQ%J zk<_Q%X_RtKr6T53R@!#pJWg@aF1FyaHEX|pTUSKElOCZwM+sDnouL+q5hgAcl$LFU z1)k<#HubFlS~)@=u#g~s?ANRkQH7 z%YUw=f$XA#2tlz#yA6?9kEK`#=U;F+WjbULq$>~T8GYF!K)(-{RQV-sLpz3`(2i=$ zZ^8H|9_0`%>H)g8SmO9xThybwSmNNWb;&6kzT0mzHI`~Me)lc-H~540Vx9`lea`Wb zfKxc(Xn)igpo>m;%4T({YMXLq1M3j^Go8Y5%0svfQM>3VPjTDhL*z;vKE*s8oPFH- zQh0_D`!worIB9ZMAXXgE4Y4wApHXvrI@CtLP|UOa1vnERZM6LP36`%f>QlN{qO?;y zI-!>Jh2N}}PC0>VUehV}y@|To2laW|QrU)C)UF1c_}GR!P*eE<{C)6h@G@-K)nM@D zP+{LcJB8fPaMug$XAJD!sIkzTK0Yj6^WMwyp%;3H; zQ~V`r?eG-e&f;QM`4}Ij!(-E~5Chb8dT`(AYA#s*1?2VY{p~kcJx{ZAEd+;wNnLY{ zF^t{ea=&(Mxcp0Dt#v3d786*l_BZK=!Sjj%AWNWRGm9lN^A2Ac13okw6l9xxT)YfzGVaaMOWkZzQ!d9zZUWPP>UL3+Jfh&Qv-R zM=dE+i}*MYaeK8ueQ9)bw)2Ul2HWSr3JKbkv11kxwXb55nx8p>gqKc@Ul;CP-_vE=)hrgkOTJ_#o$6co!Lnrc*9n55{pK=z*`8Hl-BE9uqHBGt@50jbj(m*Hu<`_9%YBFuM<#IoEfpr|OWOU;7 zCzJQvDe_iLsSr8yy)WrOTfba4;{l;g@-0<|by)C&HY4pgWaaTBUMHy^5BYR^0BTV@ zkk@?84=exsCh}c*b3K>ZeqC;9x23mPny_@YrT18RuchCx^l?j1TKc@DFIxJxrDxcW z;?B49QcIUx+HL7=mL@FSZRtIh-fQVMEPdS4la`K!OiS0TS+g>*aNWjRFApqT61+ON zq&WbS@U8d~QuZl$i(B!$UdCx7-dY>4jrjE1IBmpdm@gr`Ao8sk-7>DcMXmT^UB+J{ zjv-~^+KA6q?UUkjYWqDJUDgEs&ZN-=W`B_Kl#$)tZC;=7+2@}$X^J20qST@S6Dk^p~jMr``B6KgKyOM9QBkP()w8pOm5eB zeSQF|6TkA9tXJTm;GZ>c2L`yqh7T0uneO=)woF2>3u%Vq%#!SDC+f4PtRfB49&TcR0v zX)uZh({9$y;VZ5vo{!1~iLl!r#s-X3Jd3Rwv2=K6UwTKRFC4?0g={#I+oPiC{((O1 z0EuDYo>W3_00~DjnaJKS9vx@)sze6+NW!sPfB#;ncsRY$q(QVdo!$k1!r|^Mt2cCo zyEd*3hgEp(A8uT|Vf`8vUe~kf#??LHP2JtMbZrf9U43IuS6KF+)b^v8JtcORirt7} zHoV|LuHMp8+lzv&BDM~_JEm!K3YwQqhw+jmhK(d?H)6m9WP@6RB2#N|~u=4dq{UrTA18;0?h0$)}E+uVa2aIc`qjVa=#|D!`=YVN48Vym;0t= zz$ha6a{nh(?)M;~6K#0YDllw|=*xAr&_h;O+S^?JI;(%9m6Pjlp>n@SeJ)YW`Zoik zPjbInyH2;)<+k~dFsa%99>89GxtGZ0i?2%c{>b>B~Mp zp&#Ub)apz8Rlr)d^pz$95fX~Ar)yRE`?0;^S7hdSy z&~5YR%l%6LA0{)2oZ;%c;3X8W@1=gZ&yoG!(tq-NL-eE{?u9PfFZyynR9*}aNzN0) zO|1W`DDdj5kd<6w=$K`NNc}>;jsmZ~T&Ip%eUWR{7ycn+C?o#M_0G7DKI`(PzXwCi zir0!nzxf(g^u1KZPE8q^_N9jFwa;((e5VtKv`6B~`y=t)Xqf*!D-6B9$+*-jvb_AA RO#fRejl>foXlb+le*@fN$20%{ literal 0 HcmV?d00001 From 9cd2690527638f515a33daa05e2b0408d3bbb008 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:41:40 +0100 Subject: [PATCH 038/373] Cleanup go.mod. Use go-lxc fork. Signed-off-by: Ruben Jenster --- go.mod | 17 ++++++----------- go.sum | 7 +++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index fb5c39b6..fe8eff63 100644 --- a/go.mod +++ b/go.mod @@ -5,19 +5,14 @@ require ( github.com/opencontainers/runtime-spec v1.0.2 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.20.0 - github.com/securego/gosec/v2 v2.5.0 // indirect - github.com/stretchr/testify v1.4.0 - github.com/urfave/cli v1.22.5 // indirect - github.com/urfave/cli/v2 v2.2.0 - golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect - golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 - golang.org/x/text v0.3.4 // indirect - golang.org/x/tools v0.0.0-20201110201400-7099162a900a // indirect - gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b + github.com/stretchr/testify v1.3.0 + github.com/urfave/cli/v2 v2.3.0 + golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 + gopkg.in/lxc/go-lxc.v2 v2.0.0 ) +replace gopkg.in/lxc/go-lxc.v2 v2.0.0 => github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef + replace github.com/vbatts/go-mtree v0.4.4 => github.com/vbatts/go-mtree v0.4.5-0.20190122034725-8b6de6073c1a replace github.com/openSUSE/umoci v0.4.4 => github.com/tych0/umoci v0.1.1-0.20190402232331-556620754fb1 diff --git a/go.sum b/go.sum index 6f103224..4bf904e5 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef h1:t2Xd3jCGWbSXE9HGhN7acei0a9Co9TiqlhaSD6Cec0I= +github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef/go.mod h1:BpD4MbHBk1uaTubH9ItkAJxE84u7J+IohxyP40SJ9hg= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -61,6 +63,8 @@ github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -93,6 +97,8 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM= +golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M= golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -124,6 +130,7 @@ gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b h1:nZGkhEMZTXoUuojsilS gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From b05d2acfcb484aa9ba59a4d7fc0719bb8a675046 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 18 Nov 2020 23:00:17 +0100 Subject: [PATCH 039/373] kill, delete: Send kill signal to container process. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 145 +------------------------------------------------- cmd/clxc.go | 49 ++++++++++++++--- cmd/delete.go | 30 ++--------- cmd/kill.go | 11 ++-- 4 files changed, 55 insertions(+), 180 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index c781b264..f2925bc4 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -2,13 +2,9 @@ package main import ( "fmt" - "io/ioutil" "os" - "os/exec" "path/filepath" - "strconv" "strings" - "time" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -251,29 +247,7 @@ func parseSystemdCgroupPath(s string) (cg cgroupPath) { return cg } -func tryRemoveCgroups(c *crioLXC) { - configItems := []string{"lxc.cgroup.dir", "lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor"} - for _, item := range configItems { - dir := clxc.getConfigItem(item) - if dir == "" { - continue - } - err := tryRemoveAllCgroupDir(c, dir, true) - if err != nil { - log.Warn().Err(err).Str("lxc.config", item).Msg("failed to remove cgroup scope") - continue - } - // try to remove outer directory, in case this is the POD that is deleted - // FIXME crio should delete the kubepods slice - outerSlice := filepath.Dir(dir) - err = tryRemoveAllCgroupDir(c, outerSlice, false) - if err != nil { - log.Debug().Err(err).Str("file", outerSlice).Msg("failed to remove cgroup slice") - } - } -} - -func tryRemoveAllCgroupDir(c *crioLXC, cgroupPath string, killProcs bool) error { +func tryRemoveAllCgroupDir(cgroupPath string) error { dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) // #nosec dir, err := os.Open(dirName) @@ -283,12 +257,6 @@ func tryRemoveAllCgroupDir(c *crioLXC, cgroupPath string, killProcs bool) error if err != nil { return err } - if killProcs { - err := loopKillCgroupProcs(dirName, time.Second*2) - if err != nil { - log.Trace().Err(err).Str("file", dirName).Msg("failed to kill cgroup procs") - } - } entries, err := dir.Readdir(-1) if err != nil { return err @@ -304,114 +272,3 @@ func tryRemoveAllCgroupDir(c *crioLXC, cgroupPath string, killProcs bool) error } return unix.Rmdir(dirName) } - -// loopKillCgroupProcs loops over PIDs in cgroup.procs and sends -// each PID the kill signal until there are no more PIDs left. -// Looping is required because processes that have been created (forked / exec) -// may not 'yet' be visible in cgroup.procs. -func loopKillCgroupProcs(scope string, timeout time.Duration) error { - timer := time.NewTimer(timeout) - defer timer.Stop() - for { - select { - case <-timer.C: - return fmt.Errorf("timeout killing processes") - default: - nprocs, err := killCgroupProcs(scope) - if err != nil { - return err - } - if nprocs == 0 { - return nil - } - time.Sleep(time.Millisecond * 50) - } - } -} - -// getCgroupProcs returns the PIDs for all processes which are in the -// same control group as the process for which the PID is given. -func killCgroupProcs(scope string) (int, error) { - cgroupProcsPath := filepath.Join(scope, "cgroup.procs") - log.Trace().Str("file", cgroupProcsPath).Msg("reading control group process list") - // #nosec - procsData, err := ioutil.ReadFile(cgroupProcsPath) - if err != nil { - return -1, errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) - } - // cgroup.procs contains one PID per line and is newline separated. - // A trailing newline is always present. - s := strings.TrimSpace(string(procsData)) - if s == "" { - return 0, nil - } - pidStrings := strings.Split(s, "\n") - numPids := len(pidStrings) - if numPids == 0 { - return 0, nil - } - - // This indicates improper signal handling / termination of the container. - log.Warn().Strs("pids", pidStrings).Str("cgroup", scope).Msg("killing left-over container processes") - - for _, s := range pidStrings { - pid, err := strconv.Atoi(s) - if err != nil { - // Reading garbage from cgroup.procs should not happen. - return -1, errors.Wrapf(err, "failed to convert PID %q to number", s) - } - if err := unix.Kill(pid, 9); err != nil { - return -1, errors.Wrapf(err, "failed to kill %d", pid) - } - } - - return numPids, nil -} - -func enableCgroupControllers(cg cgroupPath) error { - slice := cg.ScopePath() - // #nosec - if err := os.MkdirAll(slice, 755); err != nil { - return err - } - // enable all available controllers in the scope - data, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") - if err != nil { - return errors.Wrap(err, "failed to read cgroup.controllers") - } - controllers := strings.Split(strings.TrimSpace(string(data)), " ") - - var b strings.Builder - for i, c := range controllers { - if i > 0 { - b.WriteByte(' ') - } - b.WriteByte('+') - b.WriteString(c) - } - b.WriteString("\n") - - s := b.String() - - base := "/sys/fs/cgroup" - for _, elem := range cg.Slices { - base = filepath.Join(base, elem) - c := filepath.Join(base, "cgroup.subtree_control") - err := ioutil.WriteFile(c, []byte(s), 0) - if err != nil { - return errors.Wrapf(err, "failed to enable cgroup controllers in %s", base) - } - log.Info().Str("file", base).Str("controllers", s).Msg("cgroup activated") - } - return nil -} - -func auditCgroupSubtreeControl(cg cgroupPath, auditKey string) error { - log.Debug().Str("file", cg.SlicePath()).Str("key", auditKey).Msg("audit cgroup subtree control") - watchPath := filepath.Join(cg.SlicePath(), "cgroup.subtree_control") - out, err := exec.Command("auditctl", "-w", watchPath, "-p", "w", "-k", auditKey).CombinedOutput() - if err != nil { - return errors.Wrapf(err, "auditctl error %s", string(out)) - } - return nil -} diff --git a/cmd/clxc.go b/cmd/clxc.go index e60c234b..77e8dbce 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -83,7 +83,7 @@ func (c *crioLXC) configFilePath() string { // loadContainer checks for the existence of the lxc config file. // It returns an error if the config file does not exist. func (c *crioLXC) loadContainer() error { - _, err := os.Stat(clxc.configFilePath()) + _, err := os.Stat(c.configFilePath()) if os.IsNotExist(err) { return errContainerNotExist } @@ -95,7 +95,7 @@ func (c *crioLXC) loadContainer() error { if err != nil { return errors.Wrap(err, "failed to load container") } - err = container.LoadConfigFile(clxc.configFilePath()) + err = container.LoadConfigFile(c.configFilePath()) if err != nil { return errors.Wrap(err, "failed to load config file") } @@ -107,7 +107,7 @@ func (c *crioLXC) loadContainer() error { // It must only be called once during the lifecycle of a container. func (c *crioLXC) createContainer() error { // avoid creating a container - if _, err := os.Stat(clxc.configFilePath()); err == nil { + if _, err := os.Stat(c.configFilePath()); err == nil { return errContainerExist } @@ -145,7 +145,7 @@ func (c *crioLXC) saveConfig() error { if _, err := os.Stat(cfgFile); err == nil { return fmt.Errorf("config file %s already exists", cfgFile) } - err := clxc.Container.SaveConfigFile(tmpFile) + err := c.Container.SaveConfigFile(tmpFile) if err != nil { return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) } @@ -286,7 +286,7 @@ func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { if err != nil { return "", errors.Wrap(err, "failed to create backup dir") } - err = copyDir(clxc.runtimePath(), backupDir) + err = copyDir(c.runtimePath(), backupDir) if err != nil { return backupDir, errors.Wrap(err, "failed to copy lxc runtime directory") } @@ -297,7 +297,7 @@ func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { if err != nil { log.Warn().Err(err).Str("file", syncFifoPath).Msg("failed to remove syncfifo from backup dir") } - err = copyDir(clxc.SpecPath, backupDir) + err = copyDir(c.SpecPath, backupDir) if err != nil { return backupDir, errors.Wrap(err, "failed to copy runtime spec to backup dir") } @@ -366,3 +366,40 @@ func (c *crioLXC) getContainerState() (int, string, error) { } return pid, stateRunning, nil } + +func (c *crioLXC) deleteContainer() error { + if err := c.Container.Destroy(); err != nil { + return errors.Wrap(err, "failed to destroy container") + } + + // "Note that resources associated with the container, + // but not created by this container, MUST NOT be deleted." + // TODO - because we set rootfs.managed=0, Destroy() doesn't + // delete the /var/lib/lxc/$containerID/config file: + + c.tryRemoveCgroups() + + return os.RemoveAll(c.runtimePath()) +} + +func (c *crioLXC) tryRemoveCgroups() { + configItems := []string{"lxc.cgroup.dir", "lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor"} + for _, item := range configItems { + dir := c.getConfigItem(item) + if dir == "" { + continue + } + err := tryRemoveAllCgroupDir(dir) + if err != nil { + log.Warn().Err(err).Str("lxc.config", item).Msg("failed to remove cgroup scope") + continue + } + // try to remove outer directory, in case this is the POD that is deleted + // FIXME crio should delete the kubepods slice + outerSlice := filepath.Dir(dir) + err = tryRemoveAllCgroupDir(outerSlice) + if err != nil { + log.Debug().Err(err).Str("file", outerSlice).Msg("failed to remove cgroup slice") + } + } +} diff --git a/cmd/delete.go b/cmd/delete.go index be17018f..fc7669e0 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -2,11 +2,9 @@ package main import ( "fmt" - "os" "github.com/pkg/errors" "github.com/urfave/cli/v2" - "golang.org/x/sys/unix" ) var deleteCmd = cli.Command{ @@ -38,31 +36,9 @@ func doDelete(ctx *cli.Context) error { if !force { return fmt.Errorf("container is not not stopped (current state %s)", clxc.Container.State()) } - - pid := clxc.Container.InitPid() - if pid > 0 { - log.Info().Int("pid", pid).Int("signal", 9).Msg("kill init") - err := unix.Kill(pid, 9) - if err != nil { - return err - } + if err := clxc.Container.Stop(); err != nil { + return errors.Wrap(err, "failed to stop container") } - // wait for container to be stopped ? - //if ! clxc.Container.Wait(lxc.STOPPED, time.Second*30) { - // return fmt.Errorf("timeout") - // } - } - - if err := clxc.Container.Destroy(); err != nil { - return errors.Wrap(err, "failed to destroy container") } - - //tryRemoveCgroups(&clxc) - - // "Note that resources associated with the container, - // but not created by this container, MUST NOT be deleted." - // TODO - because we set rootfs.managed=0, Destroy() doesn't - // delete the /var/lib/lxc/$containerID/config file: - - return os.RemoveAll(clxc.runtimePath()) + return clxc.deleteContainer() } diff --git a/cmd/kill.go b/cmd/kill.go index afd6c6e3..d7567a5d 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -4,6 +4,8 @@ package main import ( "fmt" + "os" + "path/filepath" "strconv" "golang.org/x/sys/unix" @@ -98,9 +100,12 @@ func doKill(ctx *cli.Context) error { return errors.Wrap(err, "failed to load container") } - pid := clxc.Container.InitPid() - if pid <= 0 { - return errors.New("init process is neither running nor created") + bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") + pidFilePath := filepath.Join(bundlePath, "pidfile") + + pid, err := readPidFile(pidFilePath) + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "failed to load pidfile") } log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") return unix.Kill(pid, signum) From 166ec845062a55674552aa4083a60c812646fe11 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 00:09:41 +0100 Subject: [PATCH 040/373] utils: Add cmd to adjust enabled cgroup controllers recursively. Signed-off-by: Ruben Jenster --- utils/.gitignore | 1 + utils/cgfix | Bin 0 -> 2248913 bytes utils/cgfix.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++ utils/cglist.sh | 7 +++++ 4 files changed, 73 insertions(+) create mode 100644 utils/.gitignore create mode 100755 utils/cgfix create mode 100644 utils/cgfix.go create mode 100644 utils/cglist.sh diff --git a/utils/.gitignore b/utils/.gitignore new file mode 100644 index 00000000..93f86994 --- /dev/null +++ b/utils/.gitignore @@ -0,0 +1 @@ +cgfix diff --git a/utils/cgfix b/utils/cgfix new file mode 100755 index 0000000000000000000000000000000000000000..9ce4abb80cbd33e6723719f66cac6709fcabc0c5 GIT binary patch literal 2248913 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

d?=I1Dbig$} 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

286eJ*|jzXCq; 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μ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%0A#bz{>1Z8+TB8dXc5Ja=b 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 z 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%0DK!b`dHmc+ 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

-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 z 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∨l;@h+_bj%%j7raL0_#d-kIKrX+(W4>75twqjm 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�CucAFKL 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Ðn59Z7s?DrMszP#2s=j2@nktLp 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≻Q3deHhhnA6=MJ?(|8zTfXWO8 zDjDuKho@e}^jL$F94z-bib|GPbcWbuP1*`onailnlk>{O{|ALYdcO-WV|u)vi47_Y z470%%tPlA@mB&q(Knv`*R~kTxg{M2b<0lPymc|S5)rg_*N=i->4ILnk)9L4^_}Xyc zDy#Fz;Y^-z2@yPk<+JcRZJ}+-i zFBz`g1XpE;sUDo@WB={aPk2~DJFWXR)k!sSVyDknk??wgelL4TKX?&dlkCVB4y3~A z*Zled#6qg00cnlz4f)uSIgu_ASGEmylcQay}(pDcGt{cKkk_BHvO z-0^eL*gPN7CZ*fg%oi#DnxEPObz1sZ+LY9;YxV0(Hljh)pP%M;Jh8;JgBF0#)8d-1 zdDY>!e)uM^UN4((NPC&n=$+^ex;RJE&n1QDYY2oIIZFPXrjfW!%zYt^>vQsIupn)I z`kYO2;(2kplzyPPJ$3MWKA+aV)YZc0^Mz_v9{zDUtj`yc%NfJANb3x;0+Jtok}jx% zC3WRA1WGE)uhz6jj2j9m3)Jx3xhQRP0}Wozoi9nVA>fhI9sNp-(Sk0{*WX#2>MHGk zcWs*YgMO#GLDIJp0i5m{yXEl)-F1Afcdik`%T0~W^w%nH8EXSBlYt;8PLeadHR?qW64>f5%MZBBBP~J86G2p^#oREy(y(mRWc~{Tb z>q3Eg)`lSjcC+fMPTT74|tHI2UJD!iNx%KSC( z>YSmvP_47J4re#d6WvVVx_o|DjWZ~0{VI*w_1;F8v$odn3h;HD9*oTQcx&ZKOgEG{ zUSH7N=ne$sv|kShX8Tq?I-xF9>zdfa z6VllGx=`&@kF!zyV!ZA~JlvDDV`$@G)rA_J0X4>kS%gAlyJm#pQX82buiAP{UarGM zfR}w9TI0|oGbA@bQsD5I=9DH^6MHvla&KM8=XHC6UizO_C}X@J*B=bX1yGu#->aRO z8Ma95fxpS)aeLU4Df$8pP8nxI3WhT3=7)Jif=#K{uhg~)mxCH!=Tiqn_IhIo)`glq zu3)IXmanPJA>na02Hdso zfM{ll(w-4jCw-6kheziSM-O|BHK*0G;{Wnr?|o! zaD_bHDSo$Hc&1p3Y@KP==69*9Rb#k&@Pxo6XlCElx{whHxElC55#u7@3DtT%!BCyI zL8XjIIt0^@;1Btb^7R-BDcxY=xy@wWHT*{KA+zk z^oE>#Kj>I3oluM#uUx@=uBQ)*SF7^xgVMxm13|A(R-E6Zab1%*Z#Q&H>~MK%i;YVItn)i3HLAV-*J*5Zr}vmNPQBNs*_p1;t)7N3_)-i-mRy0KkcR4(yUzM4 zj3zco+-V3%g~*-DV1-XuhKZrchz;dwHZ%qq@BMT@?S}D*X;MBnA7ySxmr@s{`mvL; z!tdmy*|=DWfqrjOQ0=Tor)l#Cn%T&)X{v3-++ZjYSb8$&{* zeUot-xxI4t#@JzL;SZ`TLBH-JbWE!2)X8*8znrzTct>)g%O9wh*wW9PSh^`#uYmQ- z5n|QUyJ{u}nmA4jNda0^>-YLnk@e#pZemy&jPci8g_BYD<#Su^Lf0ExTiCBs!8eGn1SI8)?pI?wTH_+u%`r8=f z`}c-@9sAQ5Y@(whT(l{X)sN(uk5>z5F?xmbXZ$HLzvBF)k%Wd7s}qk(2zCiJ?JE zaSB9A{Q6xr&Biz~uE5Pz#CFO3DE+LK`h}9FDQn#EMAWz^9B1|ziW^;1na=oLat3bPJkT<2q931viwvVTew%@hF(3(Ms$LWi1@Pe`P7hLj zP5j_gpDR>BhNsG(YSf)Fqy48EotZLk4bFHb1+>YN68nav3Z2nhg$WXwqu<&g&Z%|& zM&nwbKOpP&Wm@;r_yKQ|zs8lii0M!Gx_zOEc%&i?$p-y-aJMg1>#B1$H3T!wKZ{{x zGPDZ@`3lk8OmcB!KIhB0(CW`us|K0-a-`9UI={;`Q9a^gxKi@r)u-Dd*Q~|~n!er| z2M4dq49_hapObPE)8JX22*&j`)F{0*Cf`1M7DoBTxVnZK19figSjw0Jg&O5JX~4K; z?(U?{J}g?2MT%Mgr-5{c~5ZMdrYUFZmoNMlk%%%D7ktv}8$ z3e~6@b7Fi@N;AX^CBbdHO7*2L{KiBsq*R;MgrMK)3Gm}HG&sh6U5hm1z8q@e8~m~& zkdXc>5VtRF+0=6h{ymW2HPP!0hH4sXLp9D?3|zv{M>caazE0hG(}OSTQJ2=T-r2z2 zxbxg6w(6ctYd2YYD&m<-|Gh+?6=@B9-YG7>X5;%mUUcIg8v9*=pi{Qo4VTW>XFwXP zwB%cL}b-RPX;uBjw%E`9Q%Z}lZOy%lTT z^w+-+=wnM;k=)2hsr96u>rvYPU+L@dM745ksgF{lv$i=@>(!oR(&w6RJVA}8`$6M* zTyoN*d!BgpO_N+cr#ug;FT>26;`6!#5;LFZp+(F_mw%GWIkCY7s~d7*=>HS;rNNgZ z#eJh#p zY&WJ~n_|W9p=8hr-r1%}qLD>)Q*_g{XI6ZQRBIoAqGgfD$`i@^jT?i>%CX9{d+`b? zj}!`G7L7w{q4K^1Mc5)KqZU;+)%Ju3R2F-%uY0%imE%A$W!L~>P=+RGp>`GmgVu44 zda(zT`^=O(Fo3=Bre_D9-W37uTsJn!>p5#q*V}Ex^ssf4KPsYUQtLrC`5^}E>%d9; z5;nvnC#7s|F!F-~_2ccpfuvMd4w#e9atSqy$O+qXNTm7+zn)6^ zFLN?y;sc9oYs=wkS}y<%{n&=ZUYP;Ep5XYU(+RavHHEQVaX@kXdNLeGd^vBW>HEXi zJ1A2Za1XG5Gk53`%;AArDg1icIF?g3kmzaT*OT9erB8WoK^76K3G3I>(C?3mK3t&Y0)}v7=$qDOzb2@5 zeSH0q5A{@(>4p+=)U{59-}6Z8zE9~KkaY%8r-?rs%gMIeqOsM1N#!S-Mas_ z{srGe*2YYO*@uFD#zDr}35!6B9kDUWt*==JU)AA(3ZF^v`5 zMAv@v7~I7!@u1sD$=z;fEEqi(IDc_uas+5uTW~ zR1vQ23dh=G_KV6cPZ)Z$i^fTIGZ9{!*2K4%BK?S3+;FEj(xm`wcf(YNdj;7<1y=4rgOnDSM^z$Mng`&(GxG9D*Y(9m__VZJx}>89w{=D^X*O>JeGB5XXB%D8;jGDFIN zb24OdZCw_;p+%UVxMT`Ay_XPc1@bPqAN9bgU1Hw5EA?7-!%ExSwCfM-UxH8hA76c$ zCoQlvEFyn~|M9hvnd-u;GmqFqhErUW2!#>&fm3*$EDelqaKWP@0Y!YmKobo&f7JZN z4{UmzMN%Z&qI-Gq#Sb`SV@S=H`NhBQ#$oN^g}qn@M&T$0OULi37RCFMsgI=>o%h(o zAzm|V$dpif>!xnaZ*o+Rh~B#t*QSI42+J7>N%gXK19>=zt~vnv%vqs#eS-6DCyQ<( zG(}D5RyaJW;{a9Na5t#1EZsb0R$6&8kQ!1Ww4P;<;!Xau(#`)^RLVb!{#Ytd@nUjO$7Ly7kXc#2WRV~Y#&HPm zeG~Uik|ap*Xj+j4kaWsW-|X_0y&_)3N0@g>osUknl>JN@l7WOU4Ua z;>bjiI84zuVeQV;G2v@|9xHc-`uCF~^YG8dln7bXWLd_ID3dmUga#Wzjh4H^E?}Ze za@Z4yl}Qdu3}wnB+X_aLGRYx~kzAP;-3Twg!vK8kOLu)d8$R??Ynud1aOE>?lb9XG zXWAwaV}eI*ljC*7SlcA@fB~&-dU>0M!XM*BLd}ub(Gt=yNI-UXfKyo&alnAlqJgrg zvfC@u73M)-{ZQ~ZArtiAOZ^KA%-gj$>tIqd9p|oIdAW!T-mX`CNuesBC-iusdo*=@ z$#D;A$}>J7#{vmSnWBKuZPYWn0j zyLZ$mYdl?zDS>KSas(`75*k1ZQ#$7=-4E5Q%|MLN1$2iBlN6S^>&-gswv-a58tU#O z;o@fyJb`M;r@{c)d_C{rk9)gLp^bMQ!p8p@E5kbwQoz@*hdsuo!Hv!teds@!R}`#xM_Q z1hsUblbR!`j4~F~Q@YrwiXljP(GpyH4CW+EsYM%rjy~Ap#gysXu}Kv#G!uH72R5Jw>Ws>G)j-OKTl}?m>=)j;lq3 zf5*1##!yTdHAHPjG=m>ZI4`Ju9^-poMlY;7OeD~3!Uj>TGa8#h15*79#UWIg2-1^AF};jeax&x*=|XcBRV5t~<>VrDdYmho$x!Q(+e8)u#^m-^bQaJQ^2V`~ z<77Y49Cc3YMZD%ZHhyI-QmhgmcB7zaIT zejmKUaj&KH2<`3%2lp(AO(rNq!B)+B+7H9F2!={b5f$(rX?-~SMQjaW2h)ubva@Z) zZ{(E{4OjAt1Bn8V1*0Fzn%#?@(_dt-qXLfCQC7Jim5YuT;*CV+njmCT_>e^;yGSLd z<;)J*1uP-kqDfH{>b%+yHN0#+MJjJ%bRv>Yi2+VLu8k*Z-C26>>RR;@Osjl7bI{>- zTI+m0l}M~bW1jhF@T(kL%b*_n{MBpToLXK*%^JEc2D4-Ts@BX}TzvVD*mf{|o!s3s zvDTCASud6E6%B_l_(~^pUl8Wv?j7~zvf8-H)|Oo+VwzDbnklvKATmEVn3LhZPi{s0 zP~KmqD6^7q9QV5zo}k>^_%(RNDKJjDEylRrY4}gjHN33sV+9QvAlJi z38$YnevL54FtcYp^rG0aQS>2DhRlJS$?${T1kH^?Q?Gvdp*_07l|Mnqb+Nc+VMOgT z^jgp!P4(27ep~pMsza}Mcsw40D4w81MmIex%b|FBGarz6W3Bgsgj7fTC{;@_AT5n) zuycA7ODHxV0n#fRL5PuK!>=1o*oOBKdM{5vI|Rw=%^CrHIQZ)gcAy)z>C{Ugp=vqR zvL);an`XjJ9N*^YQve}PGb?V2mit6YNVdKEd)*kuWv8Sfv-*f`3JwqbhXX~U%{f%? za8E{GtWC%m+jB&!Ix7Y=OjV7ut}Lo5eIDTQt5lByM#~u)g!jL4 z0kS5)c#aI4g7c`}HG`^{Z|1={V4Bp7J7&$OjJkLKz_K7W<0T7Zt3xfnGq2UwX<7Qv zyl6_v_UH^*#|}I+2UK;hSz@bju>J5Mq)P30!xByhwO1a(Vq%D2UV@c+YWBJ%Ea@8F zwFK*?VCVCzmf+DYwf8+s)V3ABY59dExZw;D-#GwrO5e90g7CzZl<>_5P(C!hZ3(3d ztXCYs%#e=AZ(72gh~O8Os06&;zXXSqvoSL6*XC#nm3ZD9NgDUHIU@HzI^`wiXMor= zykJ%iCK~|(>EXnqvk4$ks4txr^-;+mo&!qBU%SLu$sag`h?2i?32R+_{Sp>kefJWS zfzo+DAs%nFuD)|w^k|m{9R1RgCG9`&USd(3zk2{;ZNB#ql(hLR2T<1Lw=bcj&F?sX zDQ&)I2`g>>;1U&We%}&Q+WhNtG->mlb0lf=*EQnGW1Jk*y^M~>ATXt+5hq`uulpjz zx2iP=wOuLvjldB4M0P_qTZF{4C$bj|~%x74~N5)p$^F70L|_W;q6 z6-$NiTao;>g*^2P8gL7rz1kWBOD?{9248111M@Mq*|EN)HSI1=Bamy!gCltfxJ;Y**?*fP!J!QWn zk!tOp`V%Dd;$)|CsP`^Jw&25z$kBs?L|G)CmUyl-qiN}(2R`E1nqe0|PaqD4D=_CT z5hM~3>}?fAB)4ISE+P_FMF2%a;u;8uh)A5E-d*|Fqo4z)9)>+2GnBS&Mjt%%vic6CbwZa04y7VXE@lA1Bg6pbRoQ_VPUTSl+2kae`YL$to(#FjZMy9|Knp z0VsZK_VLiAKCDHBIiHNuFOXY@o1Hz0Fdvn(qb-l)mA$MxD1_$_EJc|K0CsfO3|AM2 z>d8tvSXY)S9?SdgQ@;fuW{P?93^4Jb&r4>&IzDXuz0<(hw=6I=9QQ8(R}Uq} z2E1Vo?rh6B&tElzY#Z*@-!!AkE4+JV$Y#Yikgr<;!RPndIS?a(Uo!_R9)Ob&erFEF z@VnQ~fhqP<+Z*fPdkjOnq_fLWOn%_6IOa>4cLs*}o+Z%P1mya;nfQY{%7g~?z76Zd z65s|YTS6V+_J}=aauAWSA=Z_x8#u)0?K26rabCQ12DotugMIf5=#IlL+`FVp+>$cm z)}hE$Iixe7;mbwa9S;-P`LqbGL*O9ya2^dmpm`@#WuXZcfr z4=q7&RNY@bfTzL_FF~Y-59*K)8t%kstlu#&!y@?5eRt~x#JbYwhV%3Dg2`~cVu1`X zSO5E$wTkKd`FS~II^Vj$l!bib92|lN|CMvPSk6~#Xl%n-TU|dseE$Qw`(s<-LSAz` zGUr&Ef#c(X;r#Ud*?KjC!Peod_PGO?I;T8%07jbiqpD}i|M@uw1~jGE|LFbM;Eh1n zDQoDb4xq7NA3K00m*6K4fUPTIg4K^4fL&cTj_;N}a|qwHe5(J%0kp&S{MlfB`~a>* z_Rs-%I8h_|*#iu@OuvwEq-+6*KN9=0qeu{%IshJ@Y|;)<{d-+XiQOUiKapqOi{Paj~(R@z)yco^RID9 z3aaewP0?T(+7tPEig{I3p*a%409s9qa%3P{MZ{0$rSUugzokNEz}yp2a;p;UY)Mo( zGJ@)xfv8VSDq&VN@(Q9>Nj7R$qYurOwa%19TN=DJ1n=LghS5hri7FdxQyyV60#=EV zFs0jUi1u5$xNF;D<$CBJ_`f;BdQ(#l24H`>z_4or@-2l_rl^`@B8!_MP+fU|9xmm2 zbC!yHQP<=`d&MF=HK3L2PFJ-jve9q~sQ>)RqU_OBJ|vDt@QT|ueTV-r9jR*|tg z#4H7Di^mi6GincPnlneN_>!O4G-p~I9f?^&=}dEN^|rAq#8QC#xt#3FAjZ#XavP`BHL4-bbyR^kHVwXjGj0%X zM9AN%IyMyIj~^75rP$Rcl1WRgyx`k(n+C{rB?%TJ^u7q0}*PuA0^rZBSB4MCNc+gr!0}ucmcK#)R@}$>J1Npvr=4T6b)MiT#JH0oa9tRYFco>(bb$ z5HHixSB}OofBrVB1UH?iL>wjH_F+tZM0Wz;0Rg94l1=NnN^Og zb-oMpKrRtL3?@Vp@q)&7qIhlW1?z~XP*xInn zd_psyupJdQpm803aqPm()>R`_PK^+J{N~41HMCL1;z!7xs`2=G7ZEjWwyn`0mBeS& zh+mG`hK8SrzpZ|gsQLcrD|0wmp)V_>FWPnZ4Y{o{z1fsULHAUAFUW2P%qj+#$t=3R z(RE`Qt2&?rL*C)v)o>D>#FQD|^Fl2i zR^$6k8(R3Ay7*8up`(AEQTtTwBZ`ho9_o!mNfWJdW2pMun%TKc(e8W0o&6JyoeV49 z@yP|Q8Oz2LVYdB+V#ZOF`y-+ExO(e@6hE(ccW!K|@E8wLSDWM$_)I~Q%RO^ak4@NO zNN#&?*Tt$IPCfpgJx)yzP@8^3RM|!G<7lvoE7;q0dDK)ym0cL92Z`7XqXKCb=jZ@Y z3^+cAK6XTuIfeI&O+!T4IDy!P_RFdOq9aC86QTu1u>;<&NoVovazyZUO$q_39C|=? z{QFt8UGHk*mCYr1cRdkB>%Co{9c^fWsA_z)jvtc&1a&yBo4_sS1fshj8Ce=Z-FvD+ z_7~o+2g8H-!)ZYPwJ$;ivabZy4}mH+9@N3MRIltSiRwn8%3jsmHD_}}N3vFo{hElf zZ2+_HPZL#6HGz7DsIsWsqfN9zHejIE{%J&&6~piS zgtH`_+nGHgL=N~ zeHh^_0ZQZd$VHn{I4Pyak66wnq_lqT5mg<9sx%xxd1R_-Zw-5Pl{!M?y@?{vHF87e zCNx+nI||q~y;D|}21rqDV=^E$6VQaCbXlWJRsf2inaVx|dUVsPIlTAywlK9xwk%8y z7otxR0|QB=&sWRt1N63Noo@`k4HxeLu(cU1R@`t^BS#xxMN@DZXxX@f?z1wo!3DN9 zL&ukEvO5LfOD*agI22T$KJK*}SWZqa(>Py$d3qMSrPdUC~38Rb<1vN?{GDK8X&eiH%ZBm_X|QmHC+ zmI6R-2{h}Gd}}fycrnCCsj~n|_uRHC{G1|S`c+m1=0wjPIN%Vv`hGE-qW=iup+p+;;0pMh(^J+8IU1^XRx|Bh#);~ zB5`~@ui5W?3L8=v6ex#Z4A*zcVFn=NA)(roTMWqB3?nZ!%9jSj?|n>!@XfphYcs^4 zv2W#wm)ex~jB1lI%J~Zf8J1!blA}5K}@|HIr*P*q636H1XM?Q278kt@YD$#AT&on<);GZ zk!Z)q1}S$cz)&)R%CXL15~%W+07Cws)SB-vM!Zf{DqkbYVNGU{DlapTvgo4OSNBDX z;Nk{mK)FAGgpE7$I>#_n<^LB3%z+APAl0FK{lY?D#Yl5V-4qCm{-%&}mw|yC41=V+ zQLaG1BN{-ztsF@JHpeZSs=M-Y*@#5r;pzJGa|AcYt}U9FLFWZIJfkzX?i}*FqT^3Wz2^YJ(KITS2Xi-k0FF9)|E!Q1 zaPOP;>p#7K!&{cb@H07sbzShp{Op1bUmIq?&*cd1?+lbBW<+>z&VaO48vgkl=I`8Z zTq^&*oB_FP!|Qu&0K?Yh{W;6o(e!&=#RulN8;YoPzmQ{XjVP>bL_e6LusHEt`inW# zjYEPyltV@BX#&JK_e(iEj3){Dg6wxR@YhMzQiDQDrU$jq30IcM=^10}22-SRs* zS_juDH{dHdh;qG_((fL^dDSB+ef1Cn*(Fxkt|jm_NwDAzaX5 zVg17#p+iDYt3S$-Eq!w_I3oWzhc?M4`X@O6W!spI%JKH?oB{JLXZX{cVRKe)hrY9b zl-K6F3lNG{!TC%5{N7=_H>HUWWB+Wy(z=vn?9Ue<_VZ>)i`-x24D_kmDFx~NWsYKw z^Q!t+IZ{;BgfJV7&0ptGA3mg$;J?Y?W3!LL{rw!V4krqX237mF2hn)!{ks_&WI!7# zDy@?8U{@G%w0oDn9i-ClXr_Lnc=U^K+_%_uUkuu=sUTf2;FgfDSMJC!3dujn(4BLL zVxg$z&&{FWRpVmMn_*!dFsNVB?>*9O(P@=Y{U&|yStl9OkKyUs3|nBv^viwRJK8pu z(og+yeH1*9Tui^brz#8bK{EQ{SwG0x$kL&?)ZmX%g5wa)xT`t|j_Ab2{#iLyhmsfoPbppA9v>J7=Ja?{Hi5o*6aBx z7aSA30ei22x8L#;=PumbUAjnZk^qN5_s_g=@e(2P683zcOTK|Kg&S{u`b{@owCB%V3JRnm6&4)9G^v~UjH5XJ9QqOMG0zyr z^S6X%Xh(d;(cE(W*4v)`oO3}|Dx4wXYR_G|?UwVm(vSTUxvwXl=9cr%;Nl{m0NHMH z@!Wr*Qiq}Qgw1QT-Lq~;1?NrL-2RMb-V|D^?scgp<&OzA7b=OnyYzwx$P25W6m(%c=6m#2Y-7gyHu^Z(y?`c)u!X` z*^1{M0Md%Zqm684fWR__l}i+y=qbOhgph&0%F?}v@&nTuUnSrO2qmvhUi=?QN&$?* z&{Ga(i9E7(bHyIv1DsWLuuDxbYoqR0Q%qK}J?Wk`MM}o5JJl3&KdQUb6qDpD)%|G- z^5}>2!mKl;^I_!^{iaT0E1H~55=%wcrtmQ-kAzYYva`Ku;-Ef3iL@#3F}xv(TV@QE zQ)#CpoQjYbCnP~sMBX83a%lJu=Re~*)8qakY&2vRQ8Db^(l;w5j4ENNeg7h_6raFt z{SRhftGzu|Ohl(2p05d2xs%ihB*8lCd)~58c}kU(w=94%?GLpp zO7gMC9(zoN9BKRyCj}jfsbbX@>jG*_>@RZ=RBOZARGELEI;P6>0~M)YV=j7`fIzZY zBU3Oyrj9=?a}daeQpAPXDYK9eyoTwDAtWD>SqO~c^s!NvX$Ep`)nu9hBQaAMEx`6l z0t6sNPz$kDW2ME|&di(^W}BH}EzovmZna3;X@w8X9XZZdpk<2o(MvVxEpd5@5USb+AP-`*tQr;n?&pW+ls{DICI(2~;t}>zqug5x+qMF*o-6M&d0feiT7)_=grUPUL41ETp!7Cz0WsyvLS(8x9>xW$ais!Q3iku_t^fuks(*lcEimVJhF5J&AYp>JV)=#Yy~3h)z3a z$Dw`-2}FP7$8~XkF0yk?Ifh1w=v?ZjNY14miQru8xa%S~*EYQg8%7ZvzSb4Qp#dbXallii`F7nA_Sv@uWhRl@J>8HjYk%_Xp z_9?MOnJ6W_eums6Y`yeBN+QY92lt7LRq3BhrDUK=AGAi-Gq^6qgQ>AYEJpBSse z-n4;LX?<7pu3}ypjH9tDdGJN5xParcx>Eer^-qq%xkFmII(_>3D4shN`OLM~L;*cl zk*~Yqnke<>Df0E#;E#lGmnP#E1Nr%i{M0k2V@qD3$fr>Uv;UN)Qwu{iFVuAPt1nXY zGpe2!Yr5ipiK1Vt_+P5&ivMMbex2ffxzKIQQzTQ&mPN~ENoLte8SSN$$Mw2OfX>b8f%!>9^hX@6Vlo zmOFprxl>nPb?@b;ox-2}_79%Q@aDpex1PHCs?RX~*!N~Qu%Fza=&6(Tae3L>0X{E) z-}rC3;PeycE?ziw^;MU-+Fz|S>Mz}N%lT7RU-fK8VNIk_{?bhs{_CYvS6}s0PukM& zE?{g>ufFQ?LHOLoizZ~Cx%#RP|MSqc=lqKPb#R2l9amrVnJaRHyaiWZ_2`v2E?h+S zPu;vbb?VfqQ~$kv+^HWp_5T6@0RR6j5f{!{Oi4lj00000379N+0py)~oGnFl@2h6c zqtAedi4TrZGrmz&e80s}6j1~8-ZP^!N6?Z@>qj0mE3$=tOR%~^H(-*^qwh8e9Ha$SLNszQfYMV8xI#NxV)seJG zRjZJdeicnyPvv-(41A+P@A?;ut>hW+`q!#V_K{-m`noAnJAcbUe^p@z$dqd3i3&SF zW@XUl6^^^X`HL4TLW3G6Mngr|yXy`s`=N*FdTf@8M;ZkjbA$ck&7wBu_DV;YchgFV z1jHRs+gHdbPgdw%ANIXU8gql^M7*di=A|l*H!Jk6g#AJivjBgQ(!47rFj8CcTO|=g zy(=*cX=85i{D>E|#k^BuZcu1c0$lS{8Hu_M#-1(6c?vr~HYk4^B7#@*n;Y|jV?0yMH`%mJ-T8JGhw0E%@% zxjI4@FmTKb9;l>9Z4A`FbN&U#v8v zJ3{iGNaC9nYL-j%OeJq|{o#a+INHP1p_iXzqvhKY^Gk)^mCu)ruTtn;2}?FQI0hoe zBP$gaT`1(26mAaF_^Kd^!OZT76NY^Et72Nl&nr~2WJaRapnMN`kN1k&5U6uTC$Frl z&NGEvP^bbXN~@=UiT_!=eOT^)q38z`%3VaSRWj}(zK{G;xWQai3|>?fq#Ud(=#_v- zjwK*#o&Od7)<7yL=HXX1_xpa)ONz> zb>UkILv@=Tt!m?aw{TTmxgZ8PRSTj!be(EJ{AWr})q<4kbp-_R+o-xEgl>$4uiB=8 zG=?=G$4l7D6)HDGzpG?yBaZEb8;C8cz?nTSH_3e@F|3EmoBM$kP~&`6ooQ^=;xG-5yXG4^umR)JWN_A7iNms^VRWUZ;@TpDsg=R=71hfrbJhfm{?W)c$aVlz||KlH^E~2N`LbFyUsa zVx}s>bPltSy{`)uVsLnUHHs9qB|~_1WJzNZv}WMmEAI7s=?s;}nF_ZC|Av<#B(TU| zgbOp_3Mo{}ZMtGS?cloA^=$awj%r7NQaRR9&pxPpu;`K|SmiDjxZ<_0DF?KPGgt9VF$oO1V2iSw?6McSAf%;>I2co{J-(G{%nZVvWjNe)9D z{P{}rZVr}bpfNW%8ved9AKB+241j=)Ean_=^sE~s<#&Q~dp8S9=-oVQmF~i^*lIi> zqU#KyKdsQa-Z#baL}WZxFW+R0&mYU~|R%Uq_UsPx~7Qu9asd%#E-}1q=V5~67ST_0K zm4$iYXqN%OWvQ2^LyAOS3Itk%76^!yf7GnOvgL=Y%>VImg*e;G=OC74ZOpy2To%T8 z_=}Y`+@wGRd%}&l0>Zm(;b5$;V*T0XCBiP5G2CrNBu%ffbph2(Wxt>rHy+leiCmu& z&s`+4U!361z_NvI2qwZlG4IOb1lg(3yYfu2cTMhIUL=Cs$HS&rWiV3P-x!PD;VTv* z$%sBiyi%II>tjSi-?=08L2D>qmPWBEJXTyTGteE<5Dm4n3Zc47U4N%Q?^9^apEK35 ziyE?)9KNSgmkp6NB7@LcoI;&BShdf)8Cc50tb0?BUfEyWPDU7QJqNLzyUBQu`SP)G-%kD`$uBud%Rz!XRiW_|I{Ac^E@Np#ePeWFP1JR4+w9o3ZQB#uPA2xmwrx*rb7E&= zJDE87`guS7>2bvURs@iAoU8hcMJLw?(I0~pNE!!=$w;;JtFd^^^zky? zoqs6F@I++<8JgU(?sTYm04Q8!O^tRMgdYL`$&^N zENI@62*Zjf)f9B#C@9r1RLIqAi2eq@N+nTbZv(`o+o-^Um57K**Z&~Hv_K8L;DjTC z#;(e6iNG)H0^kuDu4!76b;_Y^mW)VH^8N6Rl0vjcZjkC3Le|C{Dkp?jibv1K5e3#2 z*Za+$zZu%^hn~X+IK2e3h+IRk2gZL(dk#XQ-2NV`xQ;wKy*<@X+3c{JK2k$9o$P*G>V)hTKiGc8czc23K+_HUsCC$` zT5j_ndS2RNMdV=${h8)2o50|0n&#GhZ}jh#JemZe`j2vJ;h?Pn46M%B?^$KADz>%DzEs{ zI)!TZy7_eVOE@8PW6ZUOq5dMJnW$93`i`*D%i3hjN^ZbFe`qeKs^L@~@7Zu%j$SEq ztb%&SwA`vry-?4^8n-`aliW&|c|h9#x0695cgDdFGos^!JuY zKY~kJP!QF43ao`^K)zH1#=D5OY0NE;AYUZEX3z-^414rK9%CX`Gx z!SZ(!|CvlUc?rNP#erk=nuz}6aM%omqU4(Z6`N3_-kItDp}D32AFl(v;%qs}KRwcR ziH9o=0R!V$a$|&N9tFp;xdmU|=_1PB9vo}^$T+`4TQuI)`I{Z`_Xh_-Jy0%t|FVf)w& z{V#f62YwN&q6MSf1ke zbQ~9_Ec#mq3nfIYB=W?dqo(VMHJVSA?LD9%qDvwe)q9~!u~?D-=?B69$N{Du*^I|LB#yD1P0<#?#dbCqZzGshG%A;J^(0c=Fkq_C2M-|waOhc%D zpdbaYYe*$J;DJAk6fsd*?{S;Lr%RK%o6cnJPv^3eFe$LI_GEDhl>5;8Jb3GqNIP!N zQ_7Z@a3==zQoorL)#E&-0d2#dzkvi~H^im$rznBK+7|4LB;{}qhCpg!g1>w#LOwv<39}@UD+*l%6lL~MspYcy_@5%=MQ%)@F=p(d{(fOc zw9#>-gvGGe644vkwekwb#ezK*19&K+@!7+j;ALad4-JuD+axR()Pe58D|_p}4`rO>xjH@g6hVPGMITp` zYEmZYndj1zovdj@t_R|hadJ$&3-NL99NKX;3?HpQ)^b?abvZy{alTjA zJ&J-w51k3q>a9RdFuF*-=TW-udHA!0L{XcdRRH0+#UoD!4CvXucSX>IN8zbSYhr6y zLuQa*5IDWqM(!c2EJewu^z|lvept%`$9JE&iS$9^vF5#jG@t4RJVtm+^YFnzf@EGn zo9%ZwBm3p<7p{8<;(Pm|HOJ-dY^E{r(uleXc);yCE$AEA<`?bDLFru2Q*|2FI1wH}(YM2;%9QDH#zSHCbfng#_|2aTHJ<)!lCE9kmlxfSL9^>gKkoKP z{W4iZ`F}x}0&__+r))yoAj8CFAWc5K6X=>7{wfVyVM;Mg$ZXd~9HBGKMu^W{%vzJ! znS70-!r#;uK-Xwo@fq|p$iX2{Pyo#hImqh_2p5|P$@#j41Yl%i_imWq4zbqvX}8G6=3gKiZCRETH#pvAIKp3>q1LM0 zWi3V{-*U#qcWF)}=6%s)viDiy?dSsavv%FNFY&3pJdu@fMFi#C{G_f&oi{~$ZuOS|LQX~SA+j5|9dCfX$U+%VzsxPBZ`<>9SCDRNfGX=+$H$r zFXT8L`=Om`nvj2(s-`1OB7qwFgAlmoHRJ4d&ZFd0eANv=^E2d@7^_bvU^BO3OEvbtMMhU(S5?Y$w5r46Z+hl|6@fX7n*lx-!c_w)KCH*x(PK#>wY;MSjJvWG_0B}a*+a{j|3sRJAW>&FcfY~v+ z_LR*M3*3IlHNz^H zuu^%j9jhVjc$WHajWMF$gr43uC=hPwL+m{E3f_aMiANn^Cx9m6mj~?9mH4ZXpaa#H ze}}Q2zn}X{F<8>iS~+0=x9a9!1zJ8NiQVJl2=F;O%sCk&=QACR2Q(-SWq`kIaC;c3 zAOWipCcr)|77?TNZKbn?BLg)qjxs16SK>D_KUh|ZjtJg@2lW{bTroRZUOl`F9u4tQ zYIsY4I$9lJaJWOHA!chX{GAeYyF*U(C3O29G74HNq%yD6M5f8}FYO$j4?0Y;^s^#Q z3VK{T&k%f%FKwOIFwq;2{v^H&8I{x=NbBg0F2V*J)@vxC)cQX9ZhCno%hyhbTz>HT-dTNQ!z^=kk{LfW;*QCh2sX831 zW|uYsDpjJ!7m6bME|?8!5C49f7k={7aSyPB>DO^wUo2nr3Ibxp?o z>uKXuQi?e=*h&P@EUxR$E&7eR8lTL({H(h5mY_sFj;vnjtV<1QqdB*(3R|RkcmjVx z%UqWJZs4Nd%caYWgtb;Fuc*!P>_Fsse~9--awSRkmFH#hl9>5XfIN z$e6DJzt2Hm?(ePT;xr0=R*zJ zM}857ULJHmMlDFktJphKw*k3^R?zMb(nq6@M8yb~!T>&2ivY9gJ@`)bF>VEbYFAt> zxG2+m&UN_RvMTE@D56UHHC~d(r<|hQfr<7txFPMK&|)#emoc_uj8Q(rjVWG|UtT$n z^8*cfHOa5T_gsyX@il1|fy|`8HJ(WW2#HMN8ku#c4&OCr+wnF-jd_ZfyS~tu#qllc z@9jN!2Ub4ud8UZ;ETu7HCo9r2Zp> zp(Wm{mYj+cp?yCWHK1I9gpR%LnWp5?NcNRf;=jK$Bm#LrBEcwiA`r)!)UNCGaVc0| zPu%fe)wZ)ZXH&ilOY}wzi$l$iDE#P#b>wg2+GhsyaFbflW^U z2X^r$jtk0^B^2ca8?*Y=qmXxVL+H-TKpBErHCFJM9g@aztXN;5lkGxM?ge;Ipj}IL z*=*GXtO4bXcMqKr)i!ixhfX~j3V7-uPAv4e5!{2=e+Y;;qa($TZ(te7fRd8^)ItdZ zuMV4Jk1t#RF`@Ygd}0x1dg2n)CTO{}wYkJ!6OPTAX*97zzIFbj6*GsKDCx6kj|dUde)fsPdudC%{G$)p9)V`HOqd{^{abTTEf^jvp6} zlB64BB#<=mT8-!tRvpc4&DMB*U)B5?j9Fb?&vvwA+G^Xd*>DF;BG^AFWSkoyx0yV# zf?Jog5m;!Y!~vmS5TR>vFVTLQyCES!O+=r2L(+nT;W95=DXDqxP1?efeLtMj|^okyn21f^@@`{)`GyO`0x!wSEbjYx8nZu;b06qMuYw zXF8TJYM8jF$R?WX3bnHg^R=92l7~{3QdV(({-2c^I4;m)FLg^#&9r|Sm?{Sv+A_p{ zD0=ECCi8-7#l-t)rTe?XsawSC=?v>YvpqpvXjHJiCzzc@UoBda@lsIKSEsA3d`4hfxP*tsk=xvBEzhlv1KJzb%v5= zN7e(U5?SlBG~`?vf`5PB6GtsFc9vxMPF;gt?5VD=s+{by^(~mTu#pToR4b6b5Kj

r85yrF2jQ^{r?8uH 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

S)}|WU`J~ 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©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�$9g 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 V_L+QLOJF=}G=PB`vit2%{}0y5K%D>p literal 0 HcmV?d00001 diff --git a/utils/cgfix.go b/utils/cgfix.go new file mode 100644 index 00000000..a503ac36 --- /dev/null +++ b/utils/cgfix.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" +) + +func main() { + + root := "/sys/fs/cgroup/kubepods.slice" + + cgControllers, err := loadControllers(root) + if err != nil { + panic(err) + } + + subtreeControl := fmtControllers(cgControllers...) + print(subtreeControl) + + err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() && strings.HasSuffix(path, ".scope") { + return filepath.SkipDir + } + if !info.IsDir() && info.Name() == "cgroup.subtree_control" { + println(path) + if err := ioutil.WriteFile(path, []byte(subtreeControl), 0); err != nil { + return err + } + } + return nil + }) + + if err != nil { + panic(err) + } + +} + +func fmtControllers(controllers ...string) string { + var b strings.Builder + for i, c := range controllers { + if i > 0 { + b.WriteByte(' ') + } + b.WriteByte('+') + b.WriteString(c) + } + b.WriteString("\n") + return b.String() +} + +func loadControllers(cgroupPath string) ([]string, error) { + // #nosec + data, err := ioutil.ReadFile(filepath.Join(cgroupPath, "cgroup.controllers")) + if err != nil { + return nil, fmt.Errorf("failed to read cgroup.controllers: %s", err) + } + return strings.Split(strings.TrimSpace(string(data)), " "), nil +} diff --git a/utils/cglist.sh b/utils/cglist.sh new file mode 100644 index 00000000..071c3caf --- /dev/null +++ b/utils/cglist.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +cd /sys/fs/cgroup/kubepods.slice + +for cg in $(find . -name cgroup.controllers); do + echo "$(dirname $cg): $(cat $cg)" +done From 8696558c7bf39806faf919edd7208634e325fe90 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 12:01:56 +0100 Subject: [PATCH 041/373] Fix regression in runtime dir creation. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 77e8dbce..4b4dcb61 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -111,7 +111,7 @@ func (c *crioLXC) createContainer() error { return errContainerExist } - if err := os.Mkdir(c.runtimePath(), 0700); err != nil { + if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } From 714b5b0479c23aefdc8b17f018c1e318556b6478 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 12:05:36 +0100 Subject: [PATCH 042/373] Fix documentation and default value of --root flag. Signed-off-by: Ruben Jenster --- cmd/main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 5d8490b7..699ba104 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -71,9 +71,8 @@ func main() { }, &cli.StringFlag{ Name: "root", - Aliases: []string{"lxc-path"}, // 'root' is used by crio/conmon - Usage: "set the root path where container resources are created (logs, init and hook scripts). Must have access permissions", - Value: "/var/lib/lxc", + Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended, exec permissions are required", + Value: "/run/crio-lxc", Destination: &clxc.RuntimeRoot, }, &cli.BoolFlag{ From 57467f8a620105f75f3011bce4aa5398b49f49af Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 12:10:49 +0100 Subject: [PATCH 043/373] kill: Improve container termination - use Container.Stop. Signed-off-by: Ruben Jenster --- cmd/kill.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/cmd/kill.go b/cmd/kill.go index d7567a5d..e799f4b0 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "golang.org/x/sys/unix" @@ -21,7 +22,7 @@ var killCmd = cli.Command{ ArgsUsage: `[containerID] [signal] is the ID of the container to send a signal to -[signal] name (without SIG) or signal num ? +[signal] signal name or numerical value (e.g [9|kill|KILL|sigkill|SIGKILL]) `, } @@ -78,13 +79,14 @@ func getSignal(ctx *cli.Context) (unix.Signal, error) { return signum, nil } } - return sigzero, fmt.Errorf("signal %s does not exist", sig) + return sigzero, fmt.Errorf("signal %s is not supported", sig) } - // handle string signal value - signum, exists := signalMap[sig] + // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' + s := strings.TrimPrefix("SIG", strings.ToUpper(sig)) + signum, exists := signalMap[s] if !exists { - return unix.Signal(0), fmt.Errorf("signal %s does not exist", sig) + return unix.Signal(0), fmt.Errorf("signal %s not supported", sig) } return signum, nil } @@ -108,5 +110,22 @@ func doKill(ctx *cli.Context) error { return errors.Wrapf(err, "failed to load pidfile") } log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - return unix.Kill(pid, signum) + + if err := clxc.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { + return err + } + if err := clxc.Container.Stop(); err != nil { + return err + } + + // send signal to the monitor process if it still exist + if err := unix.Kill(pid, 0); err == nil { + err := unix.Kill(pid, signum) + // container process has already died + if signum == unix.SIGKILL || signum == unix.SIGTERM { + return nil + } + return err + } + return nil } From dac72c6b49097fa33f39e023078bb9e2663b0b10 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 13:55:11 +0100 Subject: [PATCH 044/373] start: Add access check for external cmds. Signed-off-by: Ruben Jenster --- cmd/create.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmd/create.go b/cmd/create.go index 7b5aa04f..85a7573b 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -55,6 +55,15 @@ var createCmd = cli.Command{ }, } +func checkAccess(externalCmds ...string) error { + for _, cmd := range externalCmds { + if err := unix.Access(cmd, unix.X_OK); err != nil { + return errors.Wrapf(err, "failed to access cmd %s", cmd) + } + } + return nil +} + func doCreate(ctx *cli.Context) error { err := doCreateInternal() if clxc.Backup || (err != nil && clxc.BackupOnError) { @@ -69,12 +78,17 @@ func doCreate(ctx *cli.Context) error { } func doCreateInternal() error { + err := checkAccess(clxc.StartCommand, clxc.HookCommand, clxc.InitCommand) + if err != nil { + return err + } + // minimal lxc version is 3.1 https://discuss.linuxcontainers.org/t/lxc-3-1-has-been-released/3527 if !lxc.VersionAtLeast(3, 1, 0) { return fmt.Errorf("LXC runtime version > 3.1.0 required, but was %s", lxc.Version()) } - err := clxc.loadContainer() + err = clxc.loadContainer() if err == nil { return fmt.Errorf("container already exists") } From f9e4e2ae2963cedf5616534417ded3e2567b5863 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 13:56:23 +0100 Subject: [PATCH 045/373] main: Fix usage text. Exec permissions are not required for runtime root. Signed-off-by: Ruben Jenster --- cmd/main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 699ba104..6a82899d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -70,8 +70,9 @@ func main() { Destination: &clxc.Backup, }, &cli.StringFlag{ - Name: "root", - Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended, exec permissions are required", + Name: "root", + Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended.", + // exec permissions are not required because init is bind mounted into the root Value: "/run/crio-lxc", Destination: &clxc.RuntimeRoot, }, From 39df599077518a6954b0da91e67f187e3871e39b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 13:57:13 +0100 Subject: [PATCH 046/373] Switch back to race-free pid file creation. Signed-off-by: Ruben Jenster --- cmd/utils.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cmd/utils.go b/cmd/utils.go index 02f0dcc0..82e9d675 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -9,16 +9,8 @@ import ( "strings" ) -func createPidFile(path string, pid int) error { - return createPidFileSimple(path, pid) -} - -func createPidFileSimple(path string, pid int) error { - return ioutil.WriteFile(path, []byte(strconv.Itoa(pid)), 0640) -} - // createPidFile atomically creates a pid file for the given pid at the given path -func createPidFileComplex(path string, pid int) error { +func createPidFile(path string, pid int) error { tmpDir := filepath.Dir(path) tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) From 418ebedf0912a77bf1d510f997c634f0383e38ce Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 13:59:41 +0100 Subject: [PATCH 047/373] cgroup: Preparation to debug cgroup delete failures. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 47 ++++++++++++++++++++++++++++++++++++++++++++--- cmd/clxc.go | 9 ++++----- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index f2925bc4..fd2da09c 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -2,8 +2,10 @@ package main import ( "fmt" + "io/ioutil" "os" "path/filepath" + "strconv" "strings" "github.com/opencontainers/runtime-spec/specs-go" @@ -247,8 +249,47 @@ func parseSystemdCgroupPath(s string) (cg cgroupPath) { return cg } -func tryRemoveAllCgroupDir(cgroupPath string) error { - dirName := filepath.Join("/sys/fs/cgroup", cgroupPath) +type cgroupInfo struct { + Name string + Procs []int + // controllers +} + +func (cg *cgroupInfo) loadProcs() error { + cgroupProcsPath := filepath.Join("/sys/fs/cgroup", cg.Name, "cgroup.procs") + // #nosec + procsData, err := ioutil.ReadFile(cgroupProcsPath) + if err != nil { + return errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) + } + // cgroup.procs contains one PID per line and is newline separated. + // A trailing newline is always present. + s := strings.TrimSpace(string(procsData)) + if s == "" { + return nil + } + pidStrings := strings.Split(s, "\n") + cg.Procs = make([]int, 0, len(pidStrings)) + for _, s := range pidStrings { + pid, err := strconv.Atoi(s) + if err != nil { + return errors.Wrapf(err, "failed to convert PID %q to number", s) + } + cg.Procs = append(cg.Procs, pid) + } + return nil +} + +func loadCgroup(cgName string) (*cgroupInfo, error) { + info := &cgroupInfo{Name: cgName} + if err := info.loadProcs(); err != nil { + return nil, err + } + return info, nil +} + +func deleteCgroup(cgName string) error { + dirName := filepath.Join("/sys/fs/cgroup", cgName) // #nosec dir, err := os.Open(dirName) if os.IsNotExist(err) { @@ -266,7 +307,7 @@ func tryRemoveAllCgroupDir(cgroupPath string) error { if i.IsDir() && i.Name() != "." && i.Name() != ".." { fullPath := filepath.Join(dirName, i.Name()) if err := unix.Rmdir(fullPath); err != nil { - return errors.Wrapf(err, "failed rmdir %s", fullPath) + return errors.Wrapf(err, "failed rmdir %s %T", fullPath, err) } } } diff --git a/cmd/clxc.go b/cmd/clxc.go index 4b4dcb61..22c2421a 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -132,10 +132,11 @@ func (c *crioLXC) createContainer() error { } // saveConfig creates and atomically enables the lxc config file. +// It must be called after #createContainer and only once. // Any config changes via clxc.setConfigItem must be done // before calling saveConfig. func (c *crioLXC) saveConfig() error { - // Allow it to be called once and only after createContainer. + // createContainer creates the tmpfile tmpFile := c.runtimePath(".config") if _, err := os.Stat(tmpFile); err != nil { return errors.Wrap(err, "failed to stat config tmpfile") @@ -389,15 +390,13 @@ func (c *crioLXC) tryRemoveCgroups() { if dir == "" { continue } - err := tryRemoveAllCgroupDir(dir) + err := deleteCgroup(dir) if err != nil { log.Warn().Err(err).Str("lxc.config", item).Msg("failed to remove cgroup scope") continue } - // try to remove outer directory, in case this is the POD that is deleted - // FIXME crio should delete the kubepods slice outerSlice := filepath.Dir(dir) - err = tryRemoveAllCgroupDir(outerSlice) + err = deleteCgroup(outerSlice) if err != nil { log.Debug().Err(err).Str("file", outerSlice).Msg("failed to remove cgroup slice") } From cbb5c6c23ab2b303cd4cfb012a4a3bcde78420d8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 17:48:55 +0100 Subject: [PATCH 048/373] logging: Separate runtime and container log-level definition. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 120 +++++++++++++++++++++++++++++--------------------- cmd/create.go | 8 ---- cmd/main.go | 15 +++++-- 3 files changed, 80 insertions(+), 63 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 22c2421a..6489dd72 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -20,6 +20,9 @@ import ( // time format used for logger const timeFormatLXCMillis = "20060102150405.000" +const defaultContainerLogLevel = lxc.WARN +const defaultLogLevel = zerolog.WarnLevel + // The singelton that wraps the lxc.Container var clxc crioLXC var log zerolog.Logger @@ -33,20 +36,20 @@ type crioLXC struct { Command string // [ global settings ] - RuntimeRoot string - ContainerID string - LogFile *os.File - LogFilePath string - LogLevel lxc.LogLevel - LogLevelString string - BackupDir string - Backup bool - BackupOnError bool - SystemdCgroup bool - MonitorCgroup string - StartCommand string - InitCommand string - HookCommand string + RuntimeRoot string + ContainerID string + LogFile *os.File + LogFilePath string + LogLevel string + ContainerLogLevel string + BackupDir string + Backup bool + BackupOnError bool + SystemdCgroup bool + MonitorCgroup string + StartCommand string + InitCommand string + HookCommand string // feature gates Seccomp bool @@ -99,8 +102,9 @@ func (c *crioLXC) loadContainer() error { if err != nil { return errors.Wrap(err, "failed to load config file") } + c.Container = container - return nil + return c.setContainerLogLevel() } // createContainer creates a new container. @@ -128,7 +132,7 @@ func (c *crioLXC) createContainer() error { return err } c.Container = container - return nil + return c.setContainerLogLevel() } // saveConfig creates and atomically enables the lxc config file. @@ -209,68 +213,82 @@ func (c *crioLXC) configureLogging() error { return errors.Wrapf(err, "failed to create log file directory %s", logDir) } - f, err := os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) + c.LogFile, err = os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { return errors.Wrapf(err, "failed to open log file %s", c.LogFilePath) } - c.LogFile = f - zerolog.TimestampFieldName = "t" zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" - zerolog.CallerFieldName = "c" - zerolog.TimeFieldFormat = timeFormatLXCMillis + // match liblxc timestamp format + zerolog.TimestampFieldName = "t" + zerolog.TimeFieldFormat = timeFormatLXCMillis zerolog.TimestampFunc = func() time.Time { return time.Now().UTC() } - // NOTE It's not possible change the possition of the timestamp. - // The ttimestamp is appended to the to the log output because it is dynamically rendered - // see https://github.com/rs/zerolog/issues/109 - log = zerolog.New(f).With().Timestamp().Caller().Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() + zerolog.CallerFieldName = "c" zerolog.CallerMarshalFunc = func(file string, line int) string { return filepath.Base(file) + ":" + strconv.Itoa(line) } - level, err := parseLogLevel(c.LogLevelString) + // NOTE Unfortunately it's not possible change the possition of the timestamp. + // The ttimestamp is appended to the to the log output because it is dynamically rendered + // see https://github.com/rs/zerolog/issues/109 + log = zerolog.New(c.LogFile).With().Timestamp().Caller(). + Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() + + level, err := zerolog.ParseLevel(strings.ToLower(c.LogLevel)) + if err != nil { + level = defaultLogLevel + log.Warn().Err(err).Str("val", c.LogLevel).Stringer("default", level). + Msg("failed to parse log-level - fallback to default") + } + zerolog.SetGlobalLevel(level) + return nil +} + +func (c *crioLXC) setContainerLogLevel() error { + // Never let lxc write to stdout, stdout belongs to the container init process. + // Explicitly disable it - allthough it is currently the default. + c.Container.SetVerbosity(lxc.Quiet) + // The log level for a running container is set, and may change, per runtime call. + err := c.Container.SetLogLevel(c.parseContainerLogLevel()) if err != nil { - log.Error().Err(err).Stringer("val", level).Msg("using fallback log-level") - } - c.LogLevel = level - - switch level { - case lxc.TRACE: - zerolog.SetGlobalLevel(zerolog.TraceLevel) - case lxc.DEBUG: - zerolog.SetGlobalLevel(zerolog.DebugLevel) - case lxc.INFO, lxc.NOTICE: - // zerolog does not support a `notice` log-level notice - zerolog.SetGlobalLevel(zerolog.InfoLevel) - case lxc.WARN: - zerolog.SetGlobalLevel(zerolog.WarnLevel) - case lxc.ERROR: - zerolog.SetGlobalLevel(zerolog.ErrorLevel) + return errors.Wrap(err, "failed to set container loglevel") + } + if err := c.Container.SetLogFile(c.LogFilePath); err != nil { + return errors.Wrap(err, "failed to set container log file") } return nil } -func parseLogLevel(s string) (lxc.LogLevel, error) { - switch strings.ToLower(s) { +func (c *crioLXC) parseContainerLogLevel() lxc.LogLevel { + switch strings.ToLower(c.ContainerLogLevel) { case "trace": - return lxc.TRACE, nil + return lxc.TRACE case "debug": - return lxc.DEBUG, nil + return lxc.DEBUG case "info": - return lxc.INFO, nil + return lxc.INFO case "notice": - return lxc.NOTICE, nil + return lxc.NOTICE case "warn": - return lxc.WARN, nil + return lxc.WARN case "error": - return lxc.ERROR, nil + return lxc.ERROR + case "crit": + return lxc.CRIT + case "alert": + return lxc.ALERT + case "fatal": + return lxc.FATAL default: - return lxc.INFO, fmt.Errorf("invalid log-level %s", s) + log.Warn().Str("val", c.ContainerLogLevel). + Stringer("default", defaultContainerLogLevel). + Msg("failed to parse container-log-level - fallback to default") + return defaultContainerLogLevel } } diff --git a/cmd/create.go b/cmd/create.go index 85a7573b..b350eae4 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -102,14 +102,6 @@ func doCreateInternal() error { return err } - err = clxc.Container.SetLogLevel(clxc.LogLevel) - if err != nil { - return errors.Wrap(err, "failed to set container loglevel") - } - if clxc.LogLevel == lxc.TRACE { - clxc.Container.SetVerbosity(lxc.Verbose) - } - clxc.SpecPath = filepath.Join(clxc.BundlePath, "config.json") spec, err := internal.ReadSpec(clxc.SpecPath) if err != nil { diff --git a/cmd/main.go b/cmd/main.go index 6a82899d..a799d584 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -36,14 +36,21 @@ func main() { app.Flags = []cli.Flag{ &cli.StringFlag{ Name: "log-level", - Usage: "set log level (trace|debug|info|warn|error)", + Usage: "set the runtime log level (trace|debug|info|warn|error)", EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, - Value: "warn", - Destination: &clxc.LogLevelString, + Value: defaultLogLevel.String(), + Destination: &clxc.LogLevel, + }, + &cli.StringFlag{ + Name: "container-log-level", + Usage: "set the container (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", + EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, + Value: defaultContainerLogLevel.String(), + Destination: &clxc.ContainerLogLevel, }, &cli.StringFlag{ Name: "log-file", - Usage: "log file for LXC and crio-lxc (default is per container in lxc-path)", + Usage: "path to log-file for combined runtime and container output", EnvVars: []string{"CRIO_LXC_LOG_FILE"}, Value: "/var/log/crio-lxc.log", Destination: &clxc.LogFilePath, From fc32b19f61fbc9d001ece6a1757f928a69aa7976 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 19 Nov 2020 18:32:56 +0100 Subject: [PATCH 049/373] Small log message change. Signed-off-by: Ruben Jenster --- cmd/exec.go | 6 +++--- cmd/main.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/exec.go b/cmd/exec.go index 8f4566f4..15448be5 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -108,7 +108,7 @@ func doExec(ctx *cli.Context) error { log.Info().Bool("detach", detach).Strs("args", procArgs). Int("uid", attachOpts.UID).Int("gid", attachOpts.GID). - Ints("groups", attachOpts.Groups).Msg("attach cmd to container") + Ints("groups", attachOpts.Groups).Msg("running cmd in container") if detach { pidFile := ctx.String("pid-file") @@ -116,7 +116,7 @@ func doExec(ctx *cli.Context) error { if err != nil { return errors.Wrapf(err, "c.RunCommandNoWait failed") } - log.Debug().Err(err).Int("pid", pid).Msg("cmd executed detached") + log.Debug().Err(err).Int("pid", pid).Msg("cmd is running detached") if pidFile == "" { log.Warn().Msg("detaching process but pid-file value is empty") return nil @@ -128,7 +128,7 @@ func doExec(ctx *cli.Context) error { if err != nil { return errors.Wrapf(err, "c.RunCommandStatus returned with exit code %d", exitStatus) } - log.Debug().Int("exit", exitStatus).Msg("cmd executed synchronous") + log.Debug().Int("exit", exitStatus).Msg("cmd terminated") return nil } diff --git a/cmd/main.go b/cmd/main.go index a799d584..0626e5b1 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -224,9 +224,9 @@ func main() { err := app.Run(os.Args) cmdDuration := time.Since(startTime) if err != nil { - log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") + log.Error().Err(err).Dur("duration", cmdDuration).Msg("runtime cmd failed") } else { - log.Debug().Dur("duration", cmdDuration).Msg("cmd done") + log.Debug().Dur("duration", cmdDuration).Msg("runtime cmd completed") } if err := clxc.release(); err != nil { From da94a0e5f596fd1473b8e573f330421552888e71 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 17:17:28 +0100 Subject: [PATCH 050/373] Rename hook to container-hook. * Improve error logging * Check for LXC_HOOK_TYPE=mount Signed-off-by: Ruben Jenster --- .gitignore | 2 +- Makefile | 6 +++--- cmd/clxc.go | 2 +- cmd/{hook => container-hook}/hook.go | 28 ++++++++++++++++++++-------- cmd/create.go | 2 +- cmd/main.go | 10 +++++----- 6 files changed, 31 insertions(+), 19 deletions(-) rename cmd/{hook => container-hook}/hook.go (73%) diff --git a/.gitignore b/.gitignore index d6869080..750bf499 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ crio-lxc crio-lxc-start crio-lxc-init -crio-lxc-hook +crio-lxc-container-hook crio-lxc-test* oci/ roots/ diff --git a/Makefile b/Makefile index 87eac446..5e0be546 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages -BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-hook +BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-container-hook PREFIX ?= /usr/local PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH @@ -28,8 +28,8 @@ crio-lxc-init: $(GO_SRC) Makefile go.mod # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null -crio-lxc-hook: $(GO_SRC) Makefile go.mod - go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/hook +crio-lxc-container-hook: $(GO_SRC) Makefile go.mod + go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/container-hook # make test TEST=basic will run only the basic test. .PHONY: check diff --git a/cmd/clxc.go b/cmd/clxc.go index 6489dd72..03beaa93 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -49,7 +49,7 @@ type crioLXC struct { MonitorCgroup string StartCommand string InitCommand string - HookCommand string + ContainerHook string // feature gates Seccomp bool diff --git a/cmd/hook/hook.go b/cmd/container-hook/hook.go similarity index 73% rename from cmd/hook/hook.go rename to cmd/container-hook/hook.go index 117a2398..14c638eb 100644 --- a/cmd/hook/hook.go +++ b/cmd/container-hook/hook.go @@ -9,39 +9,51 @@ import ( "path/filepath" ) -func fail(err error, details string) { - msg := fmt.Errorf("ERR: %s failed: %s", details, err.Error()) - panic(msg) +// from `man lxc.container.conf` +// Standard output from the hooks is logged at debug level. +// Standard error is not logged ... +func fail(err error, msg string, args ...interface{}) { + if err == nil { + fmt.Printf("ERR "+msg+"\n", args...) + } else { + fmt.Printf("ERR:"+msg+": %s\n", append(args, err)) + } + os.Exit(1) } func main() { // get rootfs mountpoint from environment rootfs := os.Getenv("LXC_ROOTFS_MOUNT") if rootfs == "" { - panic("LXC_ROOTFS_MOUNT environment is not set") + fail(nil, "LXC_ROOTFS_MOUNT environment is not set") + } + + // ensure we are running in the correct hook + if hook := os.Getenv("LXC_HOOK_TYPE"); hook != "mount" { + fail(nil, "LXC_HOOK_TYPE=%s but can only run in 'mount' hook", hook) } if _, err := os.Stat(rootfs); err != nil { - fail(err, "stat for rootfs mount failed "+rootfs) + fail(err, "stat for rootfs mount %q failed", rootfs) } specPath := filepath.Join(rootfs, internal.InitSpec) spec, err := internal.ReadSpec(specPath) if err != nil { - fail(err, "parse spec "+specPath) + fail(err, "failed to parse spec %s", specPath) } for _, dev := range spec.Linux.Devices { dev.Path = filepath.Join(rootfs, dev.Path) if err := createDevice(spec, dev); err != nil { - fail(err, "failed to create device "+dev.Path) + fail(err, "failed to create device %s", dev.Path) } } for _, p := range spec.Linux.MaskedPaths { rp := filepath.Join(rootfs, p) if err := maskPath(rp); err != nil { - fail(err, "failed to mask path "+rp) + fail(err, "failed to mask path %s", rp) } } } diff --git a/cmd/create.go b/cmd/create.go index b350eae4..1a606275 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -292,7 +292,7 @@ func configureInit(spec *specs.Spec) error { if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { return err } - if err := clxc.setConfigItem("lxc.hook.mount", clxc.HookCommand); err != nil { + if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { return err } diff --git a/cmd/main.go b/cmd/main.go index 0626e5b1..79492667 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -110,11 +110,11 @@ func main() { Destination: &clxc.StartCommand, }, &cli.StringFlag{ - Name: "cmd-hook", - Usage: "Name or path to binary executed in lxc.hook.mount", - EnvVars: []string{"CRIO_LXC_CMD_HOOK"}, - Value: "/usr/local/bin/crio-lxc-hook", - Destination: &clxc.HookCommand, + Name: "container-hook", + Usage: "absolute path to container hook executable", + EnvVars: []string{"CRIO_LXC_CONTAINER_HOOK"}, + Value: "/usr/local/bin/crio-lxc-container-hook", + Destination: &clxc.ContainerHook, }, &cli.BoolFlag{ Name: "seccomp", From 741eeea5620077237932f02a6d0eee2e59cbc056 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 17:23:45 +0100 Subject: [PATCH 051/373] Move constants to top of file. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 03beaa93..05849fba 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -17,11 +17,13 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -// time format used for logger -const timeFormatLXCMillis = "20060102150405.000" - -const defaultContainerLogLevel = lxc.WARN -const defaultLogLevel = zerolog.WarnLevel +// logging constants +const ( + // liblxc timestamp formattime format + timeFormatLXCMillis = "20060102150405.000" + defaultContainerLogLevel = lxc.WARN + defaultLogLevel = zerolog.WarnLevel +) // The singelton that wraps the lxc.Container var clxc crioLXC @@ -30,6 +32,23 @@ var log zerolog.Logger var errContainerNotExist = errors.New("container does not exist") var errContainerExist = errors.New("container already exists") +// runtime states https://github.com/opencontainers/runtime-spec/blob/v1.0.2/runtime.md +const ( + // the container is being created (step 2 in the lifecycle) + stateCreating = "creating" + // the runtime has finished the create operation (after step 2 in the lifecycle), + // and the container process has neither exited nor executed the user-specified program + stateCreated = "created" + // the container process has executed the user-specified program + // but has not exited (after step 5 in the lifecycle) + stateRunning = "running" + // the container process has exited (step 7 in the lifecycle) + stateStopped = "stopped" + + // crio-lxc-init is started but blocking at the syncfifo + envStateCreated = "CRIO_LXC_STATE=" + stateCreated +) + type crioLXC struct { Container *lxc.Container @@ -228,6 +247,7 @@ func (c *crioLXC) configureLogging() error { return time.Now().UTC() } + // TODO only log caller information in debug and trace level zerolog.CallerFieldName = "c" zerolog.CallerMarshalFunc = func(file string, line int) string { return filepath.Base(file) + ":" + strconv.Itoa(line) @@ -334,23 +354,6 @@ func copyDir(src, dst string) error { return nil } -// runtime states https://github.com/opencontainers/runtime-spec/blob/v1.0.2/runtime.md -const ( - // the container is being created (step 2 in the lifecycle) - stateCreating = "creating" - // the runtime has finished the create operation (after step 2 in the lifecycle), - // and the container process has neither exited nor executed the user-specified program - stateCreated = "created" - // the container process has executed the user-specified program - // but has not exited (after step 5 in the lifecycle) - stateRunning = "running" - // the container process has exited (step 7 in the lifecycle) - stateStopped = "stopped" - - // crio-lxc-init is started but blocking at the syncfifo - envStateCreated = "CRIO_LXC_STATE=" + stateCreated -) - func (c *crioLXC) isContainerStopped() bool { return c.Container.State() == lxc.STOPPED } From 7c1f1b0b1e37dfcc2d0555a8745b5313908b6ff8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 17:27:48 +0100 Subject: [PATCH 052/373] Rename CreateTimeout to ConsoleSocketTimeout Signed-off-by: Ruben Jenster --- cmd/clxc.go | 2 +- cmd/create.go | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 05849fba..33d27ffe 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -81,7 +81,7 @@ type crioLXC struct { SpecPath string // BundlePath + "/config.json" PidFile string ConsoleSocket string - CreateTimeout time.Duration + ConsoleSocketTimeout time.Duration // start flags StartTimeout time.Duration diff --git a/cmd/create.go b/cmd/create.go index 1a606275..1d30c85c 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -45,12 +45,11 @@ var createCmd = cli.Command{ Destination: &clxc.PidFile, }, &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for sending pty master to socket", - EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, - Value: time.Second * 60, - // TODO rename to console-socket-timeout - Destination: &clxc.CreateTimeout, + Name: "socket-timeout", + Usage: "timeout for sending pty master to socket", + EnvVars: []string{"CRIO_LXC_CREATE_SOCKET_TIMEOUT"}, + Value: time.Second * 60, + Destination: &clxc.ConsoleSocketTimeout, }, }, } @@ -497,7 +496,7 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { return errors.Wrap(err, "connecting to console socket failed") } defer conn.Close() - deadline := time.Now().Add(time.Second * clxc.CreateTimeout) + deadline := time.Now().Add(clxc.ConsoleSocketTimeout) err = conn.SetDeadline(deadline) if err != nil { return errors.Wrap(err, "failed to set connection deadline") From 7c276fd949776326c8d5e6afd9fac40ba9e4ac92 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 17:32:00 +0100 Subject: [PATCH 053/373] Rename CMD environment variables. Fix typos in Usage strings. Signed-off-by: Ruben Jenster --- cmd/main.go | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 79492667..e75b27d5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -20,9 +20,9 @@ func main() { app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" app.Version = versionString() - // The default handler will exit the appp if the command returns an error - // that implements the cli.ExitCoder interface. - // E.g an unwrapped error from os.Exec + // Disable the default ExitErrHandler. + // It will call os.Exit if a command returns an error that implements + // the cli.ExitCoder interface. E.g an unwrapped error from os.Exec. app.ExitErrHandler = func(context *cli.Context, err error) {} app.Commands = []*cli.Command{ &stateCmd, @@ -31,6 +31,8 @@ func main() { &killCmd, &deleteCmd, &execCmd, + // TODO extend urfave/cli to render a default environment file. + } app.Flags = []cli.Flag{ @@ -43,14 +45,14 @@ func main() { }, &cli.StringFlag{ Name: "container-log-level", - Usage: "set the container (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", + Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, - Value: defaultContainerLogLevel.String(), + Value: strings.ToLower(defaultContainerLogLevel.String()), Destination: &clxc.ContainerLogLevel, }, &cli.StringFlag{ Name: "log-file", - Usage: "path to log-file for combined runtime and container output", + Usage: "path to the log file for runtime and container output", EnvVars: []string{"CRIO_LXC_LOG_FILE"}, Value: "/var/log/crio-lxc.log", Destination: &clxc.LogFilePath, @@ -90,23 +92,23 @@ func main() { }, &cli.StringFlag{ Name: "monitor-cgroup", - Usage: "cgroup for LXC monitor processes", + Usage: "cgroup slice for liblxc monitor process", Destination: &clxc.MonitorCgroup, EnvVars: []string{"CRIO_LXC_MONITOR_CGROUP"}, Value: "crio-lxc-monitor.slice", }, &cli.StringFlag{ Name: "cmd-init", - Usage: "Absolute path to container init binary", - EnvVars: []string{"CRIO_LXC_CMD_INIT"}, + Usage: "absolute path to container init executable", + EnvVars: []string{"CRIO_LXC_INIT_CMD"}, Value: "/usr/local/bin/crio-lxc-init", Destination: &clxc.InitCommand, }, &cli.StringFlag{ Name: "cmd-start", - Usage: "Name or path to container start binary", - EnvVars: []string{"CRIO_LXC_CMD_START"}, - Value: "crio-lxc-start", + Usage: "absolute path to container start executable", + EnvVars: []string{"CRIO_LXC_START_CMD"}, + Value: "/usr/local/bin/crio-lxc-start", Destination: &clxc.StartCommand, }, &cli.StringFlag{ @@ -132,14 +134,14 @@ func main() { }, &cli.BoolFlag{ Name: "apparmor", - Usage: "Set apparmor profile defined in container spec", + Usage: "set apparmor profile defined in container spec", Destination: &clxc.Apparmor, EnvVars: []string{"CRIO_LXC_APPARMOR"}, Value: true, }, &cli.BoolFlag{ Name: "cgroup-devices", - Usage: "Allow only devices permitted by container spec", + Usage: "allow only devices permitted by container spec", Destination: &clxc.CgroupDevices, EnvVars: []string{"CRIO_LXC_CGROUP_DEVICES"}, Value: true, @@ -148,9 +150,12 @@ func main() { startTime := time.Now() - env, envErr := loadEnvFile(envFile) - // Environment variables must be injected from file before app is run, + // Environment variables must be injected from file before app.Run() is called. // Otherwise the values are not set to the crioLXC instance. + // FIXME when calling '--help' defaults are overwritten with environment variables. + // So you will never see the real default value if either an environment file is present + // or an environment variable is set. + env, envErr := loadEnvFile(envFile) if env != nil { for key, val := range env { if err := setEnvIfNew(key, val); err != nil { From 1c12b7f49750bbcebc13c90dde87511c30ee4cb1 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 17:35:01 +0100 Subject: [PATCH 054/373] Introduce --runtime-hook and remove backup code. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 80 ++++++++++++++++++++++----------------------------- cmd/create.go | 16 ++++------- cmd/main.go | 63 ++++++++++++++++++++-------------------- 3 files changed, 71 insertions(+), 88 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 33d27ffe..6a7b4fd0 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "github.com/pkg/errors" "io/ioutil" @@ -12,7 +13,6 @@ import ( "strings" "time" - "github.com/lxc/crio-lxc/cmd/internal" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" ) @@ -61,14 +61,15 @@ type crioLXC struct { LogFilePath string LogLevel string ContainerLogLevel string - BackupDir string - Backup bool - BackupOnError bool SystemdCgroup bool MonitorCgroup string - StartCommand string - InitCommand string - ContainerHook string + + StartCommand string + InitCommand string + ContainerHook string + RuntimeHook string + RuntimeHookTimeout time.Duration + RuntimeHookRunAlways bool // feature gates Seccomp bool @@ -77,10 +78,10 @@ type crioLXC struct { CgroupDevices bool // create flags - BundlePath string - SpecPath string // BundlePath + "/config.json" - PidFile string - ConsoleSocket string + BundlePath string + SpecPath string // BundlePath + "/config.json" + PidFile string + ConsoleSocket string ConsoleSocketTimeout time.Duration // start flags @@ -312,46 +313,35 @@ func (c *crioLXC) parseContainerLogLevel() lxc.LogLevel { } } -// BackupRuntimeResources creates a backup of the container runtime resources. -// It returns the path to the backup directory. -// -// The following resources are backed up: -// - all resources created by crio-lxc (lxc config, init script, device creation script ...) -// - lxc logfiles (if logging is setup per container) -// - the runtime spec -func (c *crioLXC) backupRuntimeResources() (backupDir string, err error) { - backupDir = filepath.Join(c.BackupDir, c.ContainerID) - err = os.MkdirAll(c.BackupDir, 0700) - if err != nil { - return "", errors.Wrap(err, "failed to create backup dir") - } - err = copyDir(c.runtimePath(), backupDir) - if err != nil { - return backupDir, errors.Wrap(err, "failed to copy lxc runtime directory") +func (c *crioLXC) executeRuntimeHook(err error) { + if c.RuntimeHook == "" { + return } - // remove syncfifo because it is not of any use and blocks 'grep' within the backup directory. - syncFifoPath := filepath.Join(backupDir, internal.SyncFifoPath) - // #nosec - err = os.Remove(syncFifoPath) - if err != nil { - log.Warn().Err(err).Str("file", syncFifoPath).Msg("failed to remove syncfifo from backup dir") + // prepare environment + env := []string{ + "CONTAINER_ID=" + c.ContainerID, + "LXC_CONFIG=" + c.configFilePath(), + "RUNTIME_CMD=" + c.Command, + "RUNTIME_PATH=" + c.runtimePath(), + "BUNDLE_PATH=" + c.BundlePath, + "SPEC_PATH=" + c.SpecPath, } - err = copyDir(c.SpecPath, backupDir) + if err != nil { - return backupDir, errors.Wrap(err, "failed to copy runtime spec to backup dir") + env = append(env, "RUNTIME_ERROR="+err.Error()) } - return backupDir, nil -} -// TODO avoid shellout -func copyDir(src, dst string) error { - // #nosec - cmd := exec.Command("cp", "-r", "-p", src, dst) - output, err := cmd.CombinedOutput() - if err != nil { - return errors.Errorf("%s: %s: %s", strings.Join(cmd.Args, " "), err, string(output)) + log.Debug().Str("file", clxc.RuntimeHook).Msg("execute runtime hook") + // TODO drop privileges, capabilities ? + ctx, cancel := context.WithTimeout(context.Background(), clxc.RuntimeHookTimeout) + defer cancel() + cmd := exec.CommandContext(ctx, c.RuntimeHook) + cmd.Env = env + cmd.Dir = "/" + if err := cmd.Run(); err != nil { + log.Error().Err(err).Str("file", c.RuntimeHook). + Bool("timeout-expired", ctx.Err() == context.DeadlineExceeded).Msg("runtime hook failed") } - return nil } func (c *crioLXC) isContainerStopped() bool { diff --git a/cmd/create.go b/cmd/create.go index 1d30c85c..a1c8fe5f 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -62,22 +62,16 @@ func checkAccess(externalCmds ...string) error { } return nil } - func doCreate(ctx *cli.Context) error { - err := doCreateInternal() - if clxc.Backup || (err != nil && clxc.BackupOnError) { - dir, err := clxc.backupRuntimeResources() - if err != nil { - log.Error().Err(err).Str("file", dir).Msg("runtime backup failed") - } else { - log.Trace().Str("file", dir).Msg("runtime backup created") - } + err := doCreateInternal(ctx) + if err != nil || clxc.RuntimeHookRunAlways { + clxc.executeRuntimeHook(err) } return err } -func doCreateInternal() error { - err := checkAccess(clxc.StartCommand, clxc.HookCommand, clxc.InitCommand) +func doCreateInternal(ctx *cli.Context) error { + err := checkAccess(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return err } diff --git a/cmd/main.go b/cmd/main.go index e75b27d5..7d9b6924 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -57,27 +57,6 @@ func main() { Value: "/var/log/crio-lxc.log", Destination: &clxc.LogFilePath, }, - &cli.StringFlag{ - Name: "backup-dir", - Usage: "directory for container runtime directory backups", - EnvVars: []string{"CRIO_LXC_BACKUP_DIR"}, - Value: "/var/lib/crio-lxc/backup", - Destination: &clxc.BackupDir, - }, - &cli.BoolFlag{ - Name: "backup-on-error", - Usage: "backup container runtime directory when cmd-start fails", - EnvVars: []string{"CRIO_LXC_BACKUP_ON_ERROR"}, - Value: true, - Destination: &clxc.BackupOnError, - }, - &cli.BoolFlag{ - Name: "backup", - Usage: "backup every container runtime before cmd-start is called", - EnvVars: []string{"CRIO_LXC_BACKUP"}, - Value: false, - Destination: &clxc.Backup, - }, &cli.StringFlag{ Name: "root", Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended.", @@ -118,19 +97,25 @@ func main() { Value: "/usr/local/bin/crio-lxc-container-hook", Destination: &clxc.ContainerHook, }, - &cli.BoolFlag{ - Name: "seccomp", - Usage: "Generate and apply seccomp profile for lxc from container spec", - Destination: &clxc.Seccomp, - EnvVars: []string{"CRIO_LXC_SECCOMP"}, - Value: true, + &cli.StringFlag{ + Name: "runtime-hook", + Usage: "absolute path to runtime hook executable", + EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK"}, + Destination: &clxc.RuntimeHook, + }, + &cli.DurationFlag{ + Name: "runtime-hook-timeout", + Usage: "duration after which the runtime hook is killed", + EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK_TIMEOUT"}, + Value: time.Second * 5, + Destination: &clxc.RuntimeHookTimeout, }, &cli.BoolFlag{ - Name: "capabilities", - Usage: "Keep capabilities defined in container spec", - Destination: &clxc.Capabilities, - EnvVars: []string{"CRIO_LXC_CAPABILITIES"}, - Value: true, + Name: "runtime-hook-always", + Usage: "if true runtime hook will run on every create - not only on error", + EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK_RUN_ALWAYS"}, + Value: false, + Destination: &clxc.RuntimeHookRunAlways, }, &cli.BoolFlag{ Name: "apparmor", @@ -139,6 +124,13 @@ func main() { EnvVars: []string{"CRIO_LXC_APPARMOR"}, Value: true, }, + &cli.BoolFlag{ + Name: "capabilities", + Usage: "keep capabilities defined in container spec", + Destination: &clxc.Capabilities, + EnvVars: []string{"CRIO_LXC_CAPABILITIES"}, + Value: true, + }, &cli.BoolFlag{ Name: "cgroup-devices", Usage: "allow only devices permitted by container spec", @@ -146,6 +138,13 @@ func main() { EnvVars: []string{"CRIO_LXC_CGROUP_DEVICES"}, Value: true, }, + &cli.BoolFlag{ + Name: "seccomp", + Usage: "Generate and apply seccomp profile for lxc from container spec", + Destination: &clxc.Seccomp, + EnvVars: []string{"CRIO_LXC_SECCOMP"}, + Value: true, + }, } startTime := time.Now() From 355cb3148b538d4cf16ade1d0c8371ebafd78301 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:26:50 +0100 Subject: [PATCH 055/373] Fix lint and gosec errors. Ignore gosec false-positives. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 6 +++++- cmd/internal/internal.go | 3 +++ cmd/utils.go | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 6a7b4fd0..ca757600 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -141,11 +141,14 @@ func (c *crioLXC) createContainer() error { // An empty tmpfile is created to ensure that createContainer can only succeed once. // The config file is atomically activated in saveConfig. + // #nosec f, err := os.OpenFile(c.runtimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) if err != nil { return err } - f.Close() + if err := f.Close(); err != nil { + return errors.Wrap(err, "failed to close empty config file") + } container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { @@ -335,6 +338,7 @@ func (c *crioLXC) executeRuntimeHook(err error) { // TODO drop privileges, capabilities ? ctx, cancel := context.WithTimeout(context.Background(), clxc.RuntimeHookTimeout) defer cancel() + // #nosec cmd := exec.CommandContext(ctx, c.RuntimeHook) cmd.Env = env cmd.Dir = "/" diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go index 9c1b2740..49165596 100644 --- a/cmd/internal/internal.go +++ b/cmd/internal/internal.go @@ -54,6 +54,7 @@ func WriteSpec(spec *specs.Spec, specFilePath string) error { return f.Sync() } +// WriteFifo writes to the SyncFifo to synchronize container process init func WriteFifo() error { f, err := os.OpenFile(SyncFifoPath, os.O_WRONLY, 0) if err != nil { @@ -66,6 +67,8 @@ func WriteFifo() error { return f.Close() } +// ReadFifo reads the content from the SyncFifo that was written by #WriteFifo. +// The read operation is aborted after the given timeout. func ReadFifo(fifoPath string, timeout time.Duration) error { // #nosec f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) diff --git a/cmd/utils.go b/cmd/utils.go index 82e9d675..ad0ea07e 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -31,6 +31,7 @@ func createPidFile(path string, pid int) error { } func readPidFile(path string) (int, error) { + // #nosec data, err := ioutil.ReadFile(path) if err != nil { return 0, err From da1b325ce4e59195216c306bdf41c12dde417ae3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 18:06:59 +0100 Subject: [PATCH 056/373] Rename original README. Signed-off-by: Ruben Jenster --- README.md => README.old.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => README.old.md (100%) diff --git a/README.md b/README.old.md similarity index 100% rename from README.md rename to README.old.md From aba0c26b9c1a524d290e2de03884918da63faeaf Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 19:30:58 +0100 Subject: [PATCH 057/373] Add documentation. Signed-off-by: Ruben Jenster --- INSTALL.md | 148 ++++++++++++++++++++++++++++++++++++++++++++ K8S.md | 120 ++++++++++++++++++++++++++++++++++++ README.md | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 444 insertions(+) create mode 100644 INSTALL.md create mode 100644 K8S.md create mode 100644 README.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000..0098b977 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,148 @@ +## cgroups + +Enable cgroupv2 unified hierarchy manually: + +``` +mount -t cgroup2 none /sys/fs/cgroup +``` + +or permanent via kernel cmdline params: + + ``` + systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all + ``` + +## build dependencies + +Install the build dependencies which are required to build the runtime and runtime dependencies. + +### debian + +```sh +# liblxc / conmon build dependencies +apt-get install build-essential libtool automake pkg-config \ +libseccomp-dev libapparmor-dev libbtrfs-dev \ +libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev +# k8s dependencies, tools +apt-get install jq ebtables iptables conntrack +``` + +### arch linux + +```sh +# liblxc / conmon build dependencies +pacman -Sy base-devel apparmor libseccomp libpcap btrfs-progs +# k8s dependencies +pacman -Sy conntrack-tools ebtables jq +``` + +## runtime dependencies + +* [lxc](https://github.com/lxc/lxc.git) >= 4.0.5, master recommened +* [conmon/pinns](https://github.com/containers/conmon.git) v2.0.2 +* [cri-o](https://github.com/cri-o/cri-o.git) release-1.19 + +By default everything is installed to `/usr/local` + +### lxc (liblxc) + +```sh +git clone https://github.com/lxc/lxc.git +cd lxc +./autogen.sh +./configure --enable-bash=no --enable-tools=no \ + --enable-commands=no --enable-seccomp=yes \ + --enable-capabilities=yes --enable-apparmor=yes +make install + +echo /usr/local/lib > /etc/ld.so.conf.d/local.conf +ldconfig +``` + +### crio-lxc + +``` +make install +``` + +The installation prefix environment variable is set to `PREFIX=/usr/local` by default.
+The library source path for `pkg-config` is set to `$PREFIX/lib/pkg-config` by default.
+You can change that by setting the `PKG_CONFIG_PATH` environment variable.
+ +E.g to install binaries in `/opt/bin` but use liblxc from `/usr/lib`: + + PREFIX=/opt PKG_CONFIG_PATH=/usr/lib/pkgconfig make install + +Keep in mind that you have to change the `INSTALL_PREFIX` in the crio install script below. + +### conmon + +```sh +git clone https://github.com/containers/conmon.git +cd conmon +git reset --hard v2.0.2 +make clean +make install +``` + +### cri-o + +```sh +#!/bin/sh +git clone https://github.com/cri-o/cri-o.git +cd cri-o +git reset --hard origin/release-1.19 +make install + +PREFIX=/usr/local +CRIO_LXC_ROOT=/run/crio-lxc + +# environment for `crio config` +export CONTAINER_CONMON=${PREFIX}/bin/conmon +export CONTAINER_PINNS_PATH=${PREFIX}/bin/pinns +export CONTAINER_DEFAULT_RUNTIME=crio-lxc +export CONTAINER_RUNTIMES=crio-lxc:${PREFIX}/bin/crio-lxc:$CRIO_LXC_ROOT + +crio config > /etc/crio/crio.conf +``` + +#### cgroupv2 ebpf + +Modify systemd service file to run with full privileges.
+This is required for the runtime to set cgroupv2 device controller eBPF.
+See https://github.com/cri-o/cri-o/pull/4272 + +``` +sed -i 's/ExecStart=\//ExecStart=+\//' /usr/local/lib/systemd/system/crio.service +systemctl daemon-reload +systemctl start crio +``` + +#### storage configuration + +If you're using `overlay` as storage driver cri-o may complain that it is not using `native diff` mode.
+Update `/etc/containers/storage.conf` to fix this. + +``` +# see https://github.com/containers/storage/blob/v1.20.2/docs/containers-storage.conf.5.md +[storage] +driver = "overlay" + +[storage.options.overlay] +# see https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt, `modinfo overlay` +# [ 8270.526807] overlayfs: conflicting options: metacopy=on,redirect_dir=off +# NOTE: metacopy can only be enabled when redirect_dir is enabled +# NOTE: storage driver name must be set or mountopt are not evaluated, +# even when the driver is the default driver --> BUG ? +mountopt = "nodev,redirect_dir=off,metacopy=off" +``` + +#### HTTP proxy + +If you're system is proxied you can add the proxy environment variables to `/etc/default/crio` + +``` +http_proxy="http://myproxy:3128" +https_proxy="http://myproxy:3128" +no_proxy="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,127.0.0.1,localhost" +``` diff --git a/K8S.md b/K8S.md new file mode 100644 index 00000000..e819ca95 --- /dev/null +++ b/K8S.md @@ -0,0 +1,120 @@ +## kubernetes + +The following skript downloads kubernetes [v1.19.4](https://dl.k8s.io/v1.19.4) and installs it to `/usr/local/bin`.
+You have to create the `kubelet.service` and `10-kubeadm.conf` before running the script. + +```sh +#!/bin/sh +# about: installs kubeadm,kubectl and kubelet to /usr/local/bin +# installs systemd service to /etc/systemd/system + + +# Upgrade process: +# * change RELEASE and CHECKSUM +# * remove downloaded archive file +# * run this script again + +ARCH="linux-amd64" +RELEASE="1.19.4" +ARCHIVE=kubernetes-server-$ARCH.tar.gz +CHECKSUM="fc9de14121af682af167ef99ce8a3803c25e92ef4739ed7eb592eadb30086b2cb9ede51d57816d1c3835f6202753d726eba804b839ae9cd516eff4e94c81c189" +DESTDIR="/usr/local/bin" + +[ -e "$ARCHIVE" ] || wget https://dl.k8s.io/v$RELEASE/$FILE + +echo "$CHECKSUM $ARCHIVE" | sha512sum -c || exit 1 + +tar -x -z -f $ARCHIVE -C $DESTDIR --strip-components=3 kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet +install -v kubelet.service /etc/systemd/system/ +install -v -D 10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf +systemctl daemon-reload +``` + +### systemd service + +**kubelet.service** +``` +[Unit] +Description=kubelet: The Kubernetes Node Agent +Documentation=http://kubernetes.io/docs/ + +[Service] +ExecStart=/usr/local/bin/kubelet +Restart=always +StartLimitInterval=0 +RestartSec=10 + +[Install] +WantedBy=multi-user.target +``` + +**10-kubeadm.conf** +``` +# Note: This dropin only works with kubeadm and kubelet v1.11+ +[Service] +Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" +Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" +# This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically +EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env +# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use +# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. +EnvironmentFile=-/etc/default/kubelet +ExecStart= +ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS +``` + +### kubeadm init + +This initializes the kubernetes control-plane. + +* Replace `HOSTIP` and `HOSTNAME` variables in `cluster-init.yaml` and initialize the cluster: + +``` +kubeadm init --config cluster-init.yaml -v 5 +# for single node cluster remove taint +taint remove kubectl taint nodes --all node-role.kubernetes.io/master- +``` + + * Install a networking plugin (I'm using [calico](https://www.projectcalico.org)) + +**cluster-init.yaml** +```yaml +apiVersion: kubeadm.k8s.io/v1beta2 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: {HOSTIP} + bindPort: 6443 +nodeRegistration: + name: {HOSTNAME} + criSocket: unix://var/run/crio/crio.sock + taints: + - effect: NoSchedule + key: node-role.kubernetes.io/master +# kubeletExtraArgs: +# v: "5" +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +cgroupDriver: systemd +--- +kind: ClusterConfiguration +kubernetesVersion: v1.19.4 +apiVersion: kubeadm.k8s.io/v1beta2 +apiServer: + timeoutForControlPlane: 4m0s +certificatesDir: /etc/kubernetes/pki +clusterName: kubernetes +controllerManager: {} +dns: + type: CoreDNS +etcd: + local: + dataDir: /var/lib/etcd +imageRepository: k8s.gcr.io +networking: + dnsDomain: cluster.local + serviceSubnet: 10.96.0.0/12 + podSubnet: 10.66.0.0/16 +scheduler: {} +controlPlaneEndpoint: "${HOSTIP}:6443" +``` diff --git a/README.md b/README.md new file mode 100644 index 00000000..eb1bc1ae --- /dev/null +++ b/README.md @@ -0,0 +1,176 @@ +# About + +This is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as +a drop-in container runtime replacement for use by +[CRI-O](https://github.com/kubernetes-sigs/cri-o). + +## Installation + +For the installation of the runtime see [INSTALL.md](INSTALL.md)
+For the installation and initialization of a kubernetes cluster see [K8S.md](K8S.md) + +## Glossary + +* `runtime` the crio-lxc binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) +* `container process` the process that starts and runs the container using liblxc (crio-lxc-start) + +## Bugs + +* cli: --help shows environment values not defaults https://github.com/urfave/cli/issues/1206 + +## Requirements and restrictions + +* Only cgroupv2 unified cgroup hierarchy is supported. +* A recent kernel > 5.8 is required for full cgroup support. +* Cgroup resource limits are not implemented yet. This will change soon. +* runtime spec `additionalGroups` requires liblxc and go-lxc development version + +## Configuration + +The runtime binary implements flags that are required by the `OCI runtime spec`,
+and flags that are runtime specific (timeouts, hooks, logging ...). + +Most of the runtime specific flags have corresponding environment variables. See `crio-lxc --help`.
+The runtime evaluates the flag value in the following order (lower order takes precedence). + +1. cmdline flag from process arguments (overwrites process environment) +2. process environment variable (overwrites environment file) +3. environment file (overwrites cmdline flag default) +4. cmdline flag default + +### Environment variables + +Currently you have to compile to environment file yourself.
+To get all available variables + +``` +grep EnvVars cmd/*.go | grep -o CRIO_LXC_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" +``` + +### Environment file + +The default path to the environment file is `/etc/defaults/crio-lxc`.
+It is loaded on every start of the `crio-lxc` binary, so changes take immediate effect.
+Empty lines and those commented with a leading *#* are ignored.
+ +A malformed environment will let the next runtime call fail.
+In production it's recommended that you replace the environment file atomically.
+ +E.g the environment file `/etc/default/crio-lxc` could look like this: + +``` +#CRIO_LXC_CONTAINER_HOOK= +#CRIO_LXC_CREATE_TIMEOUT=30s +#CRIO_LXC_INIT_CMD= +#CRIO_LXC_START_CMD= +#CRIO_LXC_START_TIMEOUT=30s + +CRIO_LXC_APPARMOR=true +CRIO_LXC_CAPABILITIES=true +CRIO_LXC_CGROUP_DEVICES=true +CRIO_LXC_SECCOMP=true + +CRIO_LXC_LOG_FILE=/tmp/crio-lxc.log +CRIO_LXC_LOG_LEVEL=info +CRIO_LXC_CONTAINER_LOG_LEVEL=warn + +CRIO_LXC_MONITOR_CGROUP=crio-lxc-monitor.slice +CRIO_LXC_RUNTIME_HOOK=/usr/local/bin/crio-lxc-backup.sh +#CRIO_LXC_RUNTIME_HOOK_RUN_ALWAYS=false +#CRIO_LXC_RUNTIME_HOOK_TIMEOUT= +``` + +### Runtime (security) features + +All supported runtime security features are enabled by default.
+There following runtime (security) features can optionally be disabled.
+Details see `crio-lxc --help` + +* apparmor +* capabilities +* cgroup-devices +* seccomp + +### Logging + +There is only a single log file for runtime and container process log output.
+The log-level for the runtime and the container process can be set independently. + +* a single logfile is easy to rotate and monitor +* a single logfile is easy to tail (watch for errors / events ...) +* robust implementation is easy + +#### Log Filtering + +Runtime log lines are written in JSON using [zerolog](https://github.com/rs/zerolog).
+The log file can be easily filtered with [jq](https://stedolan.github.io/jq/).
+For filtering with `jq` you must strip the container process logs with `grep -v '^lxc'`
+ +E.g Filter show only errors and warnings for runtime `create` command: + +```sh + grep -v '^lxc ' /var/log/crio-lxc.log |\ + jq -c 'select(.cmd == "create" and ( .l == "error or .l == "warn")' +``` + +#### Runtime log fields + +Fields that are always present: + +* `l` log level +* `m` log message +* `c` caller (source file and line number) +* `cid` container ID +* `cmd` runtime command +* `t` timestamp in UTC (format matches container process output) + + +Log message specific fields: + +* `pid` a process ID +* `file` a path to a file +* `lxc.config` the key of a container process config item +* `env` the key of an environment variable + + +### Debugging + +Apart from the logfile following resources are useful: + +* Systemd journal for cri-o and kubelet services +* `coredumpctl` if runtime or container process segfaults. + +#### Runtime Hook + +If a runtime hook is defined, it is executed when the `create` command returns with an error.
+You can use the runtime hook to backup the runtime spec and container process config for further analysis.
+ +The runtime hook executable must + +* not use the standard file descriptors (stdin/stdout/stderr) although they are nulled. +* not exceeds `CRIO_LXC_RUNTIME_HOOK_TIMEOUT` or it gets killed. +* not modify/delete any resources created by the runtime or container process + +The runtime hook process environment contains the following variables: + +* `CONTAINER_ID` the container ID +* `LXC_CONFIG` the path to runtime process config +* `RUNTIME_CMD` the runtime command which executed the runtime hook +* `RUNTIME_PATH` the path to the container runtime directory +* `BUNDLE_PATH` the absolute path to the container bundle +* `SPEC_PATH` the absolute path to the the JSON runtime spec +* `RUNTIME_ERROR` (optional) the error message if the runtime cmd return with error + +Example environment of a shell script: + +``` +SPEC_PATH=/var/run/containers/storage/overlay-containers/XXX/userdata/config.json +PWD=/ +RUNTIME_PATH=/run/crio-lxc/XXX +CONTAINER_ID=XXX +SHLVL=1 +RUNTIME_CMD=create +BUNDLE_PATH=/var/run/containers/storage/overlay-containers/XXX/userdata +LXC_CONFIG=/run/crio-lxc/XXX/config +_=/usr/bin/env +``` From 3302496b0d64ef4b2454e5711e281bdb428f1a25 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 21:13:31 +0100 Subject: [PATCH 058/373] Fix formatting. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 2 +- cmd/internal/internal.go | 2 +- cmd/utils.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index ca757600..b3657893 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -147,7 +147,7 @@ func (c *crioLXC) createContainer() error { return err } if err := f.Close(); err != nil { - return errors.Wrap(err, "failed to close empty config file") + return errors.Wrap(err, "failed to close empty config file") } container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go index 49165596..b1675b78 100644 --- a/cmd/internal/internal.go +++ b/cmd/internal/internal.go @@ -54,7 +54,7 @@ func WriteSpec(spec *specs.Spec, specFilePath string) error { return f.Sync() } -// WriteFifo writes to the SyncFifo to synchronize container process init +// WriteFifo writes to the SyncFifo to synchronize container process init func WriteFifo() error { f, err := os.OpenFile(SyncFifoPath, os.O_WRONLY, 0) if err != nil { diff --git a/cmd/utils.go b/cmd/utils.go index ad0ea07e..5f3f0b70 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -31,7 +31,7 @@ func createPidFile(path string, pid int) error { } func readPidFile(path string) (int, error) { - // #nosec + // #nosec data, err := ioutil.ReadFile(path) if err != nil { return 0, err From 896a4c7df1b5c2367f46dd01c0c3d7aeece72911 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 22:52:58 +0100 Subject: [PATCH 059/373] state: Cleanup container state retrieval. Add ContainerState type from runtime spec. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 34 +++++++++++----------------------- cmd/specs/specs.go | 22 ++++++++++++++++++++++ cmd/state.go | 18 +++++++----------- 3 files changed, 40 insertions(+), 34 deletions(-) create mode 100644 cmd/specs/specs.go diff --git a/cmd/clxc.go b/cmd/clxc.go index b3657893..ddccbfd1 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/lxc/crio-lxc/cmd/specs" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" ) @@ -23,6 +24,9 @@ const ( timeFormatLXCMillis = "20060102150405.000" defaultContainerLogLevel = lxc.WARN defaultLogLevel = zerolog.WarnLevel + + // crio-lxc-init is started but blocking at the syncfifo + envStateCreated = "CRIO_LXC_STATE=" + string(specs.StateCreated) ) // The singelton that wraps the lxc.Container @@ -32,23 +36,6 @@ var log zerolog.Logger var errContainerNotExist = errors.New("container does not exist") var errContainerExist = errors.New("container already exists") -// runtime states https://github.com/opencontainers/runtime-spec/blob/v1.0.2/runtime.md -const ( - // the container is being created (step 2 in the lifecycle) - stateCreating = "creating" - // the runtime has finished the create operation (after step 2 in the lifecycle), - // and the container process has neither exited nor executed the user-specified program - stateCreated = "created" - // the container process has executed the user-specified program - // but has not exited (after step 5 in the lifecycle) - stateRunning = "running" - // the container process has exited (step 7 in the lifecycle) - stateStopped = "stopped" - - // crio-lxc-init is started but blocking at the syncfifo - envStateCreated = "CRIO_LXC_STATE=" + stateCreated -) - type crioLXC struct { Container *lxc.Container @@ -357,30 +344,31 @@ func (c *crioLXC) isContainerStopped() bool { // The init process environment contains #envStateCreated if the the container // is created, but not yet running/started. // This requires the proc filesystem to be mounted on the host. -func (c *crioLXC) getContainerState() (int, string, error) { +func (c *crioLXC) getContainerState() (int, specs.ContainerState) { if c.isContainerStopped() { - return 0, stateStopped, nil + return 0, specs.StateStopped } pid := c.Container.InitPid() if pid < 0 { - return 0, stateCreating, nil + return 0, specs.StateCreating } envFile := fmt.Sprintf("/proc/%d/environ", pid) // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { - return 0, stateStopped, errors.Wrapf(err, "failed to read init process environment %s", envFile) + // container has died + return 0, specs.StateStopped } environ := strings.Split(string(data), "\000") for _, env := range environ { if env == envStateCreated { - return pid, stateCreated, nil + return pid, specs.StateCreated } } - return pid, stateRunning, nil + return pid, specs.StateRunning } func (c *crioLXC) deleteContainer() error { diff --git a/cmd/specs/specs.go b/cmd/specs/specs.go new file mode 100644 index 00000000..9f720457 --- /dev/null +++ b/cmd/specs/specs.go @@ -0,0 +1,22 @@ +package specs + +// Copy of ContainerState type from github.com/opencontainers/runtime-spec. +// Can be removed once next OCI spec is released. + +// ContainerState represents the state of a container. +type ContainerState string + +const ( + // StateCreating indicates that the container is being created + StateCreating ContainerState = "creating" + + // StateCreated indicates that the runtime has finished the create operation + StateCreated ContainerState = "created" + + // StateRunning indicates that the container process has executed the + // user-specified program but has not exited + StateRunning ContainerState = "running" + + // StateStopped indicates that the container process has exited + StateStopped ContainerState = "stopped" +) diff --git a/cmd/state.go b/cmd/state.go index 5ddf914e..90a6678c 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -45,19 +45,15 @@ func doState(ctx *cli.Context) error { } s := specs.State{ - Version: specs.Version, - ID: clxc.Container.Name(), - Bundle: bundlePath, - Pid: pid, + Version: specs.Version, + ID: clxc.Container.Name(), + Bundle: bundlePath, + Pid: pid, + Annotations: spec.Annotations, } - if spec.Annotations != nil { - s.Annotations = spec.Annotations - } - - // FIXME do not return the init pid, but the container process PID instead ... - _, status, err := clxc.getContainerState() - s.Status = status + _, state := clxc.getContainerState() + s.Status = string(state) log.Info().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") From 3e594d16291fe16e02f5fcf0ae0a02687569bf28 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 20 Nov 2020 22:54:51 +0100 Subject: [PATCH 060/373] Move executable check to utils. Add filesystem check for /proc and /sys/fs/cgroup Signed-off-by: Ruben Jenster --- cmd/create.go | 22 ++++++++++------------ cmd/utils.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index a1c8fe5f..0c6e4e17 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -54,14 +54,6 @@ var createCmd = cli.Command{ }, } -func checkAccess(externalCmds ...string) error { - for _, cmd := range externalCmds { - if err := unix.Access(cmd, unix.X_OK); err != nil { - return errors.Wrapf(err, "failed to access cmd %s", cmd) - } - } - return nil -} func doCreate(ctx *cli.Context) error { err := doCreateInternal(ctx) if err != nil || clxc.RuntimeHookRunAlways { @@ -71,14 +63,20 @@ func doCreate(ctx *cli.Context) error { } func doCreateInternal(ctx *cli.Context) error { - err := checkAccess(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) + err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return err } - // minimal lxc version is 3.1 https://discuss.linuxcontainers.org/t/lxc-3-1-has-been-released/3527 - if !lxc.VersionAtLeast(3, 1, 0) { - return fmt.Errorf("LXC runtime version > 3.1.0 required, but was %s", lxc.Version()) + if err := isFilesystem("/proc", "proc"); err != nil { + return err + } + if err := isFilesystem("/sys/fs/cgroup", "cgroup2"); err != nil { + return err + } + // TODO test this version + if !lxc.VersionAtLeast(4, 0, 5) { + return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } err = clxc.loadContainer() diff --git a/cmd/utils.go b/cmd/utils.go index 5f3f0b70..1e45b27f 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -2,13 +2,18 @@ package main import ( "fmt" + "github.com/pkg/errors" "io/ioutil" "os" "path/filepath" "strconv" "strings" + + "golang.org/x/sys/unix" ) +const undefined = -1 + // createPidFile atomically creates a pid file for the given pid at the given path func createPidFile(path string, pid int) error { tmpDir := filepath.Dir(path) @@ -39,3 +44,41 @@ func readPidFile(path string) (int, error) { s := strings.TrimSpace(string(data)) return strconv.Atoi(s) } + +func canExecute(cmds ...string) error { + for _, c := range cmds { + if err := unix.Access(c, unix.X_OK); err != nil { + return errors.Wrapf(err, "failed to access cmd %s", c) + } + } + return nil +} + +func filesystemName(fsName string) int64 { + switch fsName { + case "proc", "procfs": + return unix.PROC_SUPER_MAGIC + case "cgroup2", "cgroup2fs": + return unix.CGROUP2_SUPER_MAGIC + default: + return undefined + } +} + +// TODO check whether dir is the filsystem root (use /proc/mounts) +func isFilesystem(dir string, fsName string) error { + fsType := filesystemName(fsName) + if fsType == undefined { + return fmt.Errorf("undefined filesystem %q", fsName) + } + + var stat unix.Statfs_t + err := unix.Statfs(dir, &stat) + if err != nil { + return errors.Wrapf(err, "fstat failed for directory %s", dir) + } + if stat.Type != fsType { + return fmt.Errorf("%s is not on %q filesystem", dir, fsName) + } + return nil +} From d69151ea560d4772d745932a75a28206396897d8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 21 Nov 2020 09:13:51 +0100 Subject: [PATCH 061/373] Move ContainerState back to main package. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 33 +++++++++++++++++++++++++-------- cmd/specs/specs.go | 22 ---------------------- 2 files changed, 25 insertions(+), 30 deletions(-) delete mode 100644 cmd/specs/specs.go diff --git a/cmd/clxc.go b/cmd/clxc.go index ddccbfd1..ac1a871d 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -13,7 +13,6 @@ import ( "strings" "time" - "github.com/lxc/crio-lxc/cmd/specs" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" ) @@ -26,7 +25,25 @@ const ( defaultLogLevel = zerolog.WarnLevel // crio-lxc-init is started but blocking at the syncfifo - envStateCreated = "CRIO_LXC_STATE=" + string(specs.StateCreated) + envStateCreated = "CRIO_LXC_STATE=" + string(StateCreated) +) + +// ContainerState represents the state of a container. +type ContainerState string + +const ( + // StateCreating indicates that the container is being created + StateCreating ContainerState = "creating" + + // StateCreated indicates that the runtime has finished the create operation + StateCreated ContainerState = "created" + + // StateRunning indicates that the container process has executed the + // user-specified program but has not exited + StateRunning ContainerState = "running" + + // StateStopped indicates that the container process has exited + StateStopped ContainerState = "stopped" ) // The singelton that wraps the lxc.Container @@ -344,14 +361,14 @@ func (c *crioLXC) isContainerStopped() bool { // The init process environment contains #envStateCreated if the the container // is created, but not yet running/started. // This requires the proc filesystem to be mounted on the host. -func (c *crioLXC) getContainerState() (int, specs.ContainerState) { +func (c *crioLXC) getContainerState() (int, ContainerState) { if c.isContainerStopped() { - return 0, specs.StateStopped + return 0, StateStopped } pid := c.Container.InitPid() if pid < 0 { - return 0, specs.StateCreating + return 0, StateCreating } envFile := fmt.Sprintf("/proc/%d/environ", pid) @@ -359,16 +376,16 @@ func (c *crioLXC) getContainerState() (int, specs.ContainerState) { data, err := ioutil.ReadFile(envFile) if err != nil { // container has died - return 0, specs.StateStopped + return 0, StateStopped } environ := strings.Split(string(data), "\000") for _, env := range environ { if env == envStateCreated { - return pid, specs.StateCreated + return pid, StateCreated } } - return pid, specs.StateRunning + return pid, StateRunning } func (c *crioLXC) deleteContainer() error { diff --git a/cmd/specs/specs.go b/cmd/specs/specs.go deleted file mode 100644 index 9f720457..00000000 --- a/cmd/specs/specs.go +++ /dev/null @@ -1,22 +0,0 @@ -package specs - -// Copy of ContainerState type from github.com/opencontainers/runtime-spec. -// Can be removed once next OCI spec is released. - -// ContainerState represents the state of a container. -type ContainerState string - -const ( - // StateCreating indicates that the container is being created - StateCreating ContainerState = "creating" - - // StateCreated indicates that the runtime has finished the create operation - StateCreated ContainerState = "created" - - // StateRunning indicates that the container process has executed the - // user-specified program but has not exited - StateRunning ContainerState = "running" - - // StateStopped indicates that the container process has exited - StateStopped ContainerState = "stopped" -) From a842e3147831d0313fb56ce57d125b0874daa7de Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 21 Nov 2020 10:16:43 +0100 Subject: [PATCH 062/373] Save bundle state to container runtime directory. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++----- cmd/create.go | 12 +-------- cmd/kill.go | 6 +---- cmd/state.go | 17 ++++-------- 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index ac1a871d..10451614 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/json" "fmt" "github.com/pkg/errors" "io/ioutil" @@ -13,6 +14,8 @@ import ( "strings" "time" + "github.com/lxc/crio-lxc/cmd/internal" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" ) @@ -82,14 +85,20 @@ type crioLXC struct { CgroupDevices bool // create flags - BundlePath string - SpecPath string // BundlePath + "/config.json" - PidFile string - ConsoleSocket string ConsoleSocketTimeout time.Duration // start flags StartTimeout time.Duration + + bundleConfig +} + +type bundleConfig struct { + BundlePath string + SpecPath string // BundlePath + "/config.json" + PidFile string + ConsoleSocket string + //CgroupPath string } var version string @@ -107,6 +116,18 @@ func (c *crioLXC) configFilePath() string { return c.runtimePath("config") } +func (c *crioLXC) readPidFile() (int, error) { + return readPidFile(c.PidFile) +} + +func (c *crioLXC) createPidFile(pid int) error { + return createPidFile(c.PidFile, pid) +} + +func (c *crioLXC) readSpec() (*specs.Spec, error) { + return internal.ReadSpec(clxc.runtimePath(internal.InitSpec)) +} + // loadContainer checks for the existence of the lxc config file. // It returns an error if the config file does not exist. func (c *crioLXC) loadContainer() error { @@ -126,9 +147,13 @@ func (c *crioLXC) loadContainer() error { if err != nil { return errors.Wrap(err, "failed to load config file") } - c.Container = container - return c.setContainerLogLevel() + + if err := c.setContainerLogLevel(); err != nil { + return err + } + + return c.readBundleConfig() } // createContainer creates a new container. @@ -154,6 +179,12 @@ func (c *crioLXC) createContainer() error { return errors.Wrap(err, "failed to close empty config file") } + c.SpecPath = filepath.Join(clxc.BundlePath, "config.json") + + if err := c.writeBundleConfig(); err != nil { + return err + } + container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { return err @@ -162,6 +193,35 @@ func (c *crioLXC) createContainer() error { return c.setContainerLogLevel() } +func (c *crioLXC) readBundleConfig() error { + p := c.runtimePath("bundle.json") + data, err := ioutil.ReadFile(p) + if err != nil { + return errors.Wrapf(err, "failed to read bundle config file %s", p) + } + err = json.Unmarshal(data, &c.bundleConfig) + if err != nil { + return errors.Wrap(err, "failed to unmarshal bundle config") + } + return nil +} + +func (c *crioLXC) writeBundleConfig() error { + p := c.runtimePath("bundle.json") + f, err := os.OpenFile(p, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + if err != nil { + return errors.Wrapf(err, "failed to create bundle config file %s", p) + } + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + err = enc.Encode(c.bundleConfig) + if err != nil { + f.Close() + return errors.Wrap(err, "failed to marshal bundle config") + } + return f.Close() +} + // saveConfig creates and atomically enables the lxc config file. // It must be called after #createContainer and only once. // Any config changes via clxc.setConfigItem must be done diff --git a/cmd/create.go b/cmd/create.go index 0c6e4e17..63f33700 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -79,21 +79,11 @@ func doCreateInternal(ctx *cli.Context) error { return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } - err = clxc.loadContainer() - if err == nil { - return fmt.Errorf("container already exists") - } - err = clxc.createContainer() if err != nil { return errors.Wrap(err, "failed to create container") } - if err := clxc.setConfigItem("lxc.log.file", clxc.LogFilePath); err != nil { - return err - } - - clxc.SpecPath = filepath.Join(clxc.BundlePath, "config.json") spec, err := internal.ReadSpec(clxc.SpecPath) if err != nil { return errors.Wrap(err, "couldn't load bundle spec") @@ -109,7 +99,7 @@ func doCreateInternal(ctx *cli.Context) error { return errors.Wrap(err, "failed to start container process") } log.Info().Int("pid", startCmd.Process.Pid).Msg("started container process") - return createPidFile(clxc.PidFile, startCmd.Process.Pid) + return clxc.createPidFile(startCmd.Process.Pid) } diff --git a/cmd/kill.go b/cmd/kill.go index e799f4b0..f81c4391 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -5,7 +5,6 @@ package main import ( "fmt" "os" - "path/filepath" "strconv" "strings" @@ -102,10 +101,7 @@ func doKill(ctx *cli.Context) error { return errors.Wrap(err, "failed to load container") } - bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") - pidFilePath := filepath.Join(bundlePath, "pidfile") - - pid, err := readPidFile(pidFilePath) + pid, err := clxc.readPidFile() if err != nil && !os.IsNotExist(err) { return errors.Wrapf(err, "failed to load pidfile") } diff --git a/cmd/state.go b/cmd/state.go index 90a6678c..84afac5f 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -4,9 +4,7 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" - "github.com/lxc/crio-lxc/cmd/internal" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/urfave/cli/v2" @@ -29,25 +27,20 @@ func doState(ctx *cli.Context) error { return errors.Wrapf(err, "failed to load container") } - // TODO save BundlePath to init spec - // TODO create a symlink to the pidfile and config in the runtime path - bundlePath := filepath.Join("/var/run/containers/storage/overlay-containers/", clxc.Container.Name(), "userdata") - pidFilePath := filepath.Join(bundlePath, "pidfile") - - pid, err := readPidFile(pidFilePath) - if err != nil && !os.IsNotExist(err) { + pid, err := clxc.readPidFile() + if err != nil { return errors.Wrapf(err, "failed to load pidfile") } - spec, err := internal.ReadSpec(filepath.Join(bundlePath, "config.json")) + spec, err := clxc.readSpec() if err != nil { - return errors.Wrapf(err, "failed to load spec from %s", bundlePath) + return err } s := specs.State{ Version: specs.Version, ID: clxc.Container.Name(), - Bundle: bundlePath, + Bundle: clxc.BundlePath, Pid: pid, Annotations: spec.Annotations, } From 376ab1b30c94014a3b3682d0c1446cafc710f60f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 23 Nov 2020 21:00:31 +0100 Subject: [PATCH 063/373] delete: Do not return error if container does not exist. Signed-off-by: Ruben Jenster --- TODO.md | 17 +++++++++++++++++ cmd/clxc.go | 13 ++++++++----- cmd/delete.go | 6 +++++- 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..20e59adb --- /dev/null +++ b/TODO.md @@ -0,0 +1,17 @@ +--> move to separate file +## TODO + +### OCI runtime spec + +* Apply Cgroup resource limits + +* + +### Infrastructure + +* CI + + +### +* Command to generate environment file. + diff --git a/cmd/clxc.go b/cmd/clxc.go index 10451614..61ba6d80 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -448,9 +448,14 @@ func (c *crioLXC) getContainerState() (int, ContainerState) { return pid, StateRunning } -func (c *crioLXC) deleteContainer() error { - if err := c.Container.Destroy(); err != nil { - return errors.Wrap(err, "failed to destroy container") +func (c *crioLXC) destroy() error { + if c.Container != nil { + if err := c.Container.Destroy(); err != nil { + return errors.Wrap(err, "failed to destroy container") + } + // required because tryRemoveCgroups retrieves the config item from the container config + // --> store the cgroup in the runtime config + //c.tryRemoveCgroups() } // "Note that resources associated with the container, @@ -458,8 +463,6 @@ func (c *crioLXC) deleteContainer() error { // TODO - because we set rootfs.managed=0, Destroy() doesn't // delete the /var/lib/lxc/$containerID/config file: - c.tryRemoveCgroups() - return os.RemoveAll(c.runtimePath()) } diff --git a/cmd/delete.go b/cmd/delete.go index fc7669e0..d6183399 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -24,7 +24,11 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { + err := clxc.loadContainer() + if err == errContainerNotExist { + return clxc.destroy() + } if err != nil { return err } @@ -40,5 +44,5 @@ func doDelete(ctx *cli.Context) error { return errors.Wrap(err, "failed to stop container") } } - return clxc.deleteContainer() + return clxc.destroy() } From 99c80890c6af08e498cbe4305010af0a1d389b76 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 24 Nov 2020 14:16:35 +0100 Subject: [PATCH 064/373] init: Replace go with c implementation. Signed-off-by: Ruben Jenster --- .gitignore | 2 + Makefile | 12 ++- README.md | 3 + cmd/cgroup.go | 83 ++-------------- cmd/cgroup_test.go | 2 +- cmd/clxc.go | 169 +++++++++++++++++++++++--------- cmd/create.go | 171 ++++++++++++++++++++++++++------ cmd/delete.go | 5 +- cmd/exec.go | 3 +- cmd/init/crio-lxc-init.c | 205 +++++++++++++++++++++++++++++++++++++++ cmd/init/init.go | 59 ----------- cmd/internal/internal.go | 94 ------------------ cmd/main.go | 4 +- cmd/start.go | 42 +++++++- cmd/state.go | 5 +- cmd/utils.go | 13 --- 16 files changed, 538 insertions(+), 334 deletions(-) create mode 100644 cmd/init/crio-lxc-init.c delete mode 100644 cmd/init/init.go delete mode 100644 cmd/internal/internal.go diff --git a/.gitignore b/.gitignore index 750bf499..b5431de5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ oci/ roots/ .stacker/ .keeptempdirs +cmd/container-hook/musl-1.2.1.tar.gz +cmd/container-hook/musl-1.2.1/ diff --git a/Makefile b/Makefile index 5e0be546..d0ff237b 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ PREFIX ?= /usr/local PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH LDFLAGS=-X main.version=$(COMMIT) +CC ?= cc all: fmt $(BINS) @@ -21,15 +22,16 @@ crio-lxc: $(GO_SRC) Makefile go.mod go build -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c - cc -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) $? -o $@ + $(CC) -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? -crio-lxc-init: $(GO_SRC) Makefile go.mod - CGO_ENABLED=0 go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/init +crio-lxc-init: cmd/init/crio-lxc-init.c + /usr/local/musl/bin/musl-gcc -Wpedantic -Wall -static -g -o $@ $? + #musl-gcc -g3 -Wall -static $? -o $@ # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null -crio-lxc-container-hook: $(GO_SRC) Makefile go.mod - go build -ldflags '$(LDFLAGS) -extldflags "-static"' -o $@ ./cmd/container-hook +crio-lxc-container-hook: cmd/container-hook/hook.c + musl-gcc -DDEBUG -Wall -Wpedantic $? -o $@ # make test TEST=basic will run only the basic test. .PHONY: check diff --git a/README.md b/README.md index eb1bc1ae..31e203ee 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S * `runtime` the crio-lxc binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) * `container process` the process that starts and runs the container using liblxc (crio-lxc-start) +* `container config` the LXC config file +* `bundle config` the crio-lxc container state (bundle path, pidfile ....) +* `runtime spec` the OCI runtime spec from the bundle ## Bugs diff --git a/cmd/cgroup.go b/cmd/cgroup.go index fd2da09c..fb8a7fdd 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -17,15 +17,6 @@ import ( // TODO New spec will contain a property Unified for cgroupv2 properties // https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#unified func configureCgroup(spec *specs.Spec) error { - if err := configureCgroupPath(spec.Linux); err != nil { - return errors.Wrap(err, "failed to configure cgroup path") - } - - // lxc.cgroup.root and lxc.cgroup.relative must not be set for cgroup v2 - if err := clxc.setConfigItem("lxc.cgroup.relative", "0"); err != nil { - return err - } - if devices := spec.Linux.Resources.Devices; devices != nil { if err := configureDeviceController(spec); err != nil { return err @@ -61,42 +52,6 @@ func configureCgroup(spec *specs.Spec) error { return nil } -func configureCgroupPath(linux *specs.Linux) error { - if linux.CgroupsPath == "" { - return fmt.Errorf("empty cgroups path in spec") - } - if !clxc.SystemdCgroup { - return clxc.setConfigItem("lxc.cgroup.dir", linux.CgroupsPath) - } - cgPath := parseSystemdCgroupPath(linux.CgroupsPath) - - /* - if err := enableCgroupControllers(cgPath); err != nil { - return errors.Wrapf(err, "cgroup path error") - } - */ - // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb - // checking for on of the config items shuld be enough, because they were introduced together ... - if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { - if err := clxc.setConfigItem("lxc.cgroup.dir.container", cgPath.String()); err != nil { - return err - } - if err := clxc.setConfigItem("lxc.cgroup.dir.monitor", filepath.Join(clxc.MonitorCgroup, clxc.Container.Name()+".scope")); err != nil { - return err - } - } else { - if err := clxc.setConfigItem("lxc.cgroup.dir", cgPath.String()); err != nil { - return err - } - } - if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := clxc.setConfigItem("lxc.cgroup.dir.monitor.pivot", clxc.MonitorCgroup); err != nil { - return err - } - } - return nil -} - func configureDeviceController(spec *specs.Spec) error { devicesAllow := "lxc.cgroup2.devices.allow" devicesDeny := "lxc.cgroup2.devices.deny" @@ -208,45 +163,25 @@ func configureCPUController(linux *specs.LinuxCPU) error { // https://kubernetes.io/docs/setup/production-environment/container-runtimes/ // kubelet --cgroup-driver systemd --cgroups-per-qos -type cgroupPath struct { - Slices []string - Scope string -} - -func (cg cgroupPath) String() string { - return filepath.Join(append(cg.Slices, cg.Scope)...) -} - -func (cg cgroupPath) SlicePath() string { - return filepath.Join("/sys/fs/cgroup", filepath.Join(cg.Slices...)) -} - -func (cg cgroupPath) ScopePath() string { - return filepath.Join(cg.SlicePath(), cg.Scope) -} - // kubernetes creates the cgroup hierarchy which can be changed by serveral cgroup related flags. // kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod87f8bc68_7c18_4a1d_af9f_54eff815f688.slice // kubepods-burstable-pod9da3b2a14682e1fb23be3c2492753207.slice:crio:fe018d944f87b227b3b7f86226962639020e99eac8991463bf7126ef8e929589 // https://github.com/cri-o/cri-o/issues/2632 -func parseSystemdCgroupPath(s string) (cg cgroupPath) { - if s == "" { - return cg - } +func parseSystemdCgroupPath(s string) string { parts := strings.Split(s, ":") - slices := parts[0] - for i, r := range slices { + var cgPath []string + + for i, r := range parts[0] { if r == '-' && i > 0 { - slice := slices[0:i] + ".slice" - cg.Slices = append(cg.Slices, slice) + cgPath = append(cgPath, parts[0][0:i]+".slice") } } - cg.Slices = append(cg.Slices, slices) - if len(parts) > 0 { - cg.Scope = strings.Join(parts[1:], "-") + ".scope" + cgPath = append(cgPath, parts[0]) + if len(parts) > 1 { + cgPath = append(cgPath, strings.Join(parts[1:], "-")+".scope") } - return cg + return filepath.Join(cgPath...) } type cgroupInfo struct { diff --git a/cmd/cgroup_test.go b/cmd/cgroup_test.go index 8aa70262..8a5f6f0e 100644 --- a/cmd/cgroup_test.go +++ b/cmd/cgroup_test.go @@ -8,5 +8,5 @@ import ( func TestParseSystemCgroupPath(t *testing.T) { s := "kubepods-burstable-123.slice:crio:ABC" cg := parseSystemdCgroupPath(s) - require.Equal(t, "kubepods.slice/kubepods-burstable.slice/kubepods-burstable-123.slice/crio-ABC.scope", cg.String()) + require.Equal(t, "kubepods.slice/kubepods-burstable.slice/kubepods-burstable-123.slice/crio-ABC.scope", cg) } diff --git a/cmd/clxc.go b/cmd/clxc.go index 61ba6d80..4dddd772 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "github.com/pkg/errors" + "golang.org/x/sys/unix" "io/ioutil" "os" "os/exec" @@ -14,7 +15,6 @@ import ( "strings" "time" - "github.com/lxc/crio-lxc/cmd/internal" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" @@ -27,8 +27,12 @@ const ( defaultContainerLogLevel = lxc.WARN defaultLogLevel = zerolog.WarnLevel - // crio-lxc-init is started but blocking at the syncfifo - envStateCreated = "CRIO_LXC_STATE=" + string(StateCreated) + // ConfigDir is the path to the crio-lxc resources relative to the container rootfs. + configDir = "/.crio-lxc" + // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. + syncFifoPath = configDir + "/syncfifo" + // InitCmd is the path where the init binary is bind mounted. + initCmd = configDir + "/init" ) // ContainerState represents the state of a container. @@ -69,7 +73,6 @@ type crioLXC struct { LogLevel string ContainerLogLevel string SystemdCgroup bool - MonitorCgroup string StartCommand string InitCommand string @@ -98,7 +101,9 @@ type bundleConfig struct { SpecPath string // BundlePath + "/config.json" PidFile string ConsoleSocket string - //CgroupPath string + MonitorCgroup string + // values derived from spec + CgroupsPath string } var version string @@ -111,21 +116,56 @@ func versionString() string { func (c *crioLXC) runtimePath(subPath ...string) string { return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) } +func (c *crioLXC) bundlePath(subPath ...string) string { + return filepath.Join(c.BundlePath, filepath.Join(subPath...)) +} func (c *crioLXC) configFilePath() string { return c.runtimePath("config") } func (c *crioLXC) readPidFile() (int, error) { - return readPidFile(c.PidFile) + // #nosec + data, err := ioutil.ReadFile(c.PidFile) + if err != nil { + return 0, err + } + s := strings.TrimSpace(string(data)) + return strconv.Atoi(s) } func (c *crioLXC) createPidFile(pid int) error { return createPidFile(c.PidFile, pid) } +// ReadSpec deserializes the JSON encoded runtime spec from the given path. func (c *crioLXC) readSpec() (*specs.Spec, error) { - return internal.ReadSpec(clxc.runtimePath(internal.InitSpec)) + // #nosec + // FIXME set this once + c.SpecPath = c.bundlePath("config.json") + + specFile, err := os.Open(c.SpecPath) + if err != nil { + return nil, err + } + // #nosec + defer specFile.Close() + spec := &specs.Spec{} + err = json.NewDecoder(specFile).Decode(spec) + if err != nil { + return nil, err + } + + if spec.Linux.CgroupsPath == "" { + return nil, fmt.Errorf("empty cgroups path in spec") + } + if c.SystemdCgroup { + c.CgroupsPath = parseSystemdCgroupPath(spec.Linux.CgroupsPath) + } else { + c.CgroupsPath = spec.Linux.CgroupsPath + } + + return spec, nil } // loadContainer checks for the existence of the lxc config file. @@ -159,7 +199,6 @@ func (c *crioLXC) loadContainer() error { // createContainer creates a new container. // It must only be called once during the lifecycle of a container. func (c *crioLXC) createContainer() error { - // avoid creating a container if _, err := os.Stat(c.configFilePath()); err == nil { return errContainerExist } @@ -179,7 +218,7 @@ func (c *crioLXC) createContainer() error { return errors.Wrap(err, "failed to close empty config file") } - c.SpecPath = filepath.Join(clxc.BundlePath, "config.json") + c.MonitorCgroup = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") if err := c.writeBundleConfig(); err != nil { return err @@ -193,6 +232,33 @@ func (c *crioLXC) createContainer() error { return c.setContainerLogLevel() } +func (c *crioLXC) configureCgroupPath() error { + if err := clxc.setConfigItem("lxc.cgroup.relative", "0"); err != nil { + return err + } + + // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb + // checking for on of the config items shuld be enough, because they were introduced together ... + if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { + if err := c.setConfigItem("lxc.cgroup.dir.container", c.CgroupsPath); err != nil { + return err + } + if err := c.setConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroup); err != nil { + return err + } + } else { + if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupsPath); err != nil { + return err + } + } + if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { + return err + } + } + return nil +} + func (c *crioLXC) readBundleConfig() error { p := c.runtimePath("bundle.json") data, err := ioutil.ReadFile(p) @@ -287,7 +353,7 @@ func (c *crioLXC) getConfigItem(key string) string { func (c *crioLXC) setConfigItem(key, value string) error { err := c.Container.SetConfigItem(key, value) if err != nil { - return errors.Wrap(err, "failed to set config item '%s=%s'") + return errors.Wrapf(err, "failed to set config item '%s=%s'", key, value) } log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") return nil @@ -421,31 +487,55 @@ func (c *crioLXC) isContainerStopped() bool { // The init process environment contains #envStateCreated if the the container // is created, but not yet running/started. // This requires the proc filesystem to be mounted on the host. -func (c *crioLXC) getContainerState() (int, ContainerState) { - if c.isContainerStopped() { - return 0, StateStopped - } - +func (c *crioLXC) getContainerState() (ContainerState, error) { + state := c.Container.State() + switch state { + case lxc.STOPPED: + return StateStopped, nil + case lxc.STARTING: + return StateCreating, nil + } + // RUNNING, STOPPING, ABORTING, FREEZING, FROZEN, THAWED: pid := c.Container.InitPid() if pid < 0 { - return 0, StateCreating + return StateCreating, nil } - envFile := fmt.Sprintf("/proc/%d/environ", pid) - // #nosec - data, err := ioutil.ReadFile(envFile) + commPath := fmt.Sprintf("/proc/%d/cmdline", pid) + cmdline, err := ioutil.ReadFile(commPath) if err != nil { - // container has died - return 0, StateStopped + // can not determine state, caller may try again + return StateStopped, err } - environ := strings.Split(string(data), "\000") - for _, env := range environ { - if env == envStateCreated { - return pid, StateCreated + // comm contains a trailing newline + initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) + if string(cmdline) == initCmdline { + //if strings.HasPrefix(c.ContainerID, strings.TrimSpace(string(comm))) { + return StateCreated, nil + } + + return StateRunning, nil +} + +func (c *crioLXC) killContainer(signum unix.Signal) error { + pid, err := c.readPidFile() + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "failed to load pidfile") + } + log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") + + // send signal to the monitor process if it still exist + // signals other than SIGTERM are forwarded from liblxc to the container int process + if err := unix.Kill(pid, 0); err == nil { + err := unix.Kill(pid, signum) + // container process has already died + if signum == unix.SIGKILL || signum == unix.SIGTERM { + return nil } + return err } - return pid, StateRunning + return nil } func (c *crioLXC) destroy() error { @@ -453,11 +543,11 @@ func (c *crioLXC) destroy() error { if err := c.Container.Destroy(); err != nil { return errors.Wrap(err, "failed to destroy container") } - // required because tryRemoveCgroups retrieves the config item from the container config - // --> store the cgroup in the runtime config - //c.tryRemoveCgroups() } + // cgroup directories must be removed if container process was killed with SIGKILL + c.tryRemoveCgroups() + // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." // TODO - because we set rootfs.managed=0, Destroy() doesn't @@ -467,21 +557,10 @@ func (c *crioLXC) destroy() error { } func (c *crioLXC) tryRemoveCgroups() { - configItems := []string{"lxc.cgroup.dir", "lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor"} - for _, item := range configItems { - dir := c.getConfigItem(item) - if dir == "" { - continue - } - err := deleteCgroup(dir) - if err != nil { - log.Warn().Err(err).Str("lxc.config", item).Msg("failed to remove cgroup scope") - continue - } - outerSlice := filepath.Dir(dir) - err = deleteCgroup(outerSlice) - if err != nil { - log.Debug().Err(err).Str("file", outerSlice).Msg("failed to remove cgroup slice") - } + if err := deleteCgroup(c.CgroupsPath); err != nil { + log.Warn().Err(err).Str("cgroup", c.CgroupsPath).Msg("failed to remove cgroup") + } + if err := deleteCgroup(c.MonitorCgroup); err != nil { + log.Warn().Err(err).Str("cgroup", c.MonitorCgroup).Msg("failed to remove monitor cgroup") } } diff --git a/cmd/create.go b/cmd/create.go index 63f33700..4c4b6c25 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -18,7 +18,6 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli/v2" - "github.com/lxc/crio-lxc/cmd/internal" lxc "gopkg.in/lxc/go-lxc.v2" ) @@ -79,28 +78,65 @@ func doCreateInternal(ctx *cli.Context) error { return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } - err = clxc.createContainer() + spec, err := clxc.readSpec() if err != nil { - return errors.Wrap(err, "failed to create container") + return errors.Wrap(err, "couldn't load bundle spec") } - spec, err := internal.ReadSpec(clxc.SpecPath) + err = clxc.createContainer() if err != nil { - return errors.Wrap(err, "couldn't load bundle spec") + return errors.Wrap(err, "failed to create container") } if err := configureContainer(spec); err != nil { return errors.Wrap(err, "failed to configure container") } + cmdFile, err := os.OpenFile(clxc.runtimePath("/.crio-lxc/cmdline.txt"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0640) + if err != nil { + return errors.Wrap(err, "failed to create the cmd file") + } + + for _, arg := range spec.Process.Args { + fmt.Fprintln(cmdFile, arg) + } + if err := cmdFile.Close(); err != nil { + return errors.Wrap(err, "failed to close cmd file") + } + + if err := writeEnviron(clxc.runtimePath("/.crio-lxc/environ"), spec.Process.Env); err != nil { + return err + } + // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) if err := runStartCmd(startCmd, spec); err != nil { return errors.Wrap(err, "failed to start container process") } - log.Info().Int("pid", startCmd.Process.Pid).Msg("started container process") + log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + return clxc.createPidFile(startCmd.Process.Pid) +} + +func writeEnviron(envFile string, env []string) error { + f, err := os.OpenFile(envFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0640) + if err != nil { + return err + } + for _, arg := range env { + _, err := f.WriteString(arg) + if err != nil { + f.Close() + return err + } + _, err = f.Write([]byte{'\000'}) + if err != nil { + f.Close() + return err + } + } + return f.Close() } func configureContainer(spec *specs.Spec) error { @@ -200,6 +236,10 @@ func configureContainer(spec *specs.Spec) error { return errors.Wrap(err, "failed to add default devices") } + if err := clxc.configureCgroupPath(); err != nil { + return errors.Wrap(err, "failed to configure cgroups path") + } + if err := configureCgroup(spec); err != nil { return errors.Wrap(err, "failed to configure cgroups") } @@ -247,24 +287,24 @@ func configureRootfs(spec *specs.Spec) error { } func configureInit(spec *specs.Spec) error { - err := os.MkdirAll(filepath.Join(spec.Root.Path, internal.ConfigDir), 0) + err := os.MkdirAll(filepath.Join(spec.Root.Path, configDir), 0) if err != nil { - return errors.Wrapf(err, "Failed creating %s in rootfs", internal.ConfigDir) + return errors.Wrapf(err, "Failed creating %s in rootfs", configDir) } // #nosec - err = os.MkdirAll(clxc.runtimePath(internal.ConfigDir), 0755) + err = os.MkdirAll(clxc.runtimePath(configDir), 0755) if err != nil { - return errors.Wrapf(err, "Failed creating %s in lxc container dir", internal.ConfigDir) + return errors.Wrapf(err, "Failed creating %s in lxc container dir", configDir) } // create named fifo in lxcpath and mount it into the container - if err := makeSyncFifo(clxc.runtimePath(internal.SyncFifoPath)); err != nil { + if err := makeSyncFifo(clxc.runtimePath(syncFifoPath)); err != nil { return errors.Wrapf(err, "failed to make sync fifo") } spec.Mounts = append(spec.Mounts, specs.Mount{ - Source: clxc.runtimePath(internal.ConfigDir), - Destination: strings.Trim(internal.ConfigDir, "/"), + Source: clxc.runtimePath(configDir), + Destination: strings.Trim(configDir, "/"), Type: "bind", Options: []string{"bind", "ro", "nodev", "nosuid"}, }) @@ -277,32 +317,19 @@ func configureInit(spec *specs.Spec) error { return err } - path := "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - for _, kv := range spec.Process.Env { - if strings.HasPrefix(kv, "PATH=") { - path = kv - } - } - if err := clxc.setConfigItem("lxc.environment", path); err != nil { - return err - } - if err := clxc.setConfigItem("lxc.environment", envStateCreated); err != nil { - return err - } - // create destination file for bind mount - initBin := clxc.runtimePath(internal.InitCmd) + initBin := clxc.runtimePath(initCmd) err = touchFile(initBin, 0) if err != nil { return errors.Wrapf(err, "failed to create %s", initBin) } spec.Mounts = append(spec.Mounts, specs.Mount{ Source: clxc.InitCommand, - Destination: internal.InitCmd, + Destination: initCmd, Type: "bind", Options: []string{"bind", "ro", "nosuid"}, }) - return clxc.setConfigItem("lxc.init.cmd", internal.InitCmd) + return clxc.setConfigItem("lxc.init.cmd", initCmd+" "+clxc.ContainerID) } func touchFile(filePath string, perm os.FileMode) error { @@ -433,6 +460,18 @@ func ensureDefaultDevices(spec *specs.Spec) error { return nil } +func setenv(env []string, key, val string, overwrite bool) []string { + for i, kv := range env { + if strings.HasPrefix(kv, key+"=") { + if overwrite { + env[i] = key + "=" + val + } + return env + } + } + return append(env, key+"="+val) +} + func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. @@ -440,6 +479,22 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { // This is required because environment variables defined by containers contain newlines and other tokens // that can not be handled properly within the lxc config file. cmd.Env = []string{} + /* + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = &unix.SysProcAttr{} + } + + //cmd.SysProcAttr.Noctty = true + sig, err := getParentDeathSignal() + if err != nil { + return err + } + cmd.SysProcAttr.Pdeathsig = sig + //cmd.SysProcAttr.Foreground = false + //cmd.SysProcAttr.Setsid = true + */ + + cmd.Dir = clxc.runtimePath() if clxc.ConsoleSocket != "" { if err := clxc.saveConfig(); err != nil { @@ -462,12 +517,66 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { return err } - if err := internal.WriteSpec(spec, clxc.runtimePath(internal.InitSpec)); err != nil { - return errors.Wrapf(err, "failed to write init spec") + if err := writeDevices(spec); err != nil { + return errors.Wrap(err, "failed to create devices.txt") } + + if err := writeMasked(spec); err != nil { + return errors.Wrap(err, "failed to create masked.txt file") + } + return cmd.Start() } +func writeDevices(spec *specs.Spec) error { + if spec.Linux.Devices == nil { + return nil + } + f, err := os.OpenFile(clxc.runtimePath("devices.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + if err != nil { + return err + } + for _, d := range spec.Linux.Devices { + uid := spec.Process.User.UID // FIXME use 0 instead ? + if d.UID != nil { + uid = *d.UID + } + gid := spec.Process.User.GID // FIXME use 0 instead ? + if d.GID == nil { + gid = *d.GID + } + mode := os.FileMode(0600) + if d.FileMode != nil { + mode = *d.FileMode + } + _, err = fmt.Fprintf(f, "%s %s %d %d %o %d:%d\n", d.Path, d.Type, d.Major, d.Minor, mode, uid, gid) + if err != nil { + f.Close() + return err + } + } + return f.Close() +} + +func writeMasked(spec *specs.Spec) error { + // #nosec + if spec.Linux.MaskedPaths == nil { + return nil + } + f, err := os.OpenFile(clxc.runtimePath("masked.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + if err != nil { + return err + } + for _, p := range spec.Linux.MaskedPaths { + _, err = fmt.Fprintln(f, p) + if err != nil { + f.Close() + return err + } + } + return f.Close() +} + func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { addr, err := net.ResolveUnixAddr("unix", consoleSocket) if err != nil { diff --git a/cmd/delete.go b/cmd/delete.go index d6183399..1f6be6fe 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -5,6 +5,7 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli/v2" + "golang.org/x/sys/unix" ) var deleteCmd = cli.Command{ @@ -40,8 +41,8 @@ func doDelete(ctx *cli.Context) error { if !force { return fmt.Errorf("container is not not stopped (current state %s)", clxc.Container.State()) } - if err := clxc.Container.Stop(); err != nil { - return errors.Wrap(err, "failed to stop container") + if err := clxc.killContainer(unix.SIGKILL); err != nil { + return errors.Wrap(err, "failed to kill container") } } return clxc.destroy() diff --git a/cmd/exec.go b/cmd/exec.go index 15448be5..f472709e 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -10,7 +10,6 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli/v2" - "github.com/lxc/crio-lxc/cmd/internal" lxc "gopkg.in/lxc/go-lxc.v2" ) @@ -88,7 +87,7 @@ func doExec(ctx *cli.Context) error { } // Load container spec to get the list of supported namespaces. - spec, err := internal.ReadSpec(clxc.runtimePath(internal.InitSpec)) + spec, err := clxc.readSpec() if err != nil { return errors.Wrap(err, "failed to read container runtime spec") } diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c new file mode 100644 index 00000000..b8b0aac5 --- /dev/null +++ b/cmd/init/crio-lxc-init.c @@ -0,0 +1,205 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PREFIX +#define PREFIX "/.crio-lxc/" +#endif + +#define runtime_path(NAME) PREFIX NAME + +const char* syncfifo = runtime_path("syncfifo"); +const char* cmdline_path = runtime_path("cmdline.txt"); +const char* environ_path = runtime_path("environ"); + +int writefifo(const char* fifo, const char*msg) { + int fd; + +#ifdef DEBUG + printf("writing fifo %s\n", fifo); +#endif + + // Open FIFO for write only + fd = open(fifo, O_WRONLY | O_CLOEXEC); + if (fd == -1) + return -1; + + if (write(fd, msg, strlen(msg)) == -1) + return -1; + + return close(fd); +} + +/* reads up to maxlines-1 lines from path into lines */ +int readlines(const char* path, char *buf, int buflen, char **lines, int maxlines) { + FILE *f; + char *line; + int n; + +#ifdef DEBUG + printf("reading lines from %s buflen:%d maxlines:%d\n", path, buflen, maxlines); +#endif + + // FIXME open file with O_CLOEXEC + + f = fopen(path, "r"); + if(f == NULL) + return -1; + + errno = 0; + for(n = 0; n < maxlines-1; n++) { + // https://pubs.opengroup.org/onlinepubs/009696699/functions/fgets.html + line = fgets(buf, buflen, f); + if (line == NULL) + break; + // line gets truncated if it is longer than buflen ? + lines[n] = strndup(line, strlen(line)-1); + } + if (errno != 0) + return -1; + + if (fclose(f) != 0) + return -1; + + lines[n] = (char *) NULL; + return n; +} + + +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 +int load_environment(const char* path, char *buf, int buflen) { + FILE *f; + +#ifdef DEBUG + printf("reading env from %s buflen:%d\n", path, buflen); +#endif + + f = fopen(path, "r"); + if(f == NULL) + return -1; + + char c; + + while(c != EOF) { + char *value = NULL; + + for(int i = 0; i < buflen; i++) { + c = getc(f); + if (c == EOF) { + // we should have receive a '\0' before + buf[i] = '\0'; + break; + } + + buf[i] = c; + if (c == '\0') + break; + + // buffer is full but we did neither receive '\0' nor EOF before + if (i == buflen-1) { + //errno = E2BIG; + errno = 31; + goto out; + } + + // terminate enviornment key + // the checks above ensure that we are not at the end of the buffer here + if (value == NULL && c == '=') { + buf[i] = '\0'; + value = buf + ( i+1 ); + } + } + if (errno != 0) { + errno = 32; + goto out; + } + + // 'foo=' + if (value == NULL) { + errno = 33; + errno = EINVAL; + goto out; + } +#ifdef DEBUG + printf("setenv %s\n", buf); +#endif + if (setenv(buf, value, 1) == -1) + goto out; + } + +out: + fclose(f); + return (errno != 0) ? errno : 0; +} + +int sethome() { + struct passwd *pw; + + if (getenv("HOME") != NULL) { + return 0; + } + pw = getpwuid(geteuid()); + if (pw != NULL) { + if (pw->pw_dir != NULL) + return setenv("HOME", pw->pw_dir, 0); + } + // This is best effort so we ignore the errno set by getpwuid. + if (errno != 0) + errno = 0; + return setenv("HOME", "/", 0); +} + +int main(int argc, char** argv) +{ + // Buffer for reading arguments and environment variables. + // There is not a limit per environment variable, but we limit it to 1MiB here + // https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes + // For arguments "Additionally, the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF." + char buf[1024*1024]; + // see 'man 2 execve' 'Limits on size of arguments and environment' + // ... ARG_MAX constant (either defined in or available at run time using the call sysconf(_SC_ARG_MAX)) + char *args[256]; // > _POSIX_ARG_MAX+1 + + const char* cid; + + if (argc != 2) { + fprintf(stderr, "invalid number of arguments (expected 2 was %d) usage: %s \n", argc, argv[0]); + exit(1); + } + cid = argv[1]; + + if (readlines(cmdline_path, buf, sizeof(buf), args, sizeof(args)) == -1){ + perror("failed to read cmdline file"); + exit(2); + } + + // environment is already cleared by liblxc + //environ = NULL; + if (load_environment(environ_path, buf, sizeof(buf)) == -1){ + perror("failed to read environment file"); + if (errno == 0) + exit(3); + else + exit(errno); + } + + if (sethome() == -1) { + perror("failed to set HOME"); + exit(4); + } + + if (writefifo(syncfifo, cid) == -1) { + perror("failed to write syncfifo"); + exit(5); + } + + execvp(args[0],args); +} diff --git a/cmd/init/init.go b/cmd/init/init.go deleted file mode 100644 index a8189f00..00000000 --- a/cmd/init/init.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "github.com/lxc/crio-lxc/cmd/internal" - "golang.org/x/sys/unix" - "os/exec" - "os/user" - "strings" -) - -func fail(err error, step string) { - panic("init step [" + step + "] failed: " + err.Error()) -} - -func main() { - spec, err := internal.ReadSpec(internal.InitSpec) - if err != nil { - panic(err) - } - - if err := internal.WriteFifo(); err != nil { - fail(err, "write fifo") - } - - env := setHome(spec.Process.Env, spec.Process.User.Username, spec.Process.Cwd) - - if err := unix.Chdir(spec.Process.Cwd); err != nil { - fail(err, "change to cwd") - } - - cmdPath, err := exec.LookPath(spec.Process.Args[0]) - if err != nil { - fail(err, "lookup cmd path") - } - - err = unix.Exec(cmdPath, spec.Process.Args, env) - if err != nil { - fail(err, "exec") - } -} - -func setHome(env []string, userName string, fallback string) []string { - // Use existing HOME environment variable. - for _, kv := range env { - if strings.HasPrefix(kv, "HOME=") { - return env - } - return env - } - // Or lookup users home directory in passwd. - if userName != "" { - u, err := user.Lookup(userName) - if err == nil && u.HomeDir != "" { - return append(env, "HOME="+u.HomeDir) - } - } - // Use the provided fallback path as last resort. - return append(env, "HOME="+fallback) -} diff --git a/cmd/internal/internal.go b/cmd/internal/internal.go deleted file mode 100644 index b1675b78..00000000 --- a/cmd/internal/internal.go +++ /dev/null @@ -1,94 +0,0 @@ -package internal - -import ( - "encoding/json" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - "os" - "time" -) - -const ( - // ConfigDir is the path to the crio-lxc resources relative to the container rootfs. - ConfigDir = "/.crio-lxc" - // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. - SyncFifoPath = ConfigDir + "/syncfifo" - // SyncFifoContent is the content exchanged through the sync fifo. - SyncFifoContent = "meshuggah rocks" - // InitCmd is the path where the init binary is bind mounted. - InitCmd = ConfigDir + "/init" - // InitSpec is the path where the modified runtime spec is written to. - // The init command loads the spec from this path. - InitSpec = ConfigDir + "/spec.json" -) - -// ReadSpec deserializes the JSON encoded runtime spec from the given path. -func ReadSpec(specFilePath string) (*specs.Spec, error) { - // #nosec - specFile, err := os.Open(specFilePath) - if err != nil { - return nil, err - } - // #nosec - defer specFile.Close() - spec := &specs.Spec{} - err = json.NewDecoder(specFile).Decode(spec) - if err != nil { - return nil, err - } - return spec, nil -} - -// WriteSpec serializes the runtime spec to JSON and writes it to the given path. -func WriteSpec(spec *specs.Spec, specFilePath string) error { - // #nosec - f, err := os.OpenFile(specFilePath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0444) - if err != nil { - return err - } - // #nosec - defer f.Close() - if err := json.NewEncoder(f).Encode(spec); err != nil { - return err - } - return f.Sync() -} - -// WriteFifo writes to the SyncFifo to synchronize container process init -func WriteFifo() error { - f, err := os.OpenFile(SyncFifoPath, os.O_WRONLY, 0) - if err != nil { - return err - } - _, err = f.Write([]byte(SyncFifoContent)) - if err != nil { - return err - } - return f.Close() -} - -// ReadFifo reads the content from the SyncFifo that was written by #WriteFifo. -// The read operation is aborted after the given timeout. -func ReadFifo(fifoPath string, timeout time.Duration) error { - // #nosec - f, err := os.OpenFile(fifoPath, os.O_RDONLY, 0) - if err != nil { - return errors.Wrap(err, "failed to open sync fifo") - } - err = f.SetDeadline(time.Now().Add(timeout)) - if err != nil { - return errors.Wrap(err, "failed to set deadline") - } - // #nosec - defer f.Close() - - data := make([]byte, len(SyncFifoContent)) - n, err := f.Read(data) - if err != nil { - return errors.Wrap(err, "problem reading from fifo") - } - if n != len(SyncFifoContent) || string(data) != SyncFifoContent { - return errors.Errorf("bad fifo content: %s", string(data)) - } - return nil -} diff --git a/cmd/main.go b/cmd/main.go index 7d9b6924..a9ad8b4a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -228,9 +228,9 @@ func main() { err := app.Run(os.Args) cmdDuration := time.Since(startTime) if err != nil { - log.Error().Err(err).Dur("duration", cmdDuration).Msg("runtime cmd failed") + log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") } else { - log.Debug().Dur("duration", cmdDuration).Msg("runtime cmd completed") + log.Info().Dur("duration", cmdDuration).Msg("cmd completed") } if err := clxc.release(); err != nil { diff --git a/cmd/start.go b/cmd/start.go index 755021df..333fd8a2 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -1,10 +1,11 @@ package main import ( - "time" - - "github.com/lxc/crio-lxc/cmd/internal" + "fmt" + "github.com/pkg/errors" "github.com/urfave/cli/v2" + "os" + "time" ) var startCmd = cli.Command{ @@ -20,7 +21,7 @@ starts Name: "timeout", Usage: "timeout for reading from syncfifo", EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, - Value: time.Second * 60, + Value: time.Second * 5, Destination: &clxc.StartTimeout, }, }, @@ -34,5 +35,36 @@ func doStart(ctx *cli.Context) error { return err } - return internal.ReadFifo(clxc.runtimePath(internal.SyncFifoPath), clxc.StartTimeout) + done := make(chan error) + go func() { + done <- readFifo() + }() + + select { + case err := <-done: + return err + case <-time.After(clxc.StartTimeout): + return fmt.Errorf("timeout reading from syncfifo") + } +} + +func readFifo() error { + // #nosec + f, err := os.OpenFile(clxc.runtimePath(syncFifoPath), os.O_RDONLY, 0) + if err != nil { + return errors.Wrap(err, "failed to open sync fifo") + } + // can not set deadline on fifo + // #nosec + defer f.Close() + + data := make([]byte, len(clxc.ContainerID)) + _, err = f.Read(data) + if err != nil { + return errors.Wrap(err, "problem reading from fifo") + } + if clxc.ContainerID != string(data) { + return errors.Errorf("bad fifo content: %s", string(data)) + } + return nil } diff --git a/cmd/state.go b/cmd/state.go index 84afac5f..cdd3d588 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -45,8 +45,11 @@ func doState(ctx *cli.Context) error { Annotations: spec.Annotations, } - _, state := clxc.getContainerState() + state, err := clxc.getContainerState() s.Status = string(state) + if err != nil { + return err + } log.Info().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") diff --git a/cmd/utils.go b/cmd/utils.go index 1e45b27f..268f824f 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -3,11 +3,8 @@ package main import ( "fmt" "github.com/pkg/errors" - "io/ioutil" "os" "path/filepath" - "strconv" - "strings" "golang.org/x/sys/unix" ) @@ -35,16 +32,6 @@ func createPidFile(path string, pid int) error { return os.Rename(tmpName, path) } -func readPidFile(path string) (int, error) { - // #nosec - data, err := ioutil.ReadFile(path) - if err != nil { - return 0, err - } - s := strings.TrimSpace(string(data)) - return strconv.Atoi(s) -} - func canExecute(cmds ...string) error { for _, c := range cmds { if err := unix.Access(c, unix.X_OK); err != nil { From 6012ab5c06c0dd20b5e79a048eac0fb94fb71e6f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:23:58 +0100 Subject: [PATCH 065/373] hook: Replace liblxc go hook with c implementation. Signed-off-by: Ruben Jenster --- cmd/container-hook/hook.c | 249 +++++++++++++++++++++++++++++++++++++ cmd/container-hook/hook.go | 123 ------------------ 2 files changed, 249 insertions(+), 123 deletions(-) create mode 100644 cmd/container-hook/hook.c delete mode 100644 cmd/container-hook/hook.go diff --git a/cmd/container-hook/hook.c b/cmd/container-hook/hook.c new file mode 100644 index 00000000..0dd63113 --- /dev/null +++ b/cmd/container-hook/hook.c @@ -0,0 +1,249 @@ +#define _GNU_SOURCE +#include +#include +#include // dirname +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int mask_paths_at(int rootfs, int runtime, const char *masked) +{ + // limits.h PATH_MAX + char line[PATH_MAX]; + const char *rel; + int fd; + FILE *f; + + printf("reading file \"%s\" from runtime directory\n", masked); + fd = openat(runtime, masked, O_RDONLY); + if (fd == -1) { + if (errno == ENOENT) { + printf("file \"%s\" does not exist\n", masked); + return 0; + } + return -1; + } + + f = fdopen(fd, "r"); + if (f == NULL) { + printf("file descriptor for runtime directory is null: %s", strerror(errno)); + close(fd); + return -1; + } + + if (fchdir(rootfs) != 0) { + printf("file to change to rootfs: %s\n", strerror(errno)); + goto out; + } + + while (fgets(line, sizeof(line), f) != NULL) { + line[strlen(line) - 1] = '\0'; // remove newline; + rel = (line[0] == '/') ? line + 1 : line; // trim leading '/' + struct stat path_stat; + if (stat(rel, &path_stat) == -1) { + if (errno == ENOENT) { + printf("ignore non existing filepath %s\n", rel); + errno = 0; + continue; + } + goto out; + } + + if (S_ISDIR(path_stat.st_mode)) { + printf("masking directory %s\n", rel); + if (mount("tmpfs", rel, "tmpfs", MS_RDONLY, NULL) == -1) + goto out; + } else { + printf("masking file %s\n", rel); + if (mount("/dev/null", rel, NULL, MS_BIND, NULL) == -1) + goto out; + } + } +out: + fclose(f); + return (errno == 0) ? 0 : -1; +} + +/* reads up to maxlines-1 lines from path into lines */ +int create_devices_at(int rootfs, int runtime, const char *devices) +{ + int fd; + FILE *f = NULL; + char buf[256]; + + printf("reading file \"%s\" from runtime directory\n", devices); + fd = openat(runtime, devices, O_RDONLY); + if (fd == -1) { + if (errno == ENOENT) { + printf("file \"%s\" does not exist\n", devices); + return 0; + } + return -1; + } + + f = fdopen(fd, "r"); + if (f == NULL) { + printf("file descriptor for runtime directory is null: %s", strerror(errno)); + close(fd); + return -1; + } + + for (int line = 0;; line++) { + char mode; + int major, minor; + unsigned int filemode; + int uid, gid; + char *dir = NULL; + char *dev = NULL; + char *sep = NULL; + char *tmp = NULL; + int ret; + + if (fchdir(rootfs) == -1) { + printf("file to change to rootfs: %s\n", strerror(errno)); + goto out; + } + + ret = fscanf(f, "%s %c %d %d %o %d:%d\n", &buf[0], &mode, + &major, &minor, &filemode, &uid, &gid); + if (ret == EOF) + goto out; + + if (ret != 7) { + // errno is not set on a matching error + printf("invalid format at line %d at token %d\n", line, ret); + fclose(f); + return -1; + } + + dev = (buf[0] == '/') ? buf + 1 : buf; + + struct stat path_stat; + if (stat(dev, &path_stat) == 0) { + printf("ignore existing device %s\n", dev); + continue; + } + + int ft; + switch (mode) { + case 'b': + ft = S_IFBLK; + break; + case 'c': + ft = S_IFCHR; + break; + case 'f': + ft = S_IFIFO; + break; + default: + printf("%s:%d unsupported device mode '%c'\n", devices, line, mode); + return -1; + } + + sep = strrchr(dev, '/'); + if (sep != NULL) { + printf("creating non-existent directories for device path \"%s\"\n", dev); + *sep = '\0'; + tmp = dev; + dev = sep + 1; + for ((dir = strtok(tmp, "/")); dir != NULL; + dir = strtok(NULL, "/")) { + if (mkdir(dir, 0755) == -1) { + if (errno == EEXIST) + errno = 0; + else + goto out; + } + if (chdir(dir) != 0) { + printf("%s:%d failed to change to directory \"%s\": %s\n", devices, line, dir, strerror(errno)); + goto out; + } + } + } + printf("creating device: %s %c %d %d mode:%o %d:%d\n", + dev, mode, major, minor, filemode, uid, gid); + ret = mknod(dev, ft | filemode, makedev(major, minor)); + if (ret == -1) { + printf("%s:%d failed to create device \"%s\"\n", devices, line, dev); + goto out; + } + ret = chown(dev, uid, gid); + if (ret == -1) { + printf("%s:%d failed to chown %d:%d device \"%s\"\n", devices, line, uid, gid, dev); + goto out; + } + } +out: + fclose(f); + return (errno == 0) ? 0 : -1; +} + +int main(int argc, char **argv) +{ + const char *rootfs_mount; + const char *config_file; + const char *runtime_path; + int rootfs; + int runtime; + int ret = EXIT_SUCCESS; + + rootfs_mount = getenv("LXC_ROOTFS_MOUNT"); + config_file = getenv("LXC_CONFIG_FILE"); + + if (rootfs_mount == NULL) { + printf("LXC_ROOTFS_MOUNT environment variable not set\n"); + ret = 1; + goto out; + } + if (config_file == NULL) { + printf("LXC_CONFIG_FILE environment variable not set\n"); + ret = 2; + goto out; + } + + rootfs = open(rootfs_mount, O_PATH); + if (rootfs == -1) { + printf("failed to open rootfs mount directory: %s", strerror(errno)); + ret = 3; + goto out; + } + + runtime_path = dirname(strdup(config_file)); + runtime = open(runtime_path, O_PATH); + if (rootfs == -1) { + printf("failed to open runtime directory: %s", strerror(errno)); + ret = 4; + goto out; + } + + printf("create devices int container rootfs\n"); + if (create_devices_at(rootfs, runtime, "devices.txt") == -1) { + printf("failed to create devices: %s", strerror(errno)); + ret = 5; + goto out; + } + + printf("masking files and directories in container rootfs\n"); + if (mask_paths_at(rootfs, runtime, "masked.txt") == -1) { + printf("failed to mask paths: %s", strerror(errno)); + ret = 6; + goto out; + } + +out: + if (rootfs >= 0) + close(rootfs); + + if (runtime >= 0) + close(runtime); + + printf("returning with %d\n", ret); + return ret; +} diff --git a/cmd/container-hook/hook.go b/cmd/container-hook/hook.go deleted file mode 100644 index 14c638eb..00000000 --- a/cmd/container-hook/hook.go +++ /dev/null @@ -1,123 +0,0 @@ -package main - -import ( - "fmt" - "github.com/lxc/crio-lxc/cmd/internal" - "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/sys/unix" - "os" - "path/filepath" -) - -// from `man lxc.container.conf` -// Standard output from the hooks is logged at debug level. -// Standard error is not logged ... -func fail(err error, msg string, args ...interface{}) { - if err == nil { - fmt.Printf("ERR "+msg+"\n", args...) - } else { - fmt.Printf("ERR:"+msg+": %s\n", append(args, err)) - } - os.Exit(1) -} - -func main() { - // get rootfs mountpoint from environment - rootfs := os.Getenv("LXC_ROOTFS_MOUNT") - if rootfs == "" { - fail(nil, "LXC_ROOTFS_MOUNT environment is not set") - } - - // ensure we are running in the correct hook - if hook := os.Getenv("LXC_HOOK_TYPE"); hook != "mount" { - fail(nil, "LXC_HOOK_TYPE=%s but can only run in 'mount' hook", hook) - } - - if _, err := os.Stat(rootfs); err != nil { - fail(err, "stat for rootfs mount %q failed", rootfs) - } - - specPath := filepath.Join(rootfs, internal.InitSpec) - spec, err := internal.ReadSpec(specPath) - if err != nil { - fail(err, "failed to parse spec %s", specPath) - } - - for _, dev := range spec.Linux.Devices { - dev.Path = filepath.Join(rootfs, dev.Path) - if err := createDevice(spec, dev); err != nil { - fail(err, "failed to create device %s", dev.Path) - } - } - - for _, p := range spec.Linux.MaskedPaths { - rp := filepath.Join(rootfs, p) - if err := maskPath(rp); err != nil { - fail(err, "failed to mask path %s", rp) - } - } -} - -func getDeviceType(s string) int { - switch s { - case "b": - return unix.S_IFBLK - case "c": - return unix.S_IFCHR - case "p": - return unix.S_IFIFO - // case "u": ? unbuffered character device ? - } - return -1 -} - -func createDevice(spec *specs.Spec, dev specs.LinuxDevice) error { - var mode uint32 = 0660 - if dev.FileMode != nil { - mode |= uint32(*dev.FileMode) - } - devType := getDeviceType(dev.Type) - if devType == -1 { - return fmt.Errorf("unsupported device type: %s", dev.Type) - } - mode |= uint32(devType) - - devMode := 0 - if devType == unix.S_IFBLK || devType == unix.S_IFCHR { - devMode = int(unix.Mkdev(uint32(dev.Major), uint32(dev.Minor))) - } - - // ignore error (mknod will fail) - // #nosec - os.MkdirAll(filepath.Dir(dev.Path), 0755) - - err := unix.Mknod(dev.Path, mode, devMode) - if err != nil { - return fmt.Errorf("mknod failed: %s", err) - } - - uid := spec.Process.User.UID - if dev.UID != nil { - uid = *dev.UID - } - gid := spec.Process.User.GID - if dev.GID != nil { - gid = *dev.GID - } - err = unix.Chown(dev.Path, int(uid), int(gid)) - if err != nil { - return fmt.Errorf("chown failed: %s", err) - } - return nil -} - -func maskPath(p string) error { - err := unix.Mount("/dev/null", p, "", unix.MS_BIND, "") - if os.IsNotExist(err) { - return nil - } - if err == unix.ENOTDIR { - return unix.Mount("tmpfs", p, "tmpfs", unix.MS_RDONLY, "") - } - return err -} From fe39a18173a02ef414a22e7b6e4413ed9dad5bb2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 03:19:01 +0100 Subject: [PATCH 066/373] kill: Fix signal parsing. Signed-off-by: Ruben Jenster --- cmd/cgroup_test.go | 31 +++++++++++++++++++++++++++++++ cmd/kill.go | 46 +++++++++++----------------------------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/cmd/cgroup_test.go b/cmd/cgroup_test.go index 8a5f6f0e..96f8ad81 100644 --- a/cmd/cgroup_test.go +++ b/cmd/cgroup_test.go @@ -2,6 +2,7 @@ package main import ( "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" "testing" ) @@ -10,3 +11,33 @@ func TestParseSystemCgroupPath(t *testing.T) { cg := parseSystemdCgroupPath(s) require.Equal(t, "kubepods.slice/kubepods-burstable.slice/kubepods-burstable-123.slice/crio-ABC.scope", cg) } + +func TestParseSignal(t *testing.T) { + sig, err := parseSignal("9") + require.NoError(t, err) + require.Equal(t, unix.SIGKILL, sig) + + sig, err = parseSignal("kill") + require.NoError(t, err) + require.Equal(t, unix.SIGKILL, sig) + + sig, err = parseSignal("sigkill") + require.NoError(t, err) + require.Equal(t, unix.SIGKILL, sig) + + sig, err = parseSignal("KILL") + require.NoError(t, err) + require.Equal(t, unix.SIGKILL, sig) + + sig, err = parseSignal("SIGKILL") + require.NoError(t, err) + require.Equal(t, unix.SIGKILL, sig) + + sig, err = parseSignal("SIGNOTEXIST") + require.Error(t, err) + require.Equal(t, sigzero, sig) + + sig, err = parseSignal("66") + require.Error(t, err) + require.Equal(t, sigzero, sig) +} diff --git a/cmd/kill.go b/cmd/kill.go index f81c4391..9c0090ec 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -4,7 +4,6 @@ package main import ( "fmt" - "os" "strconv" "strings" @@ -64,13 +63,7 @@ var signalMap = map[string]unix.Signal{ "XFSZ": unix.SIGXFSZ, } -// Retrieve the PID from container init process safely. -func getSignal(ctx *cli.Context) (unix.Signal, error) { - sig := ctx.Args().Get(1) - if len(sig) == 0 { - return sigzero, errors.New("missing signal") - } - +func parseSignal(sig string) (unix.Signal, error) { // handle numerical signal value if num, err := strconv.Atoi(sig); err == nil { for _, signum := range signalMap { @@ -78,20 +71,25 @@ func getSignal(ctx *cli.Context) (unix.Signal, error) { return signum, nil } } - return sigzero, fmt.Errorf("signal %s is not supported", sig) + return sigzero, fmt.Errorf("signal %q is not supported", sig) } // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' - s := strings.TrimPrefix("SIG", strings.ToUpper(sig)) + s := strings.TrimPrefix(strings.ToUpper(sig), "SIG") signum, exists := signalMap[s] if !exists { - return unix.Signal(0), fmt.Errorf("signal %s not supported", sig) + return sigzero, fmt.Errorf("signal %q not supported", sig) } return signum, nil } func doKill(ctx *cli.Context) error { - signum, err := getSignal(ctx) + sig := ctx.Args().Get(1) + if len(sig) == 0 { + return errors.New("missing signal") + } + + signum, err := parseSignal(sig) if err != nil { return errors.Wrap(err, "invalid signal param") } @@ -101,27 +99,5 @@ func doKill(ctx *cli.Context) error { return errors.Wrap(err, "failed to load container") } - pid, err := clxc.readPidFile() - if err != nil && !os.IsNotExist(err) { - return errors.Wrapf(err, "failed to load pidfile") - } - log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - - if err := clxc.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { - return err - } - if err := clxc.Container.Stop(); err != nil { - return err - } - - // send signal to the monitor process if it still exist - if err := unix.Kill(pid, 0); err == nil { - err := unix.Kill(pid, signum) - // container process has already died - if signum == unix.SIGKILL || signum == unix.SIGTERM { - return nil - } - return err - } - return nil + return clxc.killContainer(signum) } From 962d7fdcf1be50026db3ec3d10f8d97ca237378b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 10:23:24 +0100 Subject: [PATCH 067/373] Change default log-file path to /var/log/crio-lxc/crio-lxc.log. Signed-off-by: Ruben Jenster --- cmd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index a9ad8b4a..900503bb 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -54,7 +54,7 @@ func main() { Name: "log-file", Usage: "path to the log file for runtime and container output", EnvVars: []string{"CRIO_LXC_LOG_FILE"}, - Value: "/var/log/crio-lxc.log", + Value: "/var/log/crio-lxc/crio-lxc.log", Destination: &clxc.LogFilePath, }, &cli.StringFlag{ From bf74c4b82e3fc7ed98e68a16a9edc2c6191f15f5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 10:24:51 +0100 Subject: [PATCH 068/373] Add LOG_FILE variable to runtime hook environment. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/clxc.go b/cmd/clxc.go index 4dddd772..ed9d45a6 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -458,6 +458,7 @@ func (c *crioLXC) executeRuntimeHook(err error) { "RUNTIME_PATH=" + c.runtimePath(), "BUNDLE_PATH=" + c.BundlePath, "SPEC_PATH=" + c.SpecPath, + "LOG_FILE=" + c.LogFilePath, } if err != nil { From c4dd78c6f731d77bb96e74f5e1e9fa6784f902f4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 10:25:49 +0100 Subject: [PATCH 069/373] Log unsupported config items at log level info. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index ed9d45a6..28583b6c 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -330,7 +330,7 @@ func (c crioLXC) release() error { func supportsConfigItem(keys ...string) bool { for _, key := range keys { if !lxc.IsSupportedConfigItem(key) { - log.Debug().Str("lxc.config", key).Msg("unsupported config item") + log.Info().Str("lxc.config", key).Msg("unsupported config item") return false } } From 4a4384d253d7e6d964d8a576c4a329529db88fc8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 10:26:41 +0100 Subject: [PATCH 070/373] Rename executeRuntimeHook param. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index 28583b6c..a61aca79 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -446,11 +446,12 @@ func (c *crioLXC) parseContainerLogLevel() lxc.LogLevel { } } -func (c *crioLXC) executeRuntimeHook(err error) { +// executeRuntimeHook executes the runtime hook executable if defined. +// Execution errors are logged at log level error. +func (c *crioLXC) executeRuntimeHook(runtimeError error) { if c.RuntimeHook == "" { return } - // prepare environment env := []string{ "CONTAINER_ID=" + c.ContainerID, "LXC_CONFIG=" + c.configFilePath(), @@ -461,8 +462,8 @@ func (c *crioLXC) executeRuntimeHook(err error) { "LOG_FILE=" + c.LogFilePath, } - if err != nil { - env = append(env, "RUNTIME_ERROR="+err.Error()) + if runtimeError != nil { + env = append(env, "RUNTIME_ERROR="+runtimeError.Error()) } log.Debug().Str("file", clxc.RuntimeHook).Msg("execute runtime hook") From bdb311b5a59da11f833862ba855d0f70859388d9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 11:05:58 +0100 Subject: [PATCH 071/373] Fix cgroup removal in deleteCgroup (missing Close). Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 28 ++++++++++++++++++++++++++-- cmd/clxc.go | 20 +++++++++----------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index fb8a7fdd..42d23810 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -223,6 +223,28 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { return info, nil } +/* +func deleteCgroupContext(ctx context.Context, cgroupPath string) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + err := deleteCgroup(cgroupPath) + if err == nil { + return nil + } + if err == unix.EBUSY { + log.Warn().Err(err).Str("cgroup", cgroupPath).Msg("failed to remove cgroup") + time.Sleep(time.Millisecond * 50) + continue + } + return err + } + } +} +*/ + func deleteCgroup(cgName string) error { dirName := filepath.Join("/sys/fs/cgroup", cgName) // #nosec @@ -234,15 +256,17 @@ func deleteCgroup(cgName string) error { return err } entries, err := dir.Readdir(-1) + if err := dir.Close(); err != nil { + return err + } if err != nil { return err } - // leftover lxc.pivot path for _, i := range entries { if i.IsDir() && i.Name() != "." && i.Name() != ".." { fullPath := filepath.Join(dirName, i.Name()) if err := unix.Rmdir(fullPath); err != nil { - return errors.Wrapf(err, "failed rmdir %s %T", fullPath, err) + return err } } } diff --git a/cmd/clxc.go b/cmd/clxc.go index a61aca79..70b59f33 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -547,8 +547,15 @@ func (c *crioLXC) destroy() error { } } - // cgroup directories must be removed if container process was killed with SIGKILL - c.tryRemoveCgroups() + // Ensure that cgroup directories are gone after container is destroyed. + // kubernetes will show the container as 'Terminated' until the cgroup is removed. + // Cgroups may exist if container process was killed with SIGKILL and could not cleanup cgroups itself. + if err := deleteCgroup(c.CgroupsPath); err != nil { + log.Warn().Err(err).Str("cgroup", c.CgroupsPath).Msg("failed to remove cgroup") + } + if err := deleteCgroup(c.MonitorCgroup); err != nil { + log.Warn().Err(err).Str("cgroup", c.MonitorCgroup).Msg("failed to remove monitor cgroup") + } // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." @@ -557,12 +564,3 @@ func (c *crioLXC) destroy() error { return os.RemoveAll(c.runtimePath()) } - -func (c *crioLXC) tryRemoveCgroups() { - if err := deleteCgroup(c.CgroupsPath); err != nil { - log.Warn().Err(err).Str("cgroup", c.CgroupsPath).Msg("failed to remove cgroup") - } - if err := deleteCgroup(c.MonitorCgroup); err != nil { - log.Warn().Err(err).Str("cgroup", c.MonitorCgroup).Msg("failed to remove monitor cgroup") - } -} From a75813c3941b60f1fce5fac00b4410d224144e79 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 11:14:55 +0100 Subject: [PATCH 072/373] Add debug output for cgroup removal. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 42d23810..6097c22e 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -268,7 +268,12 @@ func deleteCgroup(cgName string) error { if err := unix.Rmdir(fullPath); err != nil { return err } + log.Debug().Str("file", fullPath).Msg("removed cgroup dir") } } - return unix.Rmdir(dirName) + err = unix.Rmdir(dirName) + if err == nil { + log.Debug().Str("file", dirName).Msg("removed cgroup dir") + } + return err } From f352c9927b3ebf1ddb64c527a283a37c40f4e56d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 15:22:32 +0100 Subject: [PATCH 073/373] init: Set working directory for init process from spec. Signed-off-by: Ruben Jenster --- cmd/create.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/create.go b/cmd/create.go index 4c4b6c25..cda21c24 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -317,6 +317,10 @@ func configureInit(spec *specs.Spec) error { return err } + if err := clxc.setConfigItem("lxc.init.cwd", spec.Process.Cwd); err != nil { + return err + } + // create destination file for bind mount initBin := clxc.runtimePath(initCmd) err = touchFile(initBin, 0) From a5e1374a216c4832763e950df9adea72498346ee Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 15:24:23 +0100 Subject: [PATCH 074/373] cgroup: Retry cgroup deletion if cgroup is still in used. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 14 ++++++++++---- cmd/clxc.go | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 6097c22e..898baa10 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -1,12 +1,14 @@ package main import ( + "context" "fmt" "io/ioutil" "os" "path/filepath" "strconv" "strings" + "time" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -223,7 +225,12 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { return info, nil } -/* +func deleteCgroupWait(cgroupPath string, timeout time.Duration) error { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + return deleteCgroupContext(ctx, cgroupPath) +} + func deleteCgroupContext(ctx context.Context, cgroupPath string) error { for { select { @@ -243,10 +250,9 @@ func deleteCgroupContext(ctx context.Context, cgroupPath string) error { } } } -*/ -func deleteCgroup(cgName string) error { - dirName := filepath.Join("/sys/fs/cgroup", cgName) +func deleteCgroup(cgroupName string) error { + dirName := filepath.Join("/sys/fs/cgroup", cgroupName) // #nosec dir, err := os.Open(dirName) if os.IsNotExist(err) { diff --git a/cmd/clxc.go b/cmd/clxc.go index 70b59f33..c92d6124 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -550,10 +550,10 @@ func (c *crioLXC) destroy() error { // Ensure that cgroup directories are gone after container is destroyed. // kubernetes will show the container as 'Terminated' until the cgroup is removed. // Cgroups may exist if container process was killed with SIGKILL and could not cleanup cgroups itself. - if err := deleteCgroup(c.CgroupsPath); err != nil { + if err := deleteCgroupWait(c.CgroupsPath, time.Second); err != nil { log.Warn().Err(err).Str("cgroup", c.CgroupsPath).Msg("failed to remove cgroup") } - if err := deleteCgroup(c.MonitorCgroup); err != nil { + if err := deleteCgroupWait(c.MonitorCgroup, time.Second); err != nil { log.Warn().Err(err).Str("cgroup", c.MonitorCgroup).Msg("failed to remove monitor cgroup") } From a2060e5dafa078cd440808ce5ec6c10252ccd680 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 26 Nov 2020 20:43:32 +0100 Subject: [PATCH 075/373] cgroup: Try to improve cgroup removal Signed-off-by: Ruben Jenster --- Makefile | 4 +- cmd/cgroup.go | 18 ++++++- cmd/clxc.go | 135 +++++++++++++++++++++++++++++++++++------------- cmd/create.go | 2 +- cmd/delete.go | 3 +- cmd/main.go | 2 +- cmd/state.go | 2 + utils/cglist.sh | 2 +- 8 files changed, 125 insertions(+), 43 deletions(-) mode change 100644 => 100755 utils/cglist.sh diff --git a/Makefile b/Makefile index d0ff237b..7c67bd40 100644 --- a/Makefile +++ b/Makefile @@ -13,13 +13,13 @@ CC ?= cc all: fmt $(BINS) install: all - cp $(BINS) $(PREFIX)/bin + cp -v $(BINS) $(PREFIX)/bin lint: golangci-lint run -c ./lint.yaml ./... crio-lxc: $(GO_SRC) Makefile go.mod - go build -ldflags '$(LDFLAGS)' -o $@ ./cmd + go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c $(CC) -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 898baa10..e180abea 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -243,7 +243,7 @@ func deleteCgroupContext(ctx context.Context, cgroupPath string) error { } if err == unix.EBUSY { log.Warn().Err(err).Str("cgroup", cgroupPath).Msg("failed to remove cgroup") - time.Sleep(time.Millisecond * 50) + time.Sleep(time.Millisecond * 100) continue } return err @@ -272,6 +272,22 @@ func deleteCgroup(cgroupName string) error { if i.IsDir() && i.Name() != "." && i.Name() != ".." { fullPath := filepath.Join(dirName, i.Name()) if err := unix.Rmdir(fullPath); err != nil { + log.Warn().Err(err).Str("file", fullPath).Msg("failed to remove cgroup dir") + cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) + if err != nil { + log.Warn().Err(err).Str("file", fullPath).Msg("failed to read cgroup proces") + } + for _, pid := range cg.Procs { + log.Warn().Int("pid", pid).Msg("killing left-over process") + err := unix.Kill(pid, unix.SIGKILL) + if err != nil { + errors.Wrapf(err, "failed to kill %d", pid) + } + } + // try again + if err := unix.Rmdir(fullPath); err != nil { + log.Warn().Err(err).Str("file", fullPath).Msg("failed to remove cgroup dir #2") + } return err } log.Debug().Str("file", fullPath).Msg("removed cgroup dir") diff --git a/cmd/clxc.go b/cmd/clxc.go index c92d6124..1e37241b 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -73,6 +73,7 @@ type crioLXC struct { LogLevel string ContainerLogLevel string SystemdCgroup bool + MonitorCgroup string StartCommand string InitCommand string @@ -97,13 +98,13 @@ type crioLXC struct { } type bundleConfig struct { - BundlePath string - SpecPath string // BundlePath + "/config.json" - PidFile string - ConsoleSocket string - MonitorCgroup string + BundlePath string + SpecPath string // BundlePath + "/config.json" + PidFile string + ConsoleSocket string + MonitorCgroupDir string // values derived from spec - CgroupsPath string + CgroupDir string } var version string @@ -156,15 +157,6 @@ func (c *crioLXC) readSpec() (*specs.Spec, error) { return nil, err } - if spec.Linux.CgroupsPath == "" { - return nil, fmt.Errorf("empty cgroups path in spec") - } - if c.SystemdCgroup { - c.CgroupsPath = parseSystemdCgroupPath(spec.Linux.CgroupsPath) - } else { - c.CgroupsPath = spec.Linux.CgroupsPath - } - return spec, nil } @@ -198,7 +190,7 @@ func (c *crioLXC) loadContainer() error { // createContainer creates a new container. // It must only be called once during the lifecycle of a container. -func (c *crioLXC) createContainer() error { +func (c *crioLXC) createContainer(spec *specs.Spec) error { if _, err := os.Stat(c.configFilePath()); err == nil { return errContainerExist } @@ -218,7 +210,20 @@ func (c *crioLXC) createContainer() error { return errors.Wrap(err, "failed to close empty config file") } - c.MonitorCgroup = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") + if spec.Linux.CgroupsPath == "" { + return fmt.Errorf("empty cgroups path in spec") + } + if c.SystemdCgroup { + c.CgroupDir = parseSystemdCgroupPath(spec.Linux.CgroupsPath) + } else { + c.CgroupDir = spec.Linux.CgroupsPath + } + + c.MonitorCgroupDir = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") + + if err := enableCgroupControllers(filepath.Dir(c.CgroupDir)); err != nil { + return err + } if err := c.writeBundleConfig(); err != nil { return err @@ -237,25 +242,37 @@ func (c *crioLXC) configureCgroupPath() error { return err } - // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb - // checking for on of the config items shuld be enough, because they were introduced together ... - if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { - if err := c.setConfigItem("lxc.cgroup.dir.container", c.CgroupsPath); err != nil { - return err - } - if err := c.setConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroup); err != nil { - return err - } - } else { - if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupsPath); err != nil { - return err - } + if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { + return err } + if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { return err } } + + /* + // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb + // checking for on of the config items shuld be enough, because they were introduced together ... + if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { + if err := c.setConfigItem("lxc.cgroup.dir.container", c.CgroupDir); err != nil { + return err + } + if err := c.setConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroupDir); err != nil { + return err + } + } else { + if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { + return err + } + } + if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { + return err + } + } + */ return nil } @@ -520,6 +537,48 @@ func (c *crioLXC) getContainerState() (ContainerState, error) { return StateRunning, nil } +func enableCgroupControllers(cg string) error { + //slice := cg.ScopePath() + // #nosec + cgPath := filepath.Join("/sys/fs/cgroup", cg) + if err := os.MkdirAll(cgPath, 755); err != nil { + return err + } + /* + // enable all available controllers in the scope + data, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") + if err != nil { + return errors.Wrap(err, "failed to read cgroup.controllers") + } + controllers := strings.Split(strings.TrimSpace(string(data)), " ") + + var b strings.Builder + for i, c := range controllers { + if i > 0 { + b.WriteByte(' ') + } + b.WriteByte('+') + b.WriteString(c) + } + b.WriteString("\n") + + s := b.String() + */ + s := "+cpuset +cpu +io +memory +hugetlb +pids +rdma\n" + + base := "/sys/fs/cgroup" + for _, elem := range strings.Split(cg, "/") { + base = filepath.Join(base, elem) + c := filepath.Join(base, "cgroup.subtree_control") + err := ioutil.WriteFile(c, []byte(s), 0) + if err != nil { + return errors.Wrapf(err, "failed to enable cgroup controllers in %s", base) + } + log.Info().Str("file", base).Str("controllers", strings.TrimSpace(s)).Msg("cgroup activated") + } + return nil +} + func (c *crioLXC) killContainer(signum unix.Signal) error { pid, err := c.readPidFile() if err != nil && !os.IsNotExist(err) { @@ -550,12 +609,16 @@ func (c *crioLXC) destroy() error { // Ensure that cgroup directories are gone after container is destroyed. // kubernetes will show the container as 'Terminated' until the cgroup is removed. // Cgroups may exist if container process was killed with SIGKILL and could not cleanup cgroups itself. - if err := deleteCgroupWait(c.CgroupsPath, time.Second); err != nil { - log.Warn().Err(err).Str("cgroup", c.CgroupsPath).Msg("failed to remove cgroup") - } - if err := deleteCgroupWait(c.MonitorCgroup, time.Second); err != nil { - log.Warn().Err(err).Str("cgroup", c.MonitorCgroup).Msg("failed to remove monitor cgroup") - } + //if err := deleteCgroupWait(c.CgroupDir, 10*time.Second); err != nil { + if err := deleteCgroup(c.CgroupDir); err != nil { + log.Warn().Err(err).Str("cgroup", c.CgroupDir).Msg("failed to remove cgroup") + } + /* + //if err := deleteCgroupWait(c.MonitorCgroupDir, 10*time.Second); err != nil { + if err := deleteCgroup(c.MonitorCgroupDir); err != nil { + log.Warn().Err(err).Str("cgroup", c.MonitorCgroupDir).Msg("failed to remove monitor cgroup") + } + */ // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." diff --git a/cmd/create.go b/cmd/create.go index cda21c24..4b63ed44 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -83,7 +83,7 @@ func doCreateInternal(ctx *cli.Context) error { return errors.Wrap(err, "couldn't load bundle spec") } - err = clxc.createContainer() + err = clxc.createContainer(spec) if err != nil { return errors.Wrap(err, "failed to create container") } diff --git a/cmd/delete.go b/cmd/delete.go index 1f6be6fe..07f2ff19 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -28,7 +28,8 @@ func doDelete(ctx *cli.Context) error { err := clxc.loadContainer() if err == errContainerNotExist { - return clxc.destroy() + return nil + //return clxc.destroy() } if err != nil { return err diff --git a/cmd/main.go b/cmd/main.go index 900503bb..f47c4db0 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -71,7 +71,7 @@ func main() { }, &cli.StringFlag{ Name: "monitor-cgroup", - Usage: "cgroup slice for liblxc monitor process", + Usage: "cgroup slice for liblxc monitor process and pivot path", Destination: &clxc.MonitorCgroup, EnvVars: []string{"CRIO_LXC_MONITOR_CGROUP"}, Value: "crio-lxc-monitor.slice", diff --git a/cmd/state.go b/cmd/state.go index cdd3d588..8944d902 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -45,6 +45,8 @@ func doState(ctx *cli.Context) error { Annotations: spec.Annotations, } + //s.Annotations = spec.Annotations + state, err := clxc.getContainerState() s.Status = string(state) if err != nil { diff --git a/utils/cglist.sh b/utils/cglist.sh old mode 100644 new mode 100755 index 071c3caf..5d1afa29 --- a/utils/cglist.sh +++ b/utils/cglist.sh @@ -3,5 +3,5 @@ cd /sys/fs/cgroup/kubepods.slice for cg in $(find . -name cgroup.controllers); do - echo "$(dirname $cg): $(cat $cg)" + echo "$(dirname $cg) [$(cat $cg)]" done From 73fddfd85865ab79bb0424f945d2aff98fdb9db0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 28 Nov 2020 00:26:13 +0100 Subject: [PATCH 076/373] cgroup: Implemented cgroup drain. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 98 +++++++++++++++++++++++++-------------------------- cmd/clxc.go | 24 +++++++------ 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index e180abea..62aed0fb 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -1,7 +1,7 @@ package main import ( - "context" + "bytes" "fmt" "io/ioutil" "os" @@ -225,33 +225,7 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { return info, nil } -func deleteCgroupWait(cgroupPath string, timeout time.Duration) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - return deleteCgroupContext(ctx, cgroupPath) -} - -func deleteCgroupContext(ctx context.Context, cgroupPath string) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - err := deleteCgroup(cgroupPath) - if err == nil { - return nil - } - if err == unix.EBUSY { - log.Warn().Err(err).Str("cgroup", cgroupPath).Msg("failed to remove cgroup") - time.Sleep(time.Millisecond * 100) - continue - } - return err - } - } -} - -func deleteCgroup(cgroupName string) error { +func killCgroupProcs(cgroupName string, sig unix.Signal) error { dirName := filepath.Join("/sys/fs/cgroup", cgroupName) // #nosec dir, err := os.Open(dirName) @@ -271,31 +245,55 @@ func deleteCgroup(cgroupName string) error { for _, i := range entries { if i.IsDir() && i.Name() != "." && i.Name() != ".." { fullPath := filepath.Join(dirName, i.Name()) - if err := unix.Rmdir(fullPath); err != nil { - log.Warn().Err(err).Str("file", fullPath).Msg("failed to remove cgroup dir") - cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) - if err != nil { - log.Warn().Err(err).Str("file", fullPath).Msg("failed to read cgroup proces") - } - for _, pid := range cg.Procs { - log.Warn().Int("pid", pid).Msg("killing left-over process") - err := unix.Kill(pid, unix.SIGKILL) - if err != nil { - errors.Wrapf(err, "failed to kill %d", pid) - } - } - // try again - if err := unix.Rmdir(fullPath); err != nil { - log.Warn().Err(err).Str("file", fullPath).Msg("failed to remove cgroup dir #2") - } + cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) + if err != nil { + log.Warn().Err(err).Str("file", fullPath).Msg("failed to read cgroup proces") return err } - log.Debug().Str("file", fullPath).Msg("removed cgroup dir") + for _, pid := range cg.Procs { + log.Warn().Int("pid", pid).Msg("killing left-over process") + err := unix.Kill(pid, sig) + if err != nil && err != unix.ESRCH { + return errors.Wrapf(err, "failed to kill %d", pid) + } + } } } - err = unix.Rmdir(dirName) - if err == nil { - log.Debug().Str("file", dirName).Msg("removed cgroup dir") + return nil +} + +// TODO maybe use polling instead +// fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} +// n, err := unix.Poll(fds, timeout) +func waitCgroupDrained(cgroupName string, timeout time.Duration) error { + p := filepath.Join("/sys/fs/cgroup", cgroupName, "cgroup.events") + f, err := os.OpenFile(p, os.O_RDONLY, 0) + if err != nil { + return err + } + + var buf bytes.Buffer + buf.Grow(64) + deadline := time.Now().Add(timeout) + for time.Now().Before(deadline) { + buf.Reset() + _, err = f.Seek(0, os.SEEK_SET) + if err != nil { + return err + } + _, err := buf.ReadFrom(f) + if err != nil { + return err + } + + for _, line := range strings.Split(buf.String(), "\n") { + if line == "populated 0" { + return nil + } + } + // TODO change log level to trace + log.Info().Str("cgroup", cgroupName).Msg("wait for cgroup to get empty") + time.Sleep(time.Millisecond * 50) } - return err + return fmt.Errorf("timeout") } diff --git a/cmd/clxc.go b/cmd/clxc.go index 1e37241b..59298ecc 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -596,6 +596,12 @@ func (c *crioLXC) killContainer(signum unix.Signal) error { } return err } + + err = killCgroupProcs(c.CgroupDir, signum) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Msg("failed to kill cgroup procs") + } + return nil } @@ -608,17 +614,15 @@ func (c *crioLXC) destroy() error { // Ensure that cgroup directories are gone after container is destroyed. // kubernetes will show the container as 'Terminated' until the cgroup is removed. - // Cgroups may exist if container process was killed with SIGKILL and could not cleanup cgroups itself. - //if err := deleteCgroupWait(c.CgroupDir, 10*time.Second); err != nil { - if err := deleteCgroup(c.CgroupDir); err != nil { - log.Warn().Err(err).Str("cgroup", c.CgroupDir).Msg("failed to remove cgroup") + err := killCgroupProcs(c.CgroupDir, unix.SIGKILL) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to kill cgroup procs") + } + + err = waitCgroupDrained(c.CgroupDir, time.Second*5) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") } - /* - //if err := deleteCgroupWait(c.MonitorCgroupDir, 10*time.Second); err != nil { - if err := deleteCgroup(c.MonitorCgroupDir); err != nil { - log.Warn().Err(err).Str("cgroup", c.MonitorCgroupDir).Msg("failed to remove monitor cgroup") - } - */ // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." From 08a4662a43c48d1496050e1f6ef26a8f7ed0c1bd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 28 Nov 2020 00:44:02 +0100 Subject: [PATCH 077/373] cgroup: Delete drained cgroup. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 33 +++++++++++++++++++++++++++++++-- cmd/clxc.go | 5 +++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index 62aed0fb..ace2fef2 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -291,9 +291,38 @@ func waitCgroupDrained(cgroupName string, timeout time.Duration) error { return nil } } - // TODO change log level to trace - log.Info().Str("cgroup", cgroupName).Msg("wait for cgroup to get empty") + log.Trace().Str("cgroup", cgroupName).Msg("waiting for cgroup to drain") time.Sleep(time.Millisecond * 50) } return fmt.Errorf("timeout") } + +func deleteCgroup(cgroupName string) error { + dirName := filepath.Join("/sys/fs/cgroup", cgroupName) + // #nosec + dir, err := os.Open(dirName) + if os.IsNotExist(err) { + return nil + } + if err != nil { + return err + } + entries, err := dir.Readdir(-1) + if err := dir.Close(); err != nil { + return err + } + if err != nil { + return err + } + for _, i := range entries { + if i.IsDir() && i.Name() != "." && i.Name() != ".." { + p := filepath.Join(dirName, i.Name()) + err := unix.Rmdir(p) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Str("file", p).Msg("failed to read cgroup dir") + return err + } + } + } + return unix.Rmdir(dirName) +} diff --git a/cmd/clxc.go b/cmd/clxc.go index 59298ecc..4f7e2db1 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -624,6 +624,11 @@ func (c *crioLXC) destroy() error { log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") } + err = deleteCgroup(c.CgroupDir) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + } + // "Note that resources associated with the container, // but not created by this container, MUST NOT be deleted." // TODO - because we set rootfs.managed=0, Destroy() doesn't From 7e8eef2a8a5f3cdd51d11c032f060948d2dbb40c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 28 Nov 2020 14:11:27 +0100 Subject: [PATCH 078/373] create: Fix environment and cmdline file permissions. Signed-off-by: Ruben Jenster --- cmd/create.go | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 4b63ed44..28ebe05e 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -92,19 +92,11 @@ func doCreateInternal(ctx *cli.Context) error { return errors.Wrap(err, "failed to configure container") } - cmdFile, err := os.OpenFile(clxc.runtimePath("/.crio-lxc/cmdline.txt"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0640) - if err != nil { - return errors.Wrap(err, "failed to create the cmd file") - } - - for _, arg := range spec.Process.Args { - fmt.Fprintln(cmdFile, arg) - } - if err := cmdFile.Close(); err != nil { - return errors.Wrap(err, "failed to close cmd file") + if err := writeCmdline(clxc.runtimePath("/.crio-lxc/cmdline.txt"), spec); err != nil { + return err } - if err := writeEnviron(clxc.runtimePath("/.crio-lxc/environ"), spec.Process.Env); err != nil { + if err := writeEnviron(clxc.runtimePath("/.crio-lxc/environ"), spec); err != nil { return err } @@ -118,13 +110,32 @@ func doCreateInternal(ctx *cli.Context) error { return clxc.createPidFile(startCmd.Process.Pid) } -func writeEnviron(envFile string, env []string) error { - f, err := os.OpenFile(envFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0640) +func writeCmdline(cmdFile string, spec *specs.Spec) error { + // #nosec + f, err := os.OpenFile(cmdFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) + if err != nil { + return errors.Wrap(err, "failed to create the cmd file") + } + for _, arg := range spec.Process.Args { + fmt.Fprintln(f, arg) + } + if err := f.Close(); err != nil { + return err + } + if err := unix.Chown(cmdFile, int(spec.Process.User.UID), int(spec.Process.User.GID)); err != nil { + return err + } + return unix.Chmod(cmdFile, 0400) +} + +func writeEnviron(envFile string, spec *specs.Spec) error { + // #nosec + f, err := os.OpenFile(envFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) if err != nil { return err } - for _, arg := range env { + for _, arg := range spec.Process.Env { _, err := f.WriteString(arg) if err != nil { f.Close() @@ -136,7 +147,13 @@ func writeEnviron(envFile string, env []string) error { return err } } - return f.Close() + if err := f.Close(); err != nil { + return err + } + if err := unix.Chown(envFile, int(spec.Process.User.UID), int(spec.Process.User.GID)); err != nil { + return err + } + return unix.Chmod(envFile, 0400) } func configureContainer(spec *specs.Spec) error { @@ -608,8 +625,8 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { // Send the pty file descriptor over the console socket (to the 'conmon' process) // For technical backgrounds see: - // man sendmsg 2', 'man unix 3', 'man cmsg 1' - // see https://blog.cloudflare.com/know-your-scm_rights/ + // * `man sendmsg 2`, `man unix 3`, `man cmsg 1` + // * https://blog.cloudflare.com/know-your-scm_rights/ oob := unix.UnixRights(int(ptmx.Fd())) // Don't know whether 'terminal' is the right data to send, but conmon doesn't care anyway. err = unix.Sendmsg(int(sockFile.Fd()), []byte("terminal"), oob, nil, 0) From 92cef7191c70b1ced06aa769429485ba2e009a4c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 28 Nov 2020 14:12:02 +0100 Subject: [PATCH 079/373] cgroup: Improve cgroup drain Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 6 +++++- cmd/clxc.go | 9 +-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index ace2fef2..cc891c9f 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -265,7 +265,7 @@ func killCgroupProcs(cgroupName string, sig unix.Signal) error { // TODO maybe use polling instead // fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} // n, err := unix.Poll(fds, timeout) -func waitCgroupDrained(cgroupName string, timeout time.Duration) error { +func drainCgroup(cgroupName string, sig unix.Signal, timeout time.Duration) error { p := filepath.Join("/sys/fs/cgroup", cgroupName, "cgroup.events") f, err := os.OpenFile(p, os.O_RDONLY, 0) if err != nil { @@ -291,6 +291,10 @@ func waitCgroupDrained(cgroupName string, timeout time.Duration) error { return nil } } + err = killCgroupProcs(cgroupName, sig) + if err != nil { + return errors.Wrapf(err, "failed to kill cgroup procs %s", cgroupName) + } log.Trace().Str("cgroup", cgroupName).Msg("waiting for cgroup to drain") time.Sleep(time.Millisecond * 50) } diff --git a/cmd/clxc.go b/cmd/clxc.go index 4f7e2db1..1a91f09d 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -612,14 +612,7 @@ func (c *crioLXC) destroy() error { } } - // Ensure that cgroup directories are gone after container is destroyed. - // kubernetes will show the container as 'Terminated' until the cgroup is removed. - err := killCgroupProcs(c.CgroupDir, unix.SIGKILL) - if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to kill cgroup procs") - } - - err = waitCgroupDrained(c.CgroupDir, time.Second*5) + err := drainCgroup(c.CgroupDir, unix.SIGKILL, time.Second*10) if err != nil && !os.IsNotExist(err) { log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") } From 2402a223b42a3e0ad56011ce8611ae54b941bd2b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 29 Nov 2020 23:00:19 +0100 Subject: [PATCH 080/373] kill: Use container stop only for SIGKILL and SIGTERM Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 2 +- cmd/clxc.go | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index cc891c9f..d6620ed4 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -323,7 +323,7 @@ func deleteCgroup(cgroupName string) error { p := filepath.Join(dirName, i.Name()) err := unix.Rmdir(p) if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", p).Msg("failed to read cgroup dir") + log.Warn().Err(err).Str("file", p).Msg("failed to remove ecgroup dir") return err } } diff --git a/cmd/clxc.go b/cmd/clxc.go index 1a91f09d..5ac8beda 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -238,7 +238,7 @@ func (c *crioLXC) createContainer(spec *specs.Spec) error { } func (c *crioLXC) configureCgroupPath() error { - if err := clxc.setConfigItem("lxc.cgroup.relative", "0"); err != nil { + if err := c.setConfigItem("lxc.cgroup.relative", "0"); err != nil { return err } @@ -586,15 +586,26 @@ func (c *crioLXC) killContainer(signum unix.Signal) error { } log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - // send signal to the monitor process if it still exist - // signals other than SIGTERM are forwarded from liblxc to the container int process + if signum == unix.SIGKILL || signum == unix.SIGTERM { + if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { + return err + } + if err := c.Container.Stop(); err != nil { + return err + } + if !c.Container.Wait(lxc.STOPPED, time.Second*10) { + log.Warn().Msg("failed to stop lxc container - sending kill") + } + } + + // TODO wait for the monitor process to die ? + + // kill remaining processes within the cgroup if err := unix.Kill(pid, 0); err == nil { err := unix.Kill(pid, signum) - // container process has already died - if signum == unix.SIGKILL || signum == unix.SIGTERM { - return nil + if err != unix.ESRCH { + return errors.Wrap(err, "failed to kill container process") } - return err } err = killCgroupProcs(c.CgroupDir, signum) @@ -612,9 +623,12 @@ func (c *crioLXC) destroy() error { } } + start := time.Now() err := drainCgroup(c.CgroupDir, unix.SIGKILL, time.Second*10) if err != nil && !os.IsNotExist(err) { log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + } else { + log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") } err = deleteCgroup(c.CgroupDir) From 44c482b40d440d50d8a91c40097d82b8c906a3b3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 30 Nov 2020 19:55:23 +0100 Subject: [PATCH 081/373] kill: Check container state. Remove signalMap in favour of unix.SignalNum. Signed-off-by: Ruben Jenster --- cmd/kill.go | 78 +++++++++++++---------------------------------------- 1 file changed, 19 insertions(+), 59 deletions(-) diff --git a/cmd/kill.go b/cmd/kill.go index 9c0090ec..b8877f7a 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -1,5 +1,3 @@ -// +build go1.10 - package main import ( @@ -24,79 +22,41 @@ var killCmd = cli.Command{ `, } -const sigzero = unix.Signal(0) - -var signalMap = map[string]unix.Signal{ - "ABRT": unix.SIGABRT, - "ALRM": unix.SIGALRM, - "BUS": unix.SIGBUS, - "CHLD": unix.SIGCHLD, - "CLD": unix.SIGCLD, - "CONT": unix.SIGCONT, - "FPE": unix.SIGFPE, - "HUP": unix.SIGHUP, - "ILL": unix.SIGILL, - "INT": unix.SIGINT, - "IO": unix.SIGIO, - "IOT": unix.SIGIOT, - "KILL": unix.SIGKILL, - "PIPE": unix.SIGPIPE, - "POLL": unix.SIGPOLL, - "PROF": unix.SIGPROF, - "PWR": unix.SIGPWR, - "QUIT": unix.SIGQUIT, - "SEGV": unix.SIGSEGV, - "STKFLT": unix.SIGSTKFLT, - "STOP": unix.SIGSTOP, - "SYS": unix.SIGSYS, - "TERM": unix.SIGTERM, - "TRAP": unix.SIGTRAP, - "TSTP": unix.SIGTSTP, - "TTIN": unix.SIGTTIN, - "TTOU": unix.SIGTTOU, - "URG": unix.SIGURG, - "USR1": unix.SIGUSR1, - "USR2": unix.SIGUSR2, - "VTALRM": unix.SIGVTALRM, - "WINCH": unix.SIGWINCH, - "XCPU": unix.SIGXCPU, - "XFSZ": unix.SIGXFSZ, -} - -func parseSignal(sig string) (unix.Signal, error) { +func parseSignal(sig string) unix.Signal { + if sig == "" { + return unix.SIGTERM + } // handle numerical signal value if num, err := strconv.Atoi(sig); err == nil { - for _, signum := range signalMap { - if num == int(signum) { - return signum, nil - } - } - return sigzero, fmt.Errorf("signal %q is not supported", sig) + return unix.Signal(num) } // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' - s := strings.TrimPrefix(strings.ToUpper(sig), "SIG") - signum, exists := signalMap[s] - if !exists { - return sigzero, fmt.Errorf("signal %q not supported", sig) + s := strings.ToUpper(sig) + if !strings.HasPrefix(s, "SIG") { + s = "SIG" + s } - return signum, nil + return unix.SignalNum(s) } func doKill(ctx *cli.Context) error { sig := ctx.Args().Get(1) - if len(sig) == 0 { - return errors.New("missing signal") + signum := parseSignal(sig) + if signum == 0 { + return fmt.Errorf("invalid signal param %q", sig) } - signum, err := parseSignal(sig) + err := clxc.loadContainer() if err != nil { - return errors.Wrap(err, "invalid signal param") + return errors.Wrap(err, "failed to load container") } - err = clxc.loadContainer() + state, err := clxc.getContainerState() if err != nil { - return errors.Wrap(err, "failed to load container") + return err + } + if !(state == StateCreated || state == StateRunning) { + return fmt.Errorf("can only kill container in state Created|Running but was %q", state) } return clxc.killContainer(signum) From 58ac8df42ac21ee30d56a8330b3beea05c366d9a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 30 Nov 2020 19:56:54 +0100 Subject: [PATCH 082/373] Fixed typo removed unused code. Signed-off-by: Ruben Jenster --- cmd/cgroup.go | 2 +- cmd/delete.go | 1 - cmd/state.go | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cmd/cgroup.go b/cmd/cgroup.go index d6620ed4..6f617687 100644 --- a/cmd/cgroup.go +++ b/cmd/cgroup.go @@ -323,7 +323,7 @@ func deleteCgroup(cgroupName string) error { p := filepath.Join(dirName, i.Name()) err := unix.Rmdir(p) if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", p).Msg("failed to remove ecgroup dir") + log.Warn().Err(err).Str("file", p).Msg("failed to remove cgroup dir") return err } } diff --git a/cmd/delete.go b/cmd/delete.go index 07f2ff19..d25aa2bd 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -29,7 +29,6 @@ func doDelete(ctx *cli.Context) error { err := clxc.loadContainer() if err == errContainerNotExist { return nil - //return clxc.destroy() } if err != nil { return err diff --git a/cmd/state.go b/cmd/state.go index 8944d902..cdd3d588 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -45,8 +45,6 @@ func doState(ctx *cli.Context) error { Annotations: spec.Annotations, } - //s.Annotations = spec.Annotations - state, err := clxc.getContainerState() s.Status = string(state) if err != nil { From 05dec2c8f66a9a44e19c0a311ce08f0b2137b545 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 30 Nov 2020 19:57:30 +0100 Subject: [PATCH 083/373] start: Check container state. Signed-off-by: Ruben Jenster --- cmd/start.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/start.go b/cmd/start.go index 333fd8a2..14fbad63 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -35,6 +35,14 @@ func doStart(ctx *cli.Context) error { return err } + state, err := clxc.getContainerState() + if err != nil { + return err + } + if state != StateCreated { + return fmt.Errorf("invalid container state. expected %q, but was %q", StateCreated, state) + } + done := make(chan error) go func() { done <- readFifo() From 18685a14b9102b57cc4cbf1fe66c571e36ca3092 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 30 Nov 2020 20:43:22 +0100 Subject: [PATCH 084/373] exec: Fail with exit code from executed cmd when running attached. Signed-off-by: Ruben Jenster --- cmd/exec.go | 15 +++++++++++---- cmd/main.go | 11 ++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/cmd/exec.go b/cmd/exec.go index f472709e..15f50144 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -13,6 +13,15 @@ import ( lxc "gopkg.in/lxc/go-lxc.v2" ) +type execError struct { + Err error + ExitStatus int +} + +func (e execError) Error() string { + return fmt.Sprintf("cmd exited with status %d: %s", e.ExitStatus, e.Err) +} + var execCmd = cli.Command{ Name: "exec", Usage: "execute a new process in a running container", @@ -124,10 +133,8 @@ func doExec(ctx *cli.Context) error { } exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) - if err != nil { - return errors.Wrapf(err, "c.RunCommandStatus returned with exit code %d", exitStatus) + if err != nil || exitStatus != 0 { + return execError{err, exitStatus} } - log.Debug().Int("exit", exitStatus).Msg("cmd terminated") - return nil } diff --git a/cmd/main.go b/cmd/main.go index f47c4db0..7bcced6c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -236,10 +236,15 @@ func main() { if err := clxc.release(); err != nil { log.Error().Err(err).Msg("failed to release container") } + if err != nil { - // write diagnostics message to stderr for crio/kubelet - println(err.Error()) - os.Exit(1) + if err, yes := err.(execError); yes { + os.Exit(err.ExitStatus) + } else { + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) + os.Exit(1) + } } } From fa9f0fd6bed61f1be18c5ba2854ee07a59517545 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 02:45:36 +0100 Subject: [PATCH 085/373] Refactor init. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 7 - cmd/create.go | 161 +---------------- cmd/init.go | 167 ++++++++++++++++++ cmd/init/Makefile | 7 + cmd/init/crio-lxc-init.c | 369 ++++++++++++++++++++------------------- cmd/init/test.bats | 31 ++++ cmd/start.go | 2 +- 7 files changed, 397 insertions(+), 347 deletions(-) create mode 100644 cmd/init.go create mode 100644 cmd/init/Makefile create mode 100644 cmd/init/test.bats diff --git a/cmd/clxc.go b/cmd/clxc.go index 5ac8beda..a6ea46ca 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -26,13 +26,6 @@ const ( timeFormatLXCMillis = "20060102150405.000" defaultContainerLogLevel = lxc.WARN defaultLogLevel = zerolog.WarnLevel - - // ConfigDir is the path to the crio-lxc resources relative to the container rootfs. - configDir = "/.crio-lxc" - // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. - syncFifoPath = configDir + "/syncfifo" - // InitCmd is the path where the init binary is bind mounted. - initCmd = configDir + "/init" ) // ContainerState represents the state of a container. diff --git a/cmd/create.go b/cmd/create.go index 28ebe05e..e6b8b7be 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -7,7 +7,6 @@ import ( "os/exec" "path/filepath" "runtime" - "strconv" "strings" "time" @@ -92,14 +91,6 @@ func doCreateInternal(ctx *cli.Context) error { return errors.Wrap(err, "failed to configure container") } - if err := writeCmdline(clxc.runtimePath("/.crio-lxc/cmdline.txt"), spec); err != nil { - return err - } - - if err := writeEnviron(clxc.runtimePath("/.crio-lxc/environ"), spec); err != nil { - return err - } - // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) if err := runStartCmd(startCmd, spec); err != nil { @@ -110,54 +101,16 @@ func doCreateInternal(ctx *cli.Context) error { return clxc.createPidFile(startCmd.Process.Pid) } -func writeCmdline(cmdFile string, spec *specs.Spec) error { - // #nosec - f, err := os.OpenFile(cmdFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) - if err != nil { - return errors.Wrap(err, "failed to create the cmd file") - } - for _, arg := range spec.Process.Args { - fmt.Fprintln(f, arg) - } - if err := f.Close(); err != nil { - return err - } - if err := unix.Chown(cmdFile, int(spec.Process.User.UID), int(spec.Process.User.GID)); err != nil { - return err - } - return unix.Chmod(cmdFile, 0400) -} - -func writeEnviron(envFile string, spec *specs.Spec) error { - // #nosec - f, err := os.OpenFile(envFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) - if err != nil { +func configureContainer(spec *specs.Spec) error { + if err := configureRootfs(spec); err != nil { return err } - for _, arg := range spec.Process.Env { - _, err := f.WriteString(arg) - if err != nil { - f.Close() - return err - } - _, err = f.Write([]byte{'\000'}) - if err != nil { - f.Close() - return err - } - } - if err := f.Close(); err != nil { - return err - } - if err := unix.Chown(envFile, int(spec.Process.User.UID), int(spec.Process.User.GID)); err != nil { + // pass context information as environment variables to hook scripts + if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { return err } - return unix.Chmod(envFile, 0400) -} - -func configureContainer(spec *specs.Spec) error { - if err := configureRootfs(spec); err != nil { + if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { return err } @@ -213,38 +166,6 @@ func configureContainer(spec *specs.Spec) error { log.Warn().Msg("capabilities are disabled") } - // TODO extract all uid/gid related settings into separate function configureUserAndGroups - if err := clxc.setConfigItem("lxc.init.uid", fmt.Sprintf("%d", spec.Process.User.UID)); err != nil { - return err - } - if err := clxc.setConfigItem("lxc.init.gid", fmt.Sprintf("%d", spec.Process.User.GID)); err != nil { - return err - } - - // TODO ensure that the user namespace is enabled - // See `man lxc.container.conf` lxc.idmap. - for _, m := range spec.Linux.UIDMappings { - if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { - return err - } - } - - for _, m := range spec.Linux.GIDMappings { - if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { - return err - } - } - - if len(spec.Process.User.AdditionalGids) > 0 && supportsConfigItem("lxc.init.groups") { - a := make([]string, 0, len(spec.Process.User.AdditionalGids)) - for _, gid := range spec.Process.User.AdditionalGids { - a = append(a, strconv.FormatUint(uint64(gid), 10)) - } - if err := clxc.setConfigItem("lxc.init.groups", strings.Join(a, " ")); err != nil { - return err - } - } - if err := setHostname(spec); err != nil { return errors.Wrap(err, "set hostname") } @@ -303,65 +224,6 @@ func configureRootfs(spec *specs.Spec) error { return nil } -func configureInit(spec *specs.Spec) error { - err := os.MkdirAll(filepath.Join(spec.Root.Path, configDir), 0) - if err != nil { - return errors.Wrapf(err, "Failed creating %s in rootfs", configDir) - } - // #nosec - err = os.MkdirAll(clxc.runtimePath(configDir), 0755) - if err != nil { - return errors.Wrapf(err, "Failed creating %s in lxc container dir", configDir) - } - - // create named fifo in lxcpath and mount it into the container - if err := makeSyncFifo(clxc.runtimePath(syncFifoPath)); err != nil { - return errors.Wrapf(err, "failed to make sync fifo") - } - - spec.Mounts = append(spec.Mounts, specs.Mount{ - Source: clxc.runtimePath(configDir), - Destination: strings.Trim(configDir, "/"), - Type: "bind", - Options: []string{"bind", "ro", "nodev", "nosuid"}, - }) - - // pass context information as environment variables to hook scripts - if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { - return err - } - if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { - return err - } - - if err := clxc.setConfigItem("lxc.init.cwd", spec.Process.Cwd); err != nil { - return err - } - - // create destination file for bind mount - initBin := clxc.runtimePath(initCmd) - err = touchFile(initBin, 0) - if err != nil { - return errors.Wrapf(err, "failed to create %s", initBin) - } - spec.Mounts = append(spec.Mounts, specs.Mount{ - Source: clxc.InitCommand, - Destination: initCmd, - Type: "bind", - Options: []string{"bind", "ro", "nosuid"}, - }) - return clxc.setConfigItem("lxc.init.cmd", initCmd+" "+clxc.ContainerID) -} - -func touchFile(filePath string, perm os.FileMode) error { - // #nosec - f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDONLY, perm) - if err == nil { - return f.Close() - } - return err -} - func configureReadonlyPaths(spec *specs.Spec) error { rootmnt := clxc.getConfigItem("lxc.rootfs.mount") if rootmnt == "" { @@ -376,19 +238,6 @@ func configureReadonlyPaths(spec *specs.Spec) error { return nil } -func makeSyncFifo(fifoFilename string) error { - prevMask := unix.Umask(0000) - defer unix.Umask(prevMask) - if err := unix.Mkfifo(fifoFilename, 0666); err != nil { - return errors.Wrapf(err, "failed to make fifo '%s'", fifoFilename) - } - return nil -} - -func configureContainerSecurity(c *lxc.Container, spec *specs.Spec) error { - return nil -} - func configureApparmor(spec *specs.Spec) error { // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. aaprofile := spec.Process.ApparmorProfile diff --git a/cmd/init.go b/cmd/init.go new file mode 100644 index 00000000..09a7dc7b --- /dev/null +++ b/cmd/init.go @@ -0,0 +1,167 @@ +package main + +import ( + "fmt" + "github.com/pkg/errors" + "golang.org/x/sys/unix" + "os" + "path/filepath" + "strings" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +const ( + // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. + initDir = "/.crio-lxc" +) + +func syncFifoPath() string { + return clxc.runtimePath(initDir, "syncfifo") +} + +func createFifo(dst string, uid int, gid int, mode uint32) error { + //prevMask := unix.Umask(0000) // ? + //defer unix.Umask(prevMask) // ? + if err := unix.Mkfifo(dst, mode); err != nil { + return err + } + return unix.Chown(dst, uid, gid) +} + +func configureInit(spec *specs.Spec) error { + runtimeInitDir := clxc.runtimePath(initDir) + rootfsInitDir := filepath.Join(spec.Root.Path, initDir) + + err := os.MkdirAll(rootfsInitDir, 0) + if err != nil { + return errors.Wrapf(err, "failed to create init dir in rootfs %q", rootfsInitDir) + } + // #nosec + err = os.MkdirAll(runtimeInitDir, 0755) + if err != nil { + return errors.Wrapf(err, "failed to create runtime init dir %q", runtimeInitDir) + } + + spec.Mounts = append(spec.Mounts, specs.Mount{ + Source: runtimeInitDir, + Destination: strings.TrimLeft(initDir, "/"), + Type: "bind", + Options: []string{"bind", "ro", "nodev", "nosuid"}, + }) + + if err := clxc.setConfigItem("lxc.init.cwd", initDir); err != nil { + return err + } + + uid := int(spec.Process.User.UID) + gid := int(spec.Process.User.GID) + + // create files required for crio-lxc-init + if err := createFifo(syncFifoPath(), uid, gid, 0600); err != nil { + return errors.Wrapf(err, "failed to create sync fifo") + } + + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), spec.Process.Args, uid, gid, 0400); err != nil { + return err + } + if err := createList(filepath.Join(runtimeInitDir, "environ"), spec.Process.Env, uid, gid, 0400); err != nil { + return err + } + if err := os.Symlink(spec.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { + return err + } + + if err := configureInitUser(spec); err != nil { + return err + } + + // bind mount crio-lxc-init into the container + initCmdPath := filepath.Join(runtimeInitDir, "init") + err = touchFile(initCmdPath, 0) + if err != nil { + return errors.Wrapf(err, "failed to create %s", initCmdPath) + } + initCmd := filepath.Join(initDir, "init") + spec.Mounts = append(spec.Mounts, specs.Mount{ + Source: clxc.InitCommand, + Destination: strings.TrimLeft(initCmd, "/"), + Type: "bind", + Options: []string{"bind", "ro", "nosuid"}, + }) + return clxc.setConfigItem("lxc.init.cmd", initCmd+" "+clxc.ContainerID) +} + +func touchFile(filePath string, perm os.FileMode) error { + // #nosec + f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDONLY, perm) + if err == nil { + return f.Close() + } + return err +} + +func createList(dst string, entries []string, uid int, gid int, mode uint32) error { + // #nosec + f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) + if err != nil { + return errors.Wrapf(err, "failed to create init list %s", dst) + } + + for _, arg := range entries { + _, err := f.WriteString(arg) + if err != nil { + f.Close() + return err + } + _, err = f.Write([]byte{'\000'}) + if err != nil { + f.Close() + return err + } + } + if err := f.Close(); err != nil { + return err + } + if err := unix.Chown(dst, uid, gid); err != nil { + return err + } + return unix.Chmod(dst, mode) +} + +func configureInitUser(spec *specs.Spec) error { + // TODO ensure that the user namespace is enabled + // See `man lxc.container.conf` lxc.idmap. + for _, m := range spec.Linux.UIDMappings { + if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + return err + } + } + + for _, m := range spec.Linux.GIDMappings { + if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + return err + } + } + + if err := clxc.setConfigItem("lxc.init.uid", fmt.Sprintf("%d", spec.Process.User.UID)); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.init.gid", fmt.Sprintf("%d", spec.Process.User.GID)); err != nil { + return err + } + + if len(spec.Process.User.AdditionalGids) > 0 && supportsConfigItem("lxc.init.groups") { + var b strings.Builder + for i, gid := range spec.Process.User.AdditionalGids { + if i > 0 { + b.WriteByte(' ') + } + fmt.Fprintf(&b, "%d", gid) + } + if err := clxc.setConfigItem("lxc.init.groups", b.String()); err != nil { + return err + } + } + return nil +} diff --git a/cmd/init/Makefile b/cmd/init/Makefile new file mode 100644 index 00000000..a50d18f6 --- /dev/null +++ b/cmd/init/Makefile @@ -0,0 +1,7 @@ +all: crio-lxc-init + +crio-lxc-init: crio-lxc-init.c + /usr/local/musl/bin/musl-gcc -Wpedantic -Wall -static -g -o $@ $? + #musl-gcc -g3 -Wall -static $? -o $@ + # ensure that crio-lxc-init is statically compiled + ! ldd $@ 2>/dev/null diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index b8b0aac5..d2bea6d9 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -1,205 +1,208 @@ #define _GNU_SOURCE -#include -#include -#include +#include #include -#include +#include #include -#include +#include #include +#include #include -#include - -#ifndef PREFIX -#define PREFIX "/.crio-lxc/" -#endif - -#define runtime_path(NAME) PREFIX NAME +#include +#include -const char* syncfifo = runtime_path("syncfifo"); -const char* cmdline_path = runtime_path("cmdline.txt"); -const char* environ_path = runtime_path("environ"); +const char *syncfifo_path = "syncfifo"; +const char *cmdline_path = "cmdline"; +const char *environ_path = "environ"; -int writefifo(const char* fifo, const char*msg) { - int fd; +int writefifo(const char *fifo, const char *msg) +{ + int fd; -#ifdef DEBUG - printf("writing fifo %s\n", fifo); -#endif + // Open FIFO for write only + fd = open(fifo, O_WRONLY | O_CLOEXEC); + if (fd == -1) + return -1; - // Open FIFO for write only - fd = open(fifo, O_WRONLY | O_CLOEXEC); - if (fd == -1) - return -1; + if (write(fd, msg, strlen(msg)) == -1) + return -1; - if (write(fd, msg, strlen(msg)) == -1) - return -1; - - return close(fd); + return close(fd); } /* reads up to maxlines-1 lines from path into lines */ -int readlines(const char* path, char *buf, int buflen, char **lines, int maxlines) { - FILE *f; - char *line; - int n; - -#ifdef DEBUG - printf("reading lines from %s buflen:%d maxlines:%d\n", path, buflen, maxlines); -#endif - - // FIXME open file with O_CLOEXEC - - f = fopen(path, "r"); - if(f == NULL) - return -1; - - errno = 0; - for(n = 0; n < maxlines-1; n++) { - // https://pubs.opengroup.org/onlinepubs/009696699/functions/fgets.html - line = fgets(buf, buflen, f); - if (line == NULL) - break; - // line gets truncated if it is longer than buflen ? - lines[n] = strndup(line, strlen(line)-1); - } - if (errno != 0) - return -1; - - if (fclose(f) != 0) - return -1; - - lines[n] = (char *) NULL; - return n; +int load_cmdline(const char *path, char *buf, int buflen, char **lines, int maxlines) +{ + int fd; + FILE *f; + int n = 0; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) + return 200; + + f = fdopen(fd, "r"); + if (f == NULL) + return 201; + + for (n = 0; n < maxlines - 1; n++) { + char c; + int i; + // read until next '\0' or EOF + for (i = 0; i < buflen; i++) { + c = getc(f); + if (c == EOF) { + break; + } + buf[i] = c; + if (c == '\0') + break; + } + + if (errno != 0) // getc failed + return 202; + + if (c == EOF) { + if (i > 0) // trailing garbage + return 203; + lines[n] = (char *)NULL; + break; + } + + lines[n] = strndup(buf, i); + if (errno != 0) // strndup failed + return 204; + } + // empty cmdline + if (n < 1) + return 205; + + return 0; } - // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 -int load_environment(const char* path, char *buf, int buflen) { - FILE *f; - -#ifdef DEBUG - printf("reading env from %s buflen:%d\n", path, buflen); -#endif - - f = fopen(path, "r"); - if(f == NULL) - return -1; - - char c; - - while(c != EOF) { - char *value = NULL; - - for(int i = 0; i < buflen; i++) { - c = getc(f); - if (c == EOF) { - // we should have receive a '\0' before - buf[i] = '\0'; - break; - } - - buf[i] = c; - if (c == '\0') - break; - - // buffer is full but we did neither receive '\0' nor EOF before - if (i == buflen-1) { - //errno = E2BIG; - errno = 31; - goto out; - } - - // terminate enviornment key - // the checks above ensure that we are not at the end of the buffer here - if (value == NULL && c == '=') { - buf[i] = '\0'; - value = buf + ( i+1 ); - } - } - if (errno != 0) { - errno = 32; - goto out; - } - - // 'foo=' - if (value == NULL) { - errno = 33; - errno = EINVAL; - goto out; - } -#ifdef DEBUG - printf("setenv %s\n", buf); -#endif - if (setenv(buf, value, 1) == -1) - goto out; - } - -out: - fclose(f); - return (errno != 0) ? errno : 0; +int load_environment(const char *path, char *buf, int buflen) +{ + int fd; + FILE *f; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) + return 210; + + f = fopen(path, "r"); + if (f == NULL) + return 211; + + for (;;) { + char *key = NULL; + char c; + int i; + // read until next '\0' or EOF + for (i = 0; i < buflen; i++) { + c = getc(f); + if (c == EOF) { + break; + } + buf[i] = c; + if (c == '\0') + break; + + // split at first '=' + if (key == NULL && c == '=') { + buf[i] = '\0'; + key = buf; + } + } + + if (errno != 0) // getc failed + return 212; + + if (c == EOF) { + if (i > 0) // trailing garbage + return 213; + break; + } + + // malformed variable + // e.g 'fooo\0' or 'fooo=\0' + if (key == NULL || i == strlen(key)) + return 214; + + if (setenv(key, buf + strlen(key) + 1, 0) == -1) + return 215; + } + return 0; } -int sethome() { - struct passwd *pw; - - if (getenv("HOME") != NULL) { - return 0; - } - pw = getpwuid(geteuid()); - if (pw != NULL) { - if (pw->pw_dir != NULL) - return setenv("HOME", pw->pw_dir, 0); - } - // This is best effort so we ignore the errno set by getpwuid. - if (errno != 0) - errno = 0; - return setenv("HOME", "/", 0); +void try_setenv_HOME() +{ + struct passwd *pw; + + if (getenv("HOME") != NULL) + return; + + pw = getpwuid(geteuid()); + if (pw != NULL && pw->pw_dir != NULL) + setenv("HOME", pw->pw_dir, 0); + else + setenv("HOME", "/", 0); + + // ignore errors + errno = 0; } -int main(int argc, char** argv) +int main(int argc, char **argv) { - // Buffer for reading arguments and environment variables. - // There is not a limit per environment variable, but we limit it to 1MiB here - // https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes - // For arguments "Additionally, the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF." - char buf[1024*1024]; - // see 'man 2 execve' 'Limits on size of arguments and environment' - // ... ARG_MAX constant (either defined in or available at run time using the call sysconf(_SC_ARG_MAX)) - char *args[256]; // > _POSIX_ARG_MAX+1 - - const char* cid; - - if (argc != 2) { - fprintf(stderr, "invalid number of arguments (expected 2 was %d) usage: %s \n", argc, argv[0]); - exit(1); - } - cid = argv[1]; - - if (readlines(cmdline_path, buf, sizeof(buf), args, sizeof(args)) == -1){ - perror("failed to read cmdline file"); - exit(2); - } - - // environment is already cleared by liblxc - //environ = NULL; - if (load_environment(environ_path, buf, sizeof(buf)) == -1){ - perror("failed to read environment file"); - if (errno == 0) - exit(3); - else - exit(errno); - } - - if (sethome() == -1) { - perror("failed to set HOME"); - exit(4); - } - - if (writefifo(syncfifo, cid) == -1) { - perror("failed to write syncfifo"); - exit(5); - } - - execvp(args[0],args); + // Buffer for reading arguments and environment variables. + // There is not a limit per environment variable, but we limit it to 1MiB here + // https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes + // For arguments "Additionally, the limit per string is 32 pages (the kernel + // constant MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF." + char buf[1024 * 1024]; + // see 'man 2 execve' 'Limits on size of arguments and environment' + // ... ARG_MAX constant (either defined in or available at + // run time using the call sysconf(_SC_ARG_MAX)) + char *args[256]; // > _POSIX_ARG_MAX+1 + + const char *cid; + + int ret = 0; + + if (argc != 2) { + fprintf(stderr, "invalid number of arguments %d\n", argc); + fprintf(stderr, "usage: %s \n", argv[0]); + exit(-1); + } + cid = argv[1]; + + // environment is already cleared by liblxc + // environ = NULL; + ret = load_environment(environ_path, buf, sizeof(buf)); + if (ret != 0) { + if (errno != 0) + fprintf(stderr, "error reading environment file \"%s\": %s\n", + environ_path, strerror(errno)); + exit(ret); + } + + ret = load_cmdline(cmdline_path, buf, sizeof(buf), args, sizeof(args)); + if (ret != 0) { + if (errno != 0) + fprintf(stderr, "error reading cmdline file \"%s\": %s\n", + cmdline_path, strerror(errno)); + exit(ret); + } + + try_setenv_HOME(); + + if (writefifo(syncfifo_path, cid) == -1) { + perror("failed to write syncfifo"); + exit(220); + } + + if (chdir("cwd") == -1) { + perror("failed to change working directory"); + exit(221); + } + execvp(args[0], args); } diff --git a/cmd/init/test.bats b/cmd/init/test.bats new file mode 100644 index 00000000..03579f86 --- /dev/null +++ b/cmd/init/test.bats @@ -0,0 +1,31 @@ +#!/usr/bin/env bats + +bin=$BATS_TEST_DIRNAME/crio-lxc-init + +cd_tmpdir () { + cd $BATS_TEST_DIRNAME +} + +myfoo() { + cd $BATS_TEST_DIRNAME + [ -f environ ] && rm environ + [ -f cmdline ] && rm cmdline + [ -f syncfifo ] && rm syncfifo +} + +#setup cd_tmpdir +teardown myfoo + + +@test "noon-existent environment file" { + #cd $BATS_TEST_DIRNAME + run $bin 12345 + echo $status + [ "$status" -eq 210 ] +} + +@test "non-existent environment file" { + #cd $BATS_TEST_DIRNAME + run $bin 12345 + [ "$status" -eq 210 ] +} diff --git a/cmd/start.go b/cmd/start.go index 14fbad63..b3975c86 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -58,7 +58,7 @@ func doStart(ctx *cli.Context) error { func readFifo() error { // #nosec - f, err := os.OpenFile(clxc.runtimePath(syncFifoPath), os.O_RDONLY, 0) + f, err := os.OpenFile(syncFifoPath(), os.O_RDONLY, 0) if err != nil { return errors.Wrap(err, "failed to open sync fifo") } From daf3767719d51e1adbeef83091d465d90ab0271f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 02:41:32 +0100 Subject: [PATCH 086/373] Container state fixes. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 116 +++++++++++++++++++++++++++++++++----------------- cmd/create.go | 5 +++ cmd/start.go | 2 + 3 files changed, 83 insertions(+), 40 deletions(-) diff --git a/cmd/clxc.go b/cmd/clxc.go index a6ea46ca..9143dd7e 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -400,6 +400,7 @@ func (c *crioLXC) configureLogging() error { // NOTE Unfortunately it's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 + //log = zerolog.New(c.LogFile).With().Timestamp().CallerWithSkipFrameCount(-1). log = zerolog.New(c.LogFile).With().Timestamp().Caller(). Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() @@ -483,7 +484,7 @@ func (c *crioLXC) executeRuntimeHook(runtimeError error) { // #nosec cmd := exec.CommandContext(ctx, c.RuntimeHook) cmd.Env = env - cmd.Dir = "/" + cmd.Dir = c.runtimePath() if err := cmd.Run(); err != nil { log.Error().Err(err).Str("file", c.RuntimeHook). Bool("timeout-expired", ctx.Err() == context.DeadlineExceeded).Msg("runtime hook failed") @@ -494,6 +495,40 @@ func (c *crioLXC) isContainerStopped() bool { return c.Container.State() == lxc.STOPPED } +func (c *crioLXC) waitCreated(timeout time.Duration) error { + if !c.Container.Wait(lxc.RUNNING, timeout) { + return fmt.Errorf("timeout starting init cmd") + } + + initState, err := c.getContainerInitState() + if err != nil { + return err + } + if initState != StateCreated { + return fmt.Errorf("unexpected init state %q", initState) + } + return nil +} + +func (c *crioLXC) waitRunning(timeout time.Duration) error { + deadline := time.Now().Add(timeout) + for time.Now().Before(deadline) { + initState, err := c.getContainerInitState() + if err != nil { + return err + } + if initState == StateRunning { + return nil + } + if initState == StateCreated { + time.Sleep(time.Millisecond * 10) + continue + } + return fmt.Errorf("unexpected init state %q", initState) + } + return fmt.Errorf("timeout") +} + // getContainerInitState returns the runtime state of the container. // It is used to determine whether the container state is 'created' or 'running'. // The init process environment contains #envStateCreated if the the container @@ -506,14 +541,21 @@ func (c *crioLXC) getContainerState() (ContainerState, error) { return StateStopped, nil case lxc.STARTING: return StateCreating, nil + case lxc.RUNNING, lxc.STOPPING, lxc.ABORTING, lxc.FREEZING, lxc.FROZEN, lxc.THAWED: + return c.getContainerInitState() + default: + return StateStopped, fmt.Errorf("unsupported lxc container state %q", state) } - // RUNNING, STOPPING, ABORTING, FREEZING, FROZEN, THAWED: - pid := c.Container.InitPid() - if pid < 0 { - return StateCreating, nil - } +} - commPath := fmt.Sprintf("/proc/%d/cmdline", pid) +// getContainerInitState returns the detailed state of the container init process. +// If the init process is not running StateStopped is returned along with an error. +func (c *crioLXC) getContainerInitState() (ContainerState, error) { + initPid := c.Container.InitPid() + if initPid < 1 { + return StateStopped, fmt.Errorf("init cmd is not running") + } + commPath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := ioutil.ReadFile(commPath) if err != nil { // can not determine state, caller may try again @@ -526,7 +568,6 @@ func (c *crioLXC) getContainerState() (ContainerState, error) { //if strings.HasPrefix(c.ContainerID, strings.TrimSpace(string(comm))) { return StateCreated, nil } - return StateRunning, nil } @@ -573,12 +614,6 @@ func enableCgroupControllers(cg string) error { } func (c *crioLXC) killContainer(signum unix.Signal) error { - pid, err := c.readPidFile() - if err != nil && !os.IsNotExist(err) { - return errors.Wrapf(err, "failed to load pidfile") - } - log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - if signum == unix.SIGKILL || signum == unix.SIGTERM { if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { return err @@ -587,28 +622,42 @@ func (c *crioLXC) killContainer(signum unix.Signal) error { return err } if !c.Container.Wait(lxc.STOPPED, time.Second*10) { - log.Warn().Msg("failed to stop lxc container - sending kill") + log.Warn().Msg("failed to stop lxc container") } - } - - // TODO wait for the monitor process to die ? - // kill remaining processes within the cgroup - if err := unix.Kill(pid, 0); err == nil { - err := unix.Kill(pid, signum) - if err != unix.ESRCH { - return errors.Wrap(err, "failed to kill container process") + // draining the cgroup is required to catch processes that escaped from the + // 'kill' e.g a bash for loop that spawns a new child immediately. + start := time.Now() + err := drainCgroup(c.CgroupDir, signum, time.Second*10) + if err != nil && !os.IsNotExist(err) { + log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + } else { + log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") } + return err } - err = killCgroupProcs(c.CgroupDir, signum) + // send non-terminating signals to monitor process + pid, err := c.readPidFile() if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Msg("failed to kill cgroup procs") + return errors.Wrapf(err, "failed to load pidfile") + } + if pid > 1 { + log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") + if err := unix.Kill(pid, 0); err == nil { + err := unix.Kill(pid, signum) + if err != unix.ESRCH { + return errors.Wrapf(err, "failed to send signal %d to container process %d", signum, pid) + } + } } - return nil } +// "Note that resources associated with the container, +// but not created by this container, MUST NOT be deleted." +// TODO - because we set rootfs.managed=0, Destroy() doesn't +// delete the /var/lib/lxc/$containerID/config file: func (c *crioLXC) destroy() error { if c.Container != nil { if err := c.Container.Destroy(); err != nil { @@ -616,23 +665,10 @@ func (c *crioLXC) destroy() error { } } - start := time.Now() - err := drainCgroup(c.CgroupDir, unix.SIGKILL, time.Second*10) - if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") - } else { - log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") - } - - err = deleteCgroup(c.CgroupDir) + err := deleteCgroup(c.CgroupDir) if err != nil && !os.IsNotExist(err) { log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") } - // "Note that resources associated with the container, - // but not created by this container, MUST NOT be deleted." - // TODO - because we set rootfs.managed=0, Destroy() doesn't - // delete the /var/lib/lxc/$containerID/config file: - return os.RemoveAll(c.runtimePath()) } diff --git a/cmd/create.go b/cmd/create.go index e6b8b7be..10a1fbcf 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -98,6 +98,11 @@ func doCreateInternal(ctx *cli.Context) error { } log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + if err := clxc.waitCreated(time.Second * 10); err != nil { + log.Error().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + return err + } + return clxc.createPidFile(startCmd.Process.Pid) } diff --git a/cmd/start.go b/cmd/start.go index b3975c86..7dcdc922 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -54,6 +54,8 @@ func doStart(ctx *cli.Context) error { case <-time.After(clxc.StartTimeout): return fmt.Errorf("timeout reading from syncfifo") } + + return clxc.waitRunning(time.Second * 5) } func readFifo() error { From 118ca53e1b3ba88172a445913aa44a9b2092e8ec Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 01:32:34 +0100 Subject: [PATCH 087/373] exec: Fix exit code. Signed-off-by: Ruben Jenster --- cmd/exec.go | 23 +++++++++++++---------- cmd/main.go | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cmd/exec.go b/cmd/exec.go index 15f50144..b070e41b 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io/ioutil" - "os" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -13,13 +12,14 @@ import ( lxc "gopkg.in/lxc/go-lxc.v2" ) -type execError struct { - Err error - ExitStatus int +type execError int + +func (e execError) ExitStatus() int { + return int(e) } func (e execError) Error() string { - return fmt.Sprintf("cmd exited with status %d: %s", e.ExitStatus, e.Err) + return fmt.Sprintf("exec cmd exited with status %d", int(e)) } var execCmd = cli.Command{ @@ -108,9 +108,9 @@ func doExec(ctx *cli.Context) error { attachOpts.Namespaces |= n.CloneFlag } - attachOpts.StdinFd = os.Stdin.Fd() - attachOpts.StdoutFd = os.Stdout.Fd() - attachOpts.StderrFd = os.Stderr.Fd() + attachOpts.StdinFd = 0 + attachOpts.StdoutFd = 1 + attachOpts.StderrFd = 2 detach := ctx.Bool("detach") @@ -133,8 +133,11 @@ func doExec(ctx *cli.Context) error { } exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) - if err != nil || exitStatus != 0 { - return execError{err, exitStatus} + if err != nil { + return err + } + if exitStatus != 0 { + return execError(exitStatus) } return nil } diff --git a/cmd/main.go b/cmd/main.go index 7bcced6c..f8827cd5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -239,7 +239,7 @@ func main() { if err != nil { if err, yes := err.(execError); yes { - os.Exit(err.ExitStatus) + os.Exit(err.ExitStatus()) } else { // write diagnostics message to stderr for crio/kubelet println(err.Error()) From 0186ed4f569a54198288b22804a295e4330d3650 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 01:34:14 +0100 Subject: [PATCH 088/373] init: Fix exit code if execvp failed. Overwrite environment variables, clear environment. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 42 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index d2bea6d9..b686fce6 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -14,6 +14,18 @@ const char *syncfifo_path = "syncfifo"; const char *cmdline_path = "cmdline"; const char *environ_path = "environ"; +// A conformance test that will fail if SETENV_OVERWRITE is set to 0 +// is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] should have a working scale subresource [Conformance]" +// In the spec two conflicting PATH environment variables are defined. +// The container image 'httpd:2.4.38-alpine' only defines the second. +// +// This value must be set to control the behaviour for conflicting environment variables: +// SETENV_OVERWRITE=0 the variable that is defined first takes precedence +// SETENV_OVERWRITE=1 the variable that is defined last overwrites all previous definitions +#ifndef SETENV_OVERWRITE +#define SETENV_OVERWRITE 1 +#endif + int writefifo(const char *fifo, const char *msg) { int fd; @@ -123,29 +135,28 @@ int load_environment(const char *path, char *buf, int buflen) break; } - // malformed variable - // e.g 'fooo\0' or 'fooo=\0' + // malformed content e.g + // e.g 'fooo\0' or 'fooo=' if (key == NULL || i == strlen(key)) return 214; - if (setenv(key, buf + strlen(key) + 1, 0) == -1) + if (setenv(key, buf + strlen(key) + 1, SETENV_OVERWRITE) == -1) return 215; } return 0; } -void try_setenv_HOME() +// Ensure_HOME_exists sets the HOME environment variable if it is not set. +// E.g this is required for running 'cilium v1.9.0' +void ensure_HOME_exists() { struct passwd *pw; - if (getenv("HOME") != NULL) - return; - pw = getpwuid(geteuid()); if (pw != NULL && pw->pw_dir != NULL) setenv("HOME", pw->pw_dir, 0); else - setenv("HOME", "/", 0); + setenv("HOME", "/", 0); // required for cilium to work // ignore errors errno = 0; @@ -175,8 +186,9 @@ int main(int argc, char **argv) } cid = argv[1]; - // environment is already cleared by liblxc - // environ = NULL; + // clear environment + environ = NULL; + ret = load_environment(environ_path, buf, sizeof(buf)); if (ret != 0) { if (errno != 0) @@ -192,8 +204,8 @@ int main(int argc, char **argv) cmdline_path, strerror(errno)); exit(ret); } - - try_setenv_HOME(); + + ensure_HOME_exists(); if (writefifo(syncfifo_path, cid) == -1) { perror("failed to write syncfifo"); @@ -204,5 +216,9 @@ int main(int argc, char **argv) perror("failed to change working directory"); exit(221); } - execvp(args[0], args); + + if (execvp(args[0], args) == -1) { + fprintf(stderr, "failed to exec \"%s\": %s\n", args[0], strerror(errno)); + exit(222); + } } From 0421b29706ce22c764c198f470624030a588fe76 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 01:48:30 +0100 Subject: [PATCH 089/373] init: clang format Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index b686fce6..2f9a3afa 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -14,14 +14,16 @@ const char *syncfifo_path = "syncfifo"; const char *cmdline_path = "cmdline"; const char *environ_path = "environ"; -// A conformance test that will fail if SETENV_OVERWRITE is set to 0 -// is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] should have a working scale subresource [Conformance]" -// In the spec two conflicting PATH environment variables are defined. -// The container image 'httpd:2.4.38-alpine' only defines the second. +// A conformance test that will fail if SETENV_OVERWRITE is set to 0 +// is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] +// should have a working scale subresource [Conformance]" In the spec two +// conflicting PATH environment variables are defined. The container image +// 'httpd:2.4.38-alpine' only defines the second. // -// This value must be set to control the behaviour for conflicting environment variables: -// SETENV_OVERWRITE=0 the variable that is defined first takes precedence -// SETENV_OVERWRITE=1 the variable that is defined last overwrites all previous definitions +// This value must be set to control the behaviour for conflicting environment +// variables: SETENV_OVERWRITE=0 the variable that is defined first takes +// precedence SETENV_OVERWRITE=1 the variable that is defined last overwrites +// all previous definitions #ifndef SETENV_OVERWRITE #define SETENV_OVERWRITE 1 #endif @@ -186,7 +188,7 @@ int main(int argc, char **argv) } cid = argv[1]; - // clear environment + // clear environment environ = NULL; ret = load_environment(environ_path, buf, sizeof(buf)); @@ -204,7 +206,7 @@ int main(int argc, char **argv) cmdline_path, strerror(errno)); exit(ret); } - + ensure_HOME_exists(); if (writefifo(syncfifo_path, cid) == -1) { @@ -216,9 +218,9 @@ int main(int argc, char **argv) perror("failed to change working directory"); exit(221); } - - if (execvp(args[0], args) == -1) { + + if (execvp(args[0], args) == -1) { fprintf(stderr, "failed to exec \"%s\": %s\n", args[0], strerror(errno)); - exit(222); - } + exit(222); + } } From c19611a1b9c9ec2288be560cdc216c95618801c2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 11:38:17 +0100 Subject: [PATCH 090/373] refactor: Rename crioLXC to Runtime. Signed-off-by: Ruben Jenster --- cmd/clxc.go | 276 ++++++++++++++++------------------------------- cmd/container.go | 112 +++++++++++++++++++ cmd/create.go | 12 +-- cmd/exec.go | 2 +- cmd/init.go | 4 +- cmd/seccomp.go | 2 +- cmd/state.go | 4 +- 7 files changed, 215 insertions(+), 197 deletions(-) create mode 100644 cmd/container.go diff --git a/cmd/clxc.go b/cmd/clxc.go index 9143dd7e..0651a393 100644 --- a/cmd/clxc.go +++ b/cmd/clxc.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "fmt" "github.com/pkg/errors" "golang.org/x/sys/unix" @@ -47,20 +46,25 @@ const ( ) // The singelton that wraps the lxc.Container -var clxc crioLXC +var clxc Runtime var log zerolog.Logger var errContainerNotExist = errors.New("container does not exist") var errContainerExist = errors.New("container already exists") -type crioLXC struct { +var version string + +func versionString() string { + return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) +} + +type Runtime struct { Container *lxc.Container + ContainerInfo Command string // [ global settings ] - RuntimeRoot string - ContainerID string LogFile *os.File LogFilePath string LogLevel string @@ -75,127 +79,28 @@ type crioLXC struct { RuntimeHookTimeout time.Duration RuntimeHookRunAlways bool - // feature gates - Seccomp bool - Capabilities bool - Apparmor bool - CgroupDevices bool - // create flags ConsoleSocketTimeout time.Duration // start flags StartTimeout time.Duration - - bundleConfig -} - -type bundleConfig struct { - BundlePath string - SpecPath string // BundlePath + "/config.json" - PidFile string - ConsoleSocket string - MonitorCgroupDir string - // values derived from spec - CgroupDir string -} - -var version string - -func versionString() string { - return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) -} - -// runtimePath builds an absolute filepath which is relative to the container runtime root. -func (c *crioLXC) runtimePath(subPath ...string) string { - return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) -} -func (c *crioLXC) bundlePath(subPath ...string) string { - return filepath.Join(c.BundlePath, filepath.Join(subPath...)) -} - -func (c *crioLXC) configFilePath() string { - return c.runtimePath("config") -} - -func (c *crioLXC) readPidFile() (int, error) { - // #nosec - data, err := ioutil.ReadFile(c.PidFile) - if err != nil { - return 0, err - } - s := strings.TrimSpace(string(data)) - return strconv.Atoi(s) -} - -func (c *crioLXC) createPidFile(pid int) error { - return createPidFile(c.PidFile, pid) -} - -// ReadSpec deserializes the JSON encoded runtime spec from the given path. -func (c *crioLXC) readSpec() (*specs.Spec, error) { - // #nosec - // FIXME set this once - c.SpecPath = c.bundlePath("config.json") - - specFile, err := os.Open(c.SpecPath) - if err != nil { - return nil, err - } - // #nosec - defer specFile.Close() - spec := &specs.Spec{} - err = json.NewDecoder(specFile).Decode(spec) - if err != nil { - return nil, err - } - - return spec, nil -} - -// loadContainer checks for the existence of the lxc config file. -// It returns an error if the config file does not exist. -func (c *crioLXC) loadContainer() error { - _, err := os.Stat(c.configFilePath()) - if os.IsNotExist(err) { - return errContainerNotExist - } - if err != nil { - return errors.Wrap(err, "failed to access config file") - } - - container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) - if err != nil { - return errors.Wrap(err, "failed to load container") - } - err = container.LoadConfigFile(c.configFilePath()) - if err != nil { - return errors.Wrap(err, "failed to load config file") - } - c.Container = container - - if err := c.setContainerLogLevel(); err != nil { - return err - } - - return c.readBundleConfig() } // createContainer creates a new container. // It must only be called once during the lifecycle of a container. -func (c *crioLXC) createContainer(spec *specs.Spec) error { - if _, err := os.Stat(c.configFilePath()); err == nil { +func (c *Runtime) createContainer(spec *specs.Spec) error { + if _, err := os.Stat(c.ConfigFilePath()); err == nil { return errContainerExist } - if err := os.MkdirAll(c.runtimePath(), 0700); err != nil { + if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } // An empty tmpfile is created to ensure that createContainer can only succeed once. // The config file is atomically activated in saveConfig. // #nosec - f, err := os.OpenFile(c.runtimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) if err != nil { return err } @@ -218,7 +123,9 @@ func (c *crioLXC) createContainer(spec *specs.Spec) error { return err } - if err := c.writeBundleConfig(); err != nil { + c.CreatedAt = time.Now() + + if err := c.ContainerInfo.Create(); err != nil { return err } @@ -230,7 +137,36 @@ func (c *crioLXC) createContainer(spec *specs.Spec) error { return c.setContainerLogLevel() } -func (c *crioLXC) configureCgroupPath() error { +// loadContainer checks for the existence of the lxc config file. +// It returns an error if the config file does not exist. +func (c *Runtime) loadContainer() error { + + if err := c.ContainerInfo.Load(); err != nil { + return err + } + + _, err := os.Stat(c.ConfigFilePath()) + if os.IsNotExist(err) { + return errContainerNotExist + } + if err != nil { + return errors.Wrap(err, "failed to access config file") + } + + container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) + if err != nil { + return errors.Wrap(err, "failed to load container") + } + err = container.LoadConfigFile(c.ConfigFilePath()) + if err != nil { + return errors.Wrap(err, "failed to load config file") + } + c.Container = container + + return c.setContainerLogLevel() +} + +func (c *Runtime) configureCgroupPath() error { if err := c.setConfigItem("lxc.cgroup.relative", "0"); err != nil { return err } @@ -269,63 +205,8 @@ func (c *crioLXC) configureCgroupPath() error { return nil } -func (c *crioLXC) readBundleConfig() error { - p := c.runtimePath("bundle.json") - data, err := ioutil.ReadFile(p) - if err != nil { - return errors.Wrapf(err, "failed to read bundle config file %s", p) - } - err = json.Unmarshal(data, &c.bundleConfig) - if err != nil { - return errors.Wrap(err, "failed to unmarshal bundle config") - } - return nil -} - -func (c *crioLXC) writeBundleConfig() error { - p := c.runtimePath("bundle.json") - f, err := os.OpenFile(p, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) - if err != nil { - return errors.Wrapf(err, "failed to create bundle config file %s", p) - } - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - err = enc.Encode(c.bundleConfig) - if err != nil { - f.Close() - return errors.Wrap(err, "failed to marshal bundle config") - } - return f.Close() -} - -// saveConfig creates and atomically enables the lxc config file. -// It must be called after #createContainer and only once. -// Any config changes via clxc.setConfigItem must be done -// before calling saveConfig. -func (c *crioLXC) saveConfig() error { - // createContainer creates the tmpfile - tmpFile := c.runtimePath(".config") - if _, err := os.Stat(tmpFile); err != nil { - return errors.Wrap(err, "failed to stat config tmpfile") - } - // Don't overwrite an existing config. - cfgFile := c.configFilePath() - if _, err := os.Stat(cfgFile); err == nil { - return fmt.Errorf("config file %s already exists", cfgFile) - } - err := c.Container.SaveConfigFile(tmpFile) - if err != nil { - return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) - } - if err := os.Rename(tmpFile, cfgFile); err != nil { - return errors.Wrap(err, "failed to rename config file") - } - log.Debug().Str("file", cfgFile).Msg("created lxc config file") - return nil -} - // Release releases/closes allocated resources (lxc.Container, LogFile) -func (c crioLXC) release() error { +func (c Runtime) release() error { if c.Container != nil { if err := c.Container.Release(); err != nil { log.Error().Err(err).Msg("failed to release container") @@ -347,7 +228,7 @@ func supportsConfigItem(keys ...string) bool { return true } -func (c *crioLXC) getConfigItem(key string) string { +func (c *Runtime) getConfigItem(key string) string { vals := c.Container.ConfigItem(key) if len(vals) > 0 { first := vals[0] @@ -360,7 +241,7 @@ func (c *crioLXC) getConfigItem(key string) string { return "" } -func (c *crioLXC) setConfigItem(key, value string) error { +func (c *Runtime) setConfigItem(key, value string) error { err := c.Container.SetConfigItem(key, value) if err != nil { return errors.Wrapf(err, "failed to set config item '%s=%s'", key, value) @@ -369,7 +250,7 @@ func (c *crioLXC) setConfigItem(key, value string) error { return nil } -func (c *crioLXC) configureLogging() error { +func (c *Runtime) configureLogging() error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) if err != nil { @@ -414,7 +295,7 @@ func (c *crioLXC) configureLogging() error { return nil } -func (c *crioLXC) setContainerLogLevel() error { +func (c *Runtime) setContainerLogLevel() error { // Never let lxc write to stdout, stdout belongs to the container init process. // Explicitly disable it - allthough it is currently the default. c.Container.SetVerbosity(lxc.Quiet) @@ -429,7 +310,7 @@ func (c *crioLXC) setContainerLogLevel() error { return nil } -func (c *crioLXC) parseContainerLogLevel() lxc.LogLevel { +func (c *Runtime) parseContainerLogLevel() lxc.LogLevel { switch strings.ToLower(c.ContainerLogLevel) { case "trace": return lxc.TRACE @@ -459,17 +340,17 @@ func (c *crioLXC) parseContainerLogLevel() lxc.LogLevel { // executeRuntimeHook executes the runtime hook executable if defined. // Execution errors are logged at log level error. -func (c *crioLXC) executeRuntimeHook(runtimeError error) { +func (c *Runtime) executeRuntimeHook(runtimeError error) { if c.RuntimeHook == "" { return } env := []string{ "CONTAINER_ID=" + c.ContainerID, - "LXC_CONFIG=" + c.configFilePath(), + "LXC_CONFIG=" + c.ConfigFilePath(), "RUNTIME_CMD=" + c.Command, - "RUNTIME_PATH=" + c.runtimePath(), + "RUNTIME_PATH=" + c.RuntimePath(), "BUNDLE_PATH=" + c.BundlePath, - "SPEC_PATH=" + c.SpecPath, + "SPEC_PATH=" + c.SpecPath(), "LOG_FILE=" + c.LogFilePath, } @@ -484,18 +365,18 @@ func (c *crioLXC) executeRuntimeHook(runtimeError error) { // #nosec cmd := exec.CommandContext(ctx, c.RuntimeHook) cmd.Env = env - cmd.Dir = c.runtimePath() + cmd.Dir = c.RuntimePath() if err := cmd.Run(); err != nil { log.Error().Err(err).Str("file", c.RuntimeHook). Bool("timeout-expired", ctx.Err() == context.DeadlineExceeded).Msg("runtime hook failed") } } -func (c *crioLXC) isContainerStopped() bool { +func (c *Runtime) isContainerStopped() bool { return c.Container.State() == lxc.STOPPED } -func (c *crioLXC) waitCreated(timeout time.Duration) error { +func (c *Runtime) waitCreated(timeout time.Duration) error { if !c.Container.Wait(lxc.RUNNING, timeout) { return fmt.Errorf("timeout starting init cmd") } @@ -510,7 +391,7 @@ func (c *crioLXC) waitCreated(timeout time.Duration) error { return nil } -func (c *crioLXC) waitRunning(timeout time.Duration) error { +func (c *Runtime) waitRunning(timeout time.Duration) error { deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { initState, err := c.getContainerInitState() @@ -534,7 +415,7 @@ func (c *crioLXC) waitRunning(timeout time.Duration) error { // The init process environment contains #envStateCreated if the the container // is created, but not yet running/started. // This requires the proc filesystem to be mounted on the host. -func (c *crioLXC) getContainerState() (ContainerState, error) { +func (c *Runtime) getContainerState() (ContainerState, error) { state := c.Container.State() switch state { case lxc.STOPPED: @@ -550,7 +431,7 @@ func (c *crioLXC) getContainerState() (ContainerState, error) { // getContainerInitState returns the detailed state of the container init process. // If the init process is not running StateStopped is returned along with an error. -func (c *crioLXC) getContainerInitState() (ContainerState, error) { +func (c *Runtime) getContainerInitState() (ContainerState, error) { initPid := c.Container.InitPid() if initPid < 1 { return StateStopped, fmt.Errorf("init cmd is not running") @@ -613,7 +494,7 @@ func enableCgroupControllers(cg string) error { return nil } -func (c *crioLXC) killContainer(signum unix.Signal) error { +func (c *Runtime) killContainer(signum unix.Signal) error { if signum == unix.SIGKILL || signum == unix.SIGTERM { if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { return err @@ -638,7 +519,7 @@ func (c *crioLXC) killContainer(signum unix.Signal) error { } // send non-terminating signals to monitor process - pid, err := c.readPidFile() + pid, err := c.Pid() if err != nil && !os.IsNotExist(err) { return errors.Wrapf(err, "failed to load pidfile") } @@ -658,7 +539,7 @@ func (c *crioLXC) killContainer(signum unix.Signal) error { // but not created by this container, MUST NOT be deleted." // TODO - because we set rootfs.managed=0, Destroy() doesn't // delete the /var/lib/lxc/$containerID/config file: -func (c *crioLXC) destroy() error { +func (c *Runtime) destroy() error { if c.Container != nil { if err := c.Container.Destroy(); err != nil { return errors.Wrap(err, "failed to destroy container") @@ -670,5 +551,30 @@ func (c *crioLXC) destroy() error { log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") } - return os.RemoveAll(c.runtimePath()) + return os.RemoveAll(c.RuntimePath()) +} + +// saveConfig creates and atomically enables the lxc config file. +// It must be called after #createContainer and only once. +// Any config changes via clxc.setConfigItem must be done +// before calling saveConfig. +func (c *Runtime) saveConfig() error { + // createContainer creates the tmpfile + tmpFile := c.RuntimePath(".config") + if _, err := os.Stat(tmpFile); err != nil { + return errors.Wrap(err, "failed to stat config tmpfile") + } + // Don't overwrite an existing config. + cfgFile := c.ConfigFilePath() + if _, err := os.Stat(cfgFile); err == nil { + return fmt.Errorf("config file %s already exists", cfgFile) + } + err := c.Container.SaveConfigFile(tmpFile) + if err != nil { + return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) + } + if err := os.Rename(tmpFile, cfgFile); err != nil { + return errors.Wrap(err, "failed to rename config file") + } + return nil } diff --git a/cmd/container.go b/cmd/container.go new file mode 100644 index 00000000..a8a21b1f --- /dev/null +++ b/cmd/container.go @@ -0,0 +1,112 @@ +package main + +import ( + "encoding/json" + "github.com/pkg/errors" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +// ContainerInfo holds the information about a single container. +// It is created at 'create' within the container runtime dir and not changed afterwards. +// It is removed when the container is deleted. +type ContainerInfo struct { + ContainerID string + CreatedAt time.Time + RuntimeRoot string + + BundlePath string + ConsoleSocket string `json;,omitempty` + // PidFile is the absolute path to the PID file of the container monitor process (crio-lxc-start) + PidFile string + MonitorCgroupDir string + + // values derived from spec + CgroupDir string + + // feature gates + Seccomp bool + Capabilities bool + Apparmor bool + CgroupDevices bool +} + +func (c ContainerInfo) SpecPath() string { + return filepath.Join(c.BundlePath, "config.json") +} + +// RuntimePath returns the absolute path witin the container root +func (c ContainerInfo) RuntimePath(subPath ...string) string { + return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) +} + +func (c ContainerInfo) ConfigFilePath() string { + return c.RuntimePath("config") +} + +func (c ContainerInfo) Pid() (int, error) { + // #nosec + data, err := ioutil.ReadFile(c.PidFile) + if err != nil { + return 0, err + } + s := strings.TrimSpace(string(data)) + return strconv.Atoi(s) +} + +func (c ContainerInfo) CreatePidFile(pid int) error { + return createPidFile(c.PidFile, pid) +} + +// Spec deserializes the JSON encoded runtime spec from the given path. +func (c ContainerInfo) Spec() (*specs.Spec, error) { + // #nosec + specFile, err := os.Open(c.SpecPath()) + if err != nil { + return nil, err + } + // #nosec + defer specFile.Close() + spec := &specs.Spec{} + err = json.NewDecoder(specFile).Decode(spec) + if err != nil { + return nil, err + } + + return spec, nil +} + +func (c *ContainerInfo) Load() error { + p := c.RuntimePath("container.json") + data, err := ioutil.ReadFile(p) + if err != nil { + return errors.Wrapf(err, "failed to read bundle config file %s", p) + } + err = json.Unmarshal(data, c) + if err != nil { + return errors.Wrap(err, "failed to unmarshal bundle config") + } + return nil +} + +func (c *ContainerInfo) Create() error { + p := c.RuntimePath("container.json") + f, err := os.OpenFile(p, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + if err != nil { + return errors.Wrapf(err, "failed to create bundle config file %s", p) + } + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + err = enc.Encode(c) + if err != nil { + f.Close() + return errors.Wrap(err, "failed to marshal bundle config") + } + return f.Close() +} diff --git a/cmd/create.go b/cmd/create.go index 10a1fbcf..defc8cba 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -77,7 +77,7 @@ func doCreateInternal(ctx *cli.Context) error { return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } - spec, err := clxc.readSpec() + spec, err := clxc.Spec() if err != nil { return errors.Wrap(err, "couldn't load bundle spec") } @@ -92,7 +92,7 @@ func doCreateInternal(ctx *cli.Context) error { } // #nosec - startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.configFilePath()) + startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) if err := runStartCmd(startCmd, spec); err != nil { return errors.Wrap(err, "failed to start container process") } @@ -103,7 +103,7 @@ func doCreateInternal(ctx *cli.Context) error { return err } - return clxc.createPidFile(startCmd.Process.Pid) + return clxc.CreatePidFile(startCmd.Process.Pid) } func configureContainer(spec *specs.Spec) error { @@ -369,7 +369,7 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { //cmd.SysProcAttr.Setsid = true */ - cmd.Dir = clxc.runtimePath() + cmd.Dir = clxc.RuntimePath() if clxc.ConsoleSocket != "" { if err := clxc.saveConfig(); err != nil { @@ -407,7 +407,7 @@ func writeDevices(spec *specs.Spec) error { if spec.Linux.Devices == nil { return nil } - f, err := os.OpenFile(clxc.runtimePath("devices.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + f, err := os.OpenFile(clxc.RuntimePath("devices.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } @@ -438,7 +438,7 @@ func writeMasked(spec *specs.Spec) error { if spec.Linux.MaskedPaths == nil { return nil } - f, err := os.OpenFile(clxc.runtimePath("masked.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + f, err := os.OpenFile(clxc.RuntimePath("masked.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } diff --git a/cmd/exec.go b/cmd/exec.go index b070e41b..617d5a69 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -96,7 +96,7 @@ func doExec(ctx *cli.Context) error { } // Load container spec to get the list of supported namespaces. - spec, err := clxc.readSpec() + spec, err := clxc.Spec() if err != nil { return errors.Wrap(err, "failed to read container runtime spec") } diff --git a/cmd/init.go b/cmd/init.go index 09a7dc7b..4d53da80 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -17,7 +17,7 @@ const ( ) func syncFifoPath() string { - return clxc.runtimePath(initDir, "syncfifo") + return clxc.RuntimePath(initDir, "syncfifo") } func createFifo(dst string, uid int, gid int, mode uint32) error { @@ -30,7 +30,7 @@ func createFifo(dst string, uid int, gid int, mode uint32) error { } func configureInit(spec *specs.Spec) error { - runtimeInitDir := clxc.runtimePath(initDir) + runtimeInitDir := clxc.RuntimePath(initDir) rootfsInitDir := filepath.Join(spec.Root.Path, initDir) err := os.MkdirAll(rootfsInitDir, 0) diff --git a/cmd/seccomp.go b/cmd/seccomp.go index f4c87ae3..613c4257 100644 --- a/cmd/seccomp.go +++ b/cmd/seccomp.go @@ -28,7 +28,7 @@ func configureSeccomp(spec *specs.Spec) error { return nil } - profilePath := clxc.runtimePath("seccomp.conf") + profilePath := clxc.RuntimePath("seccomp.conf") if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { return err } diff --git a/cmd/state.go b/cmd/state.go index cdd3d588..4e4ed94b 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -27,12 +27,12 @@ func doState(ctx *cli.Context) error { return errors.Wrapf(err, "failed to load container") } - pid, err := clxc.readPidFile() + pid, err := clxc.Pid() if err != nil { return errors.Wrapf(err, "failed to load pidfile") } - spec, err := clxc.readSpec() + spec, err := clxc.Spec() if err != nil { return err } From ab35a9ee5bfc7224701c1535d9329371051c96bf Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 12:07:06 +0100 Subject: [PATCH 091/373] refactor: Move code from start command to runtime. Signed-off-by: Ruben Jenster --- cmd/{clxc.go => runtime.go} | 56 +++++++++++++++++++++++++++++++-- cmd/start.go | 62 +++---------------------------------- 2 files changed, 59 insertions(+), 59 deletions(-) rename cmd/{clxc.go => runtime.go} (92%) diff --git a/cmd/clxc.go b/cmd/runtime.go similarity index 92% rename from cmd/clxc.go rename to cmd/runtime.go index 0651a393..f23e49b5 100644 --- a/cmd/clxc.go +++ b/cmd/runtime.go @@ -358,9 +358,9 @@ func (c *Runtime) executeRuntimeHook(runtimeError error) { env = append(env, "RUNTIME_ERROR="+runtimeError.Error()) } - log.Debug().Str("file", clxc.RuntimeHook).Msg("execute runtime hook") + log.Debug().Str("file", c.RuntimeHook).Msg("execute runtime hook") // TODO drop privileges, capabilities ? - ctx, cancel := context.WithTimeout(context.Background(), clxc.RuntimeHookTimeout) + ctx, cancel := context.WithTimeout(context.Background(), c.RuntimeHookTimeout) defer cancel() // #nosec cmd := exec.CommandContext(ctx, c.RuntimeHook) @@ -578,3 +578,55 @@ func (c *Runtime) saveConfig() error { } return nil } + +func (c *Runtime) Start(timeout time.Duration) error { + log.Info().Msg("notify init to start container process") + + err := c.loadContainer() + if err != nil { + return err + } + + state, err := c.getContainerState() + if err != nil { + return err + } + if state != StateCreated { + return fmt.Errorf("invalid container state. expected %q, but was %q", StateCreated, state) + } + + done := make(chan error) + go func() { + done <- c.readFifo() + }() + + select { + case err := <-done: + return err + case <-time.After(time.Second * 5): + return fmt.Errorf("timeout reading from syncfifo") + } + + return c.waitRunning(timeout) +} + +func (c *Runtime) readFifo() error { + // #nosec + f, err := os.OpenFile(syncFifoPath(), os.O_RDONLY, 0) + if err != nil { + return errors.Wrap(err, "failed to open sync fifo") + } + // can not set deadline on fifo + // #nosec + defer f.Close() + + data := make([]byte, len(c.ContainerID)) + _, err = f.Read(data) + if err != nil { + return errors.Wrap(err, "problem reading from fifo") + } + if c.ContainerID != string(data) { + return errors.Errorf("bad fifo content: %s", string(data)) + } + return nil +} diff --git a/cmd/start.go b/cmd/start.go index 7dcdc922..b105b181 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -1,10 +1,7 @@ package main import ( - "fmt" - "github.com/pkg/errors" "github.com/urfave/cli/v2" - "os" "time" ) @@ -18,63 +15,14 @@ starts `, Flags: []cli.Flag{ &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for reading from syncfifo", - EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, - Value: time.Second * 5, - Destination: &clxc.StartTimeout, + Name: "timeout", + Usage: "timeout for reading from syncfifo", + EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, + Value: time.Second * 5, }, }, } func doStart(ctx *cli.Context) error { - log.Info().Msg("notify init to start container process") - - err := clxc.loadContainer() - if err != nil { - return err - } - - state, err := clxc.getContainerState() - if err != nil { - return err - } - if state != StateCreated { - return fmt.Errorf("invalid container state. expected %q, but was %q", StateCreated, state) - } - - done := make(chan error) - go func() { - done <- readFifo() - }() - - select { - case err := <-done: - return err - case <-time.After(clxc.StartTimeout): - return fmt.Errorf("timeout reading from syncfifo") - } - - return clxc.waitRunning(time.Second * 5) -} - -func readFifo() error { - // #nosec - f, err := os.OpenFile(syncFifoPath(), os.O_RDONLY, 0) - if err != nil { - return errors.Wrap(err, "failed to open sync fifo") - } - // can not set deadline on fifo - // #nosec - defer f.Close() - - data := make([]byte, len(clxc.ContainerID)) - _, err = f.Read(data) - if err != nil { - return errors.Wrap(err, "problem reading from fifo") - } - if clxc.ContainerID != string(data) { - return errors.Errorf("bad fifo content: %s", string(data)) - } - return nil + return clxc.Start(ctx.Duration("timeout")) } From 9b9d7f847d586f122874119f234235133f553aeb Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 12:14:41 +0100 Subject: [PATCH 092/373] refactor: Move code for delete command to runtime. Signed-off-by: Ruben Jenster --- cmd/delete.go | 26 +------------------------- cmd/runtime.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/cmd/delete.go b/cmd/delete.go index d25aa2bd..14ee46cc 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -1,11 +1,7 @@ package main import ( - "fmt" - - "github.com/pkg/errors" "github.com/urfave/cli/v2" - "golang.org/x/sys/unix" ) var deleteCmd = cli.Command{ @@ -25,25 +21,5 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { - - err := clxc.loadContainer() - if err == errContainerNotExist { - return nil - } - if err != nil { - return err - } - - force := ctx.Bool("force") - log.Info().Bool("force", force).Msg("delete container") - - if !clxc.isContainerStopped() { - if !force { - return fmt.Errorf("container is not not stopped (current state %s)", clxc.Container.State()) - } - if err := clxc.killContainer(unix.SIGKILL); err != nil { - return errors.Wrap(err, "failed to kill container") - } - } - return clxc.destroy() + return clxc.Delete(ctx.Bool("force")) } diff --git a/cmd/runtime.go b/cmd/runtime.go index f23e49b5..41f352d9 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -630,3 +630,25 @@ func (c *Runtime) readFifo() error { } return nil } + +func (c *Runtime) Delete(force bool) error { + err := c.loadContainer() + if err == errContainerNotExist { + return nil + } + if err != nil { + return err + } + + log.Info().Bool("force", force).Msg("delete container") + + if !c.isContainerStopped() { + if !force { + return fmt.Errorf("container is not not stopped (current state %s)", c.Container.State()) + } + if err := c.killContainer(unix.SIGKILL); err != nil { + return errors.Wrap(err, "failed to kill container") + } + } + return c.destroy() +} From 9919a110db89476316c41336d5ed1dad5c127880 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 12:20:02 +0100 Subject: [PATCH 093/373] refactor: Rename main to cli. Move delete and start command to cli. Signed-off-by: Ruben Jenster --- cmd/{main.go => cli.go} | 42 +++++++++++++++++++++++++++++++++++++++++ cmd/delete.go | 25 ------------------------ cmd/start.go | 28 --------------------------- 3 files changed, 42 insertions(+), 53 deletions(-) rename cmd/{main.go => cli.go} (91%) delete mode 100644 cmd/delete.go delete mode 100644 cmd/start.go diff --git a/cmd/main.go b/cmd/cli.go similarity index 91% rename from cmd/main.go rename to cmd/cli.go index f8827cd5..29c3bce4 100644 --- a/cmd/main.go +++ b/cmd/cli.go @@ -279,3 +279,45 @@ func loadEnvFile(envFile string) (map[string]string, error) { } return env, nil } + +var deleteCmd = cli.Command{ + Name: "delete", + Usage: "deletes a container", + Action: doDelete, + ArgsUsage: `[containerID] + + is the ID of the container to delete +`, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "force", + Usage: "force deletion", + }, + }, +} + +func doDelete(ctx *cli.Context) error { + return clxc.Delete(ctx.Bool("force")) +} + +var startCmd = cli.Command{ + Name: "start", + Usage: "starts a container", + Action: doStart, + ArgsUsage: `[containerID] + +starts +`, + Flags: []cli.Flag{ + &cli.DurationFlag{ + Name: "timeout", + Usage: "timeout for reading from syncfifo", + EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, + Value: time.Second * 5, + }, + }, +} + +func doStart(ctx *cli.Context) error { + return clxc.Start(ctx.Duration("timeout")) +} diff --git a/cmd/delete.go b/cmd/delete.go deleted file mode 100644 index 14ee46cc..00000000 --- a/cmd/delete.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "github.com/urfave/cli/v2" -) - -var deleteCmd = cli.Command{ - Name: "delete", - Usage: "deletes a container", - Action: doDelete, - ArgsUsage: `[containerID] - - is the ID of the container to delete -`, - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "force", - Usage: "force deletion", - }, - }, -} - -func doDelete(ctx *cli.Context) error { - return clxc.Delete(ctx.Bool("force")) -} diff --git a/cmd/start.go b/cmd/start.go deleted file mode 100644 index b105b181..00000000 --- a/cmd/start.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "github.com/urfave/cli/v2" - "time" -) - -var startCmd = cli.Command{ - Name: "start", - Usage: "starts a container", - Action: doStart, - ArgsUsage: `[containerID] - -starts -`, - Flags: []cli.Flag{ - &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for reading from syncfifo", - EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, - Value: time.Second * 5, - }, - }, -} - -func doStart(ctx *cli.Context) error { - return clxc.Start(ctx.Duration("timeout")) -} From cd900dfdf046d391e92b5eb62f51940be8465a1b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 13:02:48 +0100 Subject: [PATCH 094/373] refactor: Moved state command to cli. Signed-off-by: Ruben Jenster --- cmd/cli.go | 23 ++++++++++++++++++ cmd/runtime.go | 34 +++++++++++++++++++++++++++ cmd/state.go | 63 -------------------------------------------------- 3 files changed, 57 insertions(+), 63 deletions(-) delete mode 100644 cmd/state.go diff --git a/cmd/cli.go b/cmd/cli.go index 29c3bce4..ccc4c55d 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "github.com/pkg/errors" "io/ioutil" @@ -321,3 +322,25 @@ starts func doStart(ctx *cli.Context) error { return clxc.Start(ctx.Duration("timeout")) } + +var stateCmd = cli.Command{ + Name: "state", + Usage: "returns state of a container", + Action: doState, + ArgsUsage: `[containerID] + + is the ID of the container you want to know about. +`, + Flags: []cli.Flag{}, +} + +func doState(ctx *cli.Context) error { + state, err := clxc.State() + if j, err := json.Marshal(state); err == nil { + fmt.Fprint(os.Stdout, string(j)) + log.Trace().RawJSON("state", j).Msg("container state") + } else { + return errors.Wrap(err, "failed to marshal json") + } + return err +} diff --git a/cmd/runtime.go b/cmd/runtime.go index 41f352d9..c4bf3fda 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -652,3 +652,37 @@ func (c *Runtime) Delete(force bool) error { } return c.destroy() } + +func (c *Runtime) State() (*specs.State, error) { + err := c.loadContainer() + if err != nil { + return nil, errors.Wrapf(err, "failed to load container") + } + + pid, err := c.Pid() + if err != nil { + return nil, errors.Wrapf(err, "failed to load pidfile") + } + + spec, err := c.Spec() + if err != nil { + return nil, err + } + + state := &specs.State{ + Version: specs.Version, + ID: c.Container.Name(), + Bundle: c.BundlePath, + Pid: pid, + Annotations: spec.Annotations, + } + + s, err := c.getContainerState() + state.Status = string(s) + if err != nil { + return nil, err + } + + log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") + return state, nil +} diff --git a/cmd/state.go b/cmd/state.go deleted file mode 100644 index 4e4ed94b..00000000 --- a/cmd/state.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - "github.com/urfave/cli/v2" -) - -var stateCmd = cli.Command{ - Name: "state", - Usage: "returns state of a container", - Action: doState, - ArgsUsage: `[containerID] - - is the ID of the container you want to know about. -`, - Flags: []cli.Flag{}, -} - -func doState(ctx *cli.Context) error { - err := clxc.loadContainer() - if err != nil { - return errors.Wrapf(err, "failed to load container") - } - - pid, err := clxc.Pid() - if err != nil { - return errors.Wrapf(err, "failed to load pidfile") - } - - spec, err := clxc.Spec() - if err != nil { - return err - } - - s := specs.State{ - Version: specs.Version, - ID: clxc.Container.Name(), - Bundle: clxc.BundlePath, - Pid: pid, - Annotations: spec.Annotations, - } - - state, err := clxc.getContainerState() - s.Status = string(state) - if err != nil { - return err - } - - log.Info().Int("pid", s.Pid).Str("status", s.Status).Msg("container state") - - if stateJSON, err := json.Marshal(s); err == nil { - fmt.Fprint(os.Stdout, string(stateJSON)) - log.Trace().RawJSON("state", stateJSON).Msg("container state") - } else { - return errors.Wrap(err, "failed to marshal json") - } - return err -} From bfeeb55923c30a45e035717fd09382a137111198 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 13:11:38 +0100 Subject: [PATCH 095/373] refactor: Move kill cmd to cli and runtime Signed-off-by: Ruben Jenster --- cmd/cli.go | 60 +++++++++++++++++++++++++++++++---------------- cmd/kill.go | 63 -------------------------------------------------- cmd/runtime.go | 17 ++++++++++++++ cmd/utils.go | 19 +++++++++++++++ 4 files changed, 76 insertions(+), 83 deletions(-) delete mode 100644 cmd/kill.go diff --git a/cmd/cli.go b/cmd/cli.go index ccc4c55d..31c7a3fa 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -281,26 +281,6 @@ func loadEnvFile(envFile string) (map[string]string, error) { return env, nil } -var deleteCmd = cli.Command{ - Name: "delete", - Usage: "deletes a container", - Action: doDelete, - ArgsUsage: `[containerID] - - is the ID of the container to delete -`, - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "force", - Usage: "force deletion", - }, - }, -} - -func doDelete(ctx *cli.Context) error { - return clxc.Delete(ctx.Bool("force")) -} - var startCmd = cli.Command{ Name: "start", Usage: "starts a container", @@ -344,3 +324,43 @@ func doState(ctx *cli.Context) error { } return err } + +var killCmd = cli.Command{ + Name: "kill", + Usage: "sends a signal to a container", + Action: doKill, + ArgsUsage: `[containerID] [signal] + + is the ID of the container to send a signal to +[signal] signal name or numerical value (e.g [9|kill|KILL|sigkill|SIGKILL]) +`, +} + +func doKill(ctx *cli.Context) error { + sig := ctx.Args().Get(1) + signum := parseSignal(sig) + if signum == 0 { + return fmt.Errorf("invalid signal param %q", sig) + } + return clxc.Kill(signum) +} + +var deleteCmd = cli.Command{ + Name: "delete", + Usage: "deletes a container", + Action: doDelete, + ArgsUsage: `[containerID] + + is the ID of the container to delete +`, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "force", + Usage: "force deletion", + }, + }, +} + +func doDelete(ctx *cli.Context) error { + return clxc.Delete(ctx.Bool("force")) +} diff --git a/cmd/kill.go b/cmd/kill.go deleted file mode 100644 index b8877f7a..00000000 --- a/cmd/kill.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "fmt" - "strconv" - "strings" - - "golang.org/x/sys/unix" - - "github.com/pkg/errors" - "github.com/urfave/cli/v2" -) - -var killCmd = cli.Command{ - Name: "kill", - Usage: "sends a signal to a container", - Action: doKill, - ArgsUsage: `[containerID] [signal] - - is the ID of the container to send a signal to -[signal] signal name or numerical value (e.g [9|kill|KILL|sigkill|SIGKILL]) -`, -} - -func parseSignal(sig string) unix.Signal { - if sig == "" { - return unix.SIGTERM - } - // handle numerical signal value - if num, err := strconv.Atoi(sig); err == nil { - return unix.Signal(num) - } - - // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' - s := strings.ToUpper(sig) - if !strings.HasPrefix(s, "SIG") { - s = "SIG" + s - } - return unix.SignalNum(s) -} - -func doKill(ctx *cli.Context) error { - sig := ctx.Args().Get(1) - signum := parseSignal(sig) - if signum == 0 { - return fmt.Errorf("invalid signal param %q", sig) - } - - err := clxc.loadContainer() - if err != nil { - return errors.Wrap(err, "failed to load container") - } - - state, err := clxc.getContainerState() - if err != nil { - return err - } - if !(state == StateCreated || state == StateRunning) { - return fmt.Errorf("can only kill container in state Created|Running but was %q", state) - } - - return clxc.killContainer(signum) -} diff --git a/cmd/runtime.go b/cmd/runtime.go index c4bf3fda..aeb434cd 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -686,3 +686,20 @@ func (c *Runtime) State() (*specs.State, error) { log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") return state, nil } + +func (c *Runtime) Kill(signum unix.Signal) error { + err := c.loadContainer() + if err != nil { + return errors.Wrap(err, "failed to load container") + } + + state, err := c.getContainerState() + if err != nil { + return err + } + if !(state == StateCreated || state == StateRunning) { + return fmt.Errorf("can only kill container in state Created|Running but was %q", state) + } + + return c.killContainer(signum) +} diff --git a/cmd/utils.go b/cmd/utils.go index 268f824f..dff5e9d8 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -5,6 +5,8 @@ import ( "github.com/pkg/errors" "os" "path/filepath" + "strconv" + "strings" "golang.org/x/sys/unix" ) @@ -69,3 +71,20 @@ func isFilesystem(dir string, fsName string) error { } return nil } + +func parseSignal(sig string) unix.Signal { + if sig == "" { + return unix.SIGTERM + } + // handle numerical signal value + if num, err := strconv.Atoi(sig); err == nil { + return unix.Signal(num) + } + + // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' + s := strings.ToUpper(sig) + if !strings.HasPrefix(s, "SIG") { + s = "SIG" + s + } + return unix.SignalNum(s) +} From cc342877446a17df6d18faa22730e92079776633 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 13:14:05 +0100 Subject: [PATCH 096/373] refactor: Move clxc package variable to cli Signed-off-by: Ruben Jenster --- cmd/cli.go | 3 +++ cmd/runtime.go | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 31c7a3fa..b41dcbb2 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -16,6 +16,9 @@ import ( // Existing environment variables are preserved. var envFile = "/etc/default/crio-lxc" +// The singelton that wraps the lxc.Container +var clxc Runtime + func main() { app := cli.NewApp() app.Name = "crio-lxc" diff --git a/cmd/runtime.go b/cmd/runtime.go index aeb434cd..d93cf873 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -45,8 +45,6 @@ const ( StateStopped ContainerState = "stopped" ) -// The singelton that wraps the lxc.Container -var clxc Runtime var log zerolog.Logger var errContainerNotExist = errors.New("container does not exist") @@ -700,6 +698,5 @@ func (c *Runtime) Kill(signum unix.Signal) error { if !(state == StateCreated || state == StateRunning) { return fmt.Errorf("can only kill container in state Created|Running but was %q", state) } - return c.killContainer(signum) } From 90f2df5d24cf3f10e1e58a32e62213112ebd7b16 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 16:07:43 +0100 Subject: [PATCH 097/373] refactor: Move cli specific code for create and exec command to cli. Signed-off-by: Ruben Jenster --- cmd/cli.go | 118 +++++++++++++++++++++++++++++++++++ cmd/container.go | 53 +++------------- cmd/create.go | 57 ++--------------- cmd/exec.go | 143 ------------------------------------------ cmd/runtime.go | 157 ++++++++++++++++++++++++++++++++++------------- cmd/utils.go | 33 ++++++++++ 6 files changed, 281 insertions(+), 280 deletions(-) delete mode 100644 cmd/exec.go diff --git a/cmd/cli.go b/cmd/cli.go index b41dcbb2..92b959ee 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -284,6 +284,46 @@ func loadEnvFile(envFile string) (map[string]string, error) { return env, nil } +var createCmd = cli.Command{ + Name: "create", + Usage: "create a container from a bundle directory", + ArgsUsage: "", + Action: doCreate, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "bundle", + Usage: "set bundle directory", + Value: ".", + Destination: &clxc.BundlePath, + }, + &cli.StringFlag{ + Name: "console-socket", + Usage: "send container pty master fd to this socket path", + Destination: &clxc.ConsoleSocket, + }, + &cli.StringFlag{ + Name: "pid-file", + Usage: "path to write container PID", + Destination: &clxc.PidFile, + }, + &cli.DurationFlag{ + Name: "socket-timeout", + Usage: "timeout for sending pty master to socket", + EnvVars: []string{"CRIO_LXC_CREATE_SOCKET_TIMEOUT"}, + Value: time.Second * 60, + Destination: &clxc.ConsoleSocketTimeout, + }, + }, +} + +func doCreate(ctx *cli.Context) error { + err := doCreateInternal() + if err != nil || clxc.RuntimeHookRunAlways { + clxc.executeRuntimeHook(err) + } + return err +} + var startCmd = cli.Command{ Name: "start", Usage: "starts a container", @@ -367,3 +407,81 @@ var deleteCmd = cli.Command{ func doDelete(ctx *cli.Context) error { return clxc.Delete(ctx.Bool("force")) } + +var execCmd = cli.Command{ + Name: "exec", + Usage: "execute a new process in a running container", + ArgsUsage: "", + Action: doExec, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "process", + Aliases: []string{"p"}, + Usage: "path to process json", + Value: "", + }, + &cli.StringFlag{ + Name: "pid-file", + Usage: "file to write the process id to", + Value: "", + }, + &cli.BoolFlag{ + Name: "detach", + Aliases: []string{"d"}, + Usage: "detach from the executed process", + }, + }, +} + +type execError int + +func (e execError) ExitStatus() int { + return int(e) +} + +func (e execError) Error() string { + return fmt.Sprintf("exec cmd exited with status %d", int(e)) +} + +func doExec(ctx *cli.Context) error { + var args []string + if ctx.Args().Len() > 1 { + args = ctx.Args().Slice()[1:] + } + + pidFile := ctx.String("pid-file") + detach := ctx.Bool("detach") + + if detach && pidFile == "" { + log.Warn().Msg("detaching process but pid-file value is unset") + } + + err := clxc.loadContainer() + if err != nil { + return err + } + + procSpec, err := ReadSpecProcess(ctx.String("process")) + if err != nil { + return err + } + + if detach { + pid, err := clxc.ExecDetached(args, procSpec) + if err != nil { + return err + } + if pidFile != "" { + return createPidFile(pidFile, pid) + } + } else { + status, err := clxc.Exec(args, procSpec) + if err != nil { + return err + } + if status != 0 { + return execError(status) + } + } + return nil +} diff --git a/cmd/container.go b/cmd/container.go index a8a21b1f..5d386e60 100644 --- a/cmd/container.go +++ b/cmd/container.go @@ -1,8 +1,6 @@ package main import ( - "encoding/json" - "github.com/pkg/errors" "io/ioutil" "os" "path/filepath" @@ -35,10 +33,8 @@ type ContainerInfo struct { Capabilities bool Apparmor bool CgroupDevices bool -} -func (c ContainerInfo) SpecPath() string { - return filepath.Join(c.BundlePath, "config.json") + *specs.Spec } // RuntimePath returns the absolute path witin the container root @@ -64,49 +60,20 @@ func (c ContainerInfo) CreatePidFile(pid int) error { return createPidFile(c.PidFile, pid) } -// Spec deserializes the JSON encoded runtime spec from the given path. -func (c ContainerInfo) Spec() (*specs.Spec, error) { - // #nosec - specFile, err := os.Open(c.SpecPath()) - if err != nil { - return nil, err - } - // #nosec - defer specFile.Close() - spec := &specs.Spec{} - err = json.NewDecoder(specFile).Decode(spec) - if err != nil { - return nil, err - } - - return spec, nil -} - +// RuntimeRoot and ContainerID must be set func (c *ContainerInfo) Load() error { p := c.RuntimePath("container.json") - data, err := ioutil.ReadFile(p) - if err != nil { - return errors.Wrapf(err, "failed to read bundle config file %s", p) - } - err = json.Unmarshal(data, c) - if err != nil { - return errors.Wrap(err, "failed to unmarshal bundle config") + if err := decodeFileJSON(c, p); err != nil { + return err } - return nil + return c.ReadSpec() } func (c *ContainerInfo) Create() error { p := c.RuntimePath("container.json") - f, err := os.OpenFile(p, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) - if err != nil { - return errors.Wrapf(err, "failed to create bundle config file %s", p) - } - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - err = enc.Encode(c) - if err != nil { - f.Close() - return errors.Wrap(err, "failed to marshal bundle config") - } - return f.Close() + return encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) +} + +func(c *ContainerInfo) ReadSpec() error { + return decodeFileJSON(c.Spec, filepath.Join(c.BundlePath, "config.json")) } diff --git a/cmd/create.go b/cmd/create.go index defc8cba..51f78f18 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -15,52 +15,11 @@ import ( "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/urfave/cli/v2" lxc "gopkg.in/lxc/go-lxc.v2" ) -var createCmd = cli.Command{ - Name: "create", - Usage: "create a container from a bundle directory", - ArgsUsage: "", - Action: doCreate, - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "bundle", - Usage: "set bundle directory", - Value: ".", - Destination: &clxc.BundlePath, - }, - &cli.StringFlag{ - Name: "console-socket", - Usage: "send container pty master fd to this socket path", - Destination: &clxc.ConsoleSocket, - }, - &cli.StringFlag{ - Name: "pid-file", - Usage: "path to write container PID", - Destination: &clxc.PidFile, - }, - &cli.DurationFlag{ - Name: "socket-timeout", - Usage: "timeout for sending pty master to socket", - EnvVars: []string{"CRIO_LXC_CREATE_SOCKET_TIMEOUT"}, - Value: time.Second * 60, - Destination: &clxc.ConsoleSocketTimeout, - }, - }, -} - -func doCreate(ctx *cli.Context) error { - err := doCreateInternal(ctx) - if err != nil || clxc.RuntimeHookRunAlways { - clxc.executeRuntimeHook(err) - } - return err -} - -func doCreateInternal(ctx *cli.Context) error { +func doCreateInternal() error { err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return err @@ -77,23 +36,18 @@ func doCreateInternal(ctx *cli.Context) error { return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } - spec, err := clxc.Spec() - if err != nil { - return errors.Wrap(err, "couldn't load bundle spec") - } - - err = clxc.createContainer(spec) + err = clxc.createContainer() if err != nil { return errors.Wrap(err, "failed to create container") } - if err := configureContainer(spec); err != nil { + if err := configureContainer(clxc.Spec); err != nil { return errors.Wrap(err, "failed to configure container") } // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) - if err := runStartCmd(startCmd, spec); err != nil { + if err := runStartCmd(startCmd, clxc.Spec); err != nil { return errors.Wrap(err, "failed to start container process") } log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") @@ -102,8 +56,7 @@ func doCreateInternal(ctx *cli.Context) error { log.Error().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") return err } - - return clxc.CreatePidFile(startCmd.Process.Pid) + return createPidFile(clxc.PidFile, startCmd.Process.Pid) } func configureContainer(spec *specs.Spec) error { diff --git a/cmd/exec.go b/cmd/exec.go deleted file mode 100644 index 617d5a69..00000000 --- a/cmd/exec.go +++ /dev/null @@ -1,143 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - "github.com/urfave/cli/v2" - - lxc "gopkg.in/lxc/go-lxc.v2" -) - -type execError int - -func (e execError) ExitStatus() int { - return int(e) -} - -func (e execError) Error() string { - return fmt.Sprintf("exec cmd exited with status %d", int(e)) -} - -var execCmd = cli.Command{ - Name: "exec", - Usage: "execute a new process in a running container", - ArgsUsage: "", - Action: doExec, - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "process", - Aliases: []string{"p"}, - Usage: "path to process json", - Value: "", - }, - &cli.StringFlag{ - Name: "pid-file", - Usage: "file to write the process id to", - Value: "", - }, - &cli.BoolFlag{ - Name: "detach", - Aliases: []string{"d"}, - Usage: "detach from the executed process", - }, - }, -} - -func doExec(ctx *cli.Context) error { - err := clxc.loadContainer() - if err != nil { - return errors.Wrap(err, "failed to load container") - } - c := clxc.Container - - attachOpts := lxc.AttachOptions{} - - var procArgs []string - specFilePath := ctx.String("process") - - if specFilePath != "" { - log.Debug().Str("spec", specFilePath).Msg("read process spec") - // #nosec - specData, err := ioutil.ReadFile(specFilePath) - log.Trace().Err(err).RawJSON("spec", specData).Msg("process spec data") - - if err != nil { - return errors.Wrap(err, "failed to read process spec") - } - - var procSpec *specs.Process - err = json.Unmarshal(specData, &procSpec) - if err != nil { - return errors.Wrapf(err, "failed to unmarshal process spec") - } - procArgs = procSpec.Args - attachOpts.UID = int(procSpec.User.UID) - attachOpts.GID = int(procSpec.User.GID) - if n := len(procSpec.User.AdditionalGids); n > 0 { - attachOpts.Groups = make([]int, n) - for i, g := range procSpec.User.AdditionalGids { - attachOpts.Groups[i] = int(g) - } - } - attachOpts.Cwd = procSpec.Cwd - // Use the environment defined by the process spec. - attachOpts.ClearEnv = true - attachOpts.Env = procSpec.Env - - } else { - // Fall back to cmdline arguments. - if ctx.Args().Len() >= 2 { - procArgs = ctx.Args().Slice()[1:] - } - } - - // Load container spec to get the list of supported namespaces. - spec, err := clxc.Spec() - if err != nil { - return errors.Wrap(err, "failed to read container runtime spec") - } - for _, ns := range spec.Linux.Namespaces { - n, supported := namespaceMap[ns.Type] - if !supported { - return fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) - } - attachOpts.Namespaces |= n.CloneFlag - } - - attachOpts.StdinFd = 0 - attachOpts.StdoutFd = 1 - attachOpts.StderrFd = 2 - - detach := ctx.Bool("detach") - - log.Info().Bool("detach", detach).Strs("args", procArgs). - Int("uid", attachOpts.UID).Int("gid", attachOpts.GID). - Ints("groups", attachOpts.Groups).Msg("running cmd in container") - - if detach { - pidFile := ctx.String("pid-file") - pid, err := c.RunCommandNoWait(procArgs, attachOpts) - if err != nil { - return errors.Wrapf(err, "c.RunCommandNoWait failed") - } - log.Debug().Err(err).Int("pid", pid).Msg("cmd is running detached") - if pidFile == "" { - log.Warn().Msg("detaching process but pid-file value is empty") - return nil - } - return createPidFile(pidFile, pid) - } - - exitStatus, err := c.RunCommandStatus(procArgs, attachOpts) - if err != nil { - return err - } - if exitStatus != 0 { - return execError(exitStatus) - } - return nil -} diff --git a/cmd/runtime.go b/cmd/runtime.go index d93cf873..ced4625a 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -86,11 +86,20 @@ type Runtime struct { // createContainer creates a new container. // It must only be called once during the lifecycle of a container. -func (c *Runtime) createContainer(spec *specs.Spec) error { +func (c *Runtime) createContainer() error { if _, err := os.Stat(c.ConfigFilePath()); err == nil { return errContainerExist } + // load spec + if err := c.ReadSpec(); err != nil { + return err + } + spec, err := + if err != nil { + return err + } + if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } @@ -121,8 +130,6 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { return err } - c.CreatedAt = time.Now() - if err := c.ContainerInfo.Create(); err != nil { return err } @@ -138,7 +145,6 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { // loadContainer checks for the existence of the lxc config file. // It returns an error if the config file does not exist. func (c *Runtime) loadContainer() error { - if err := c.ContainerInfo.Load(); err != nil { return err } @@ -216,38 +222,6 @@ func (c Runtime) release() error { return nil } -func supportsConfigItem(keys ...string) bool { - for _, key := range keys { - if !lxc.IsSupportedConfigItem(key) { - log.Info().Str("lxc.config", key).Msg("unsupported config item") - return false - } - } - return true -} - -func (c *Runtime) getConfigItem(key string) string { - vals := c.Container.ConfigItem(key) - if len(vals) > 0 { - first := vals[0] - // some lxc config values are set to '(null)' if unset - // eg. lxc.cgroup.dir - if first != "(null)" { - return first - } - } - return "" -} - -func (c *Runtime) setConfigItem(key, value string) error { - err := c.Container.SetConfigItem(key, value) - if err != nil { - return errors.Wrapf(err, "failed to set config item '%s=%s'", key, value) - } - log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") - return nil -} - func (c *Runtime) configureLogging() error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) @@ -662,17 +636,12 @@ func (c *Runtime) State() (*specs.State, error) { return nil, errors.Wrapf(err, "failed to load pidfile") } - spec, err := c.Spec() - if err != nil { - return nil, err - } - state := &specs.State{ Version: specs.Version, ID: c.Container.Name(), Bundle: c.BundlePath, Pid: pid, - Annotations: spec.Annotations, + Annotations: c.Spec.Annotations, } s, err := c.getContainerState() @@ -700,3 +669,107 @@ func (c *Runtime) Kill(signum unix.Signal) error { } return c.killContainer(signum) } + +func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { + opts, err := attachOptions(c.Spec, proc) + if err != nil { + return err + } + + log.Info().Strs("args", args). + Int("uid", opts.UID).Int("gid", opts.GID). + Ints("groups", opts.Groups).Msg("execute cmd") + + return c.Container.RunCommandNoWait(args, opts) +} + +func (c *Runtime) Exec(args []string, procSpec *specs.Process) (exitStatus int, err error) { + opts, err := attachOptions(c.Spec, proc) + if err != nil { + return err + } + + return c.RunCommandStatus(args, attachOpts) +} + +// -- LXC helper functions that should be static + +func (c *Runtime) getConfigItem(key string) string { + vals := c.Container.ConfigItem(key) + if len(vals) > 0 { + first := vals[0] + // some lxc config values are set to '(null)' if unset + // eg. lxc.cgroup.dir + if first != "(null)" { + return first + } + } + return "" +} + +func (c *Runtime) setConfigItem(key, value string) error { + err := c.Container.SetConfigItem(key, value) + if err != nil { + return errors.Wrapf(err, "failed to set config item '%s=%s'", key, value) + } + log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") + return nil +} + +// -- LXC helper functions + +func supportsConfigItem(keys ...string) bool { + for _, key := range keys { + if !lxc.IsSupportedConfigItem(key) { + log.Info().Str("lxc.config", key).Msg("unsupported config item") + return false + } + } + return true +} + +func attachOptions(spec *specs.Spec, procSpec *specs.Process) (*lxc.AttachOptions, error) { + opts := &lxc.AttachOptions{ + StdinFd: 0, + StdoutFd: 1, + StderrFd: 2, + } + + for _, ns := range spec.Linux.Namespaces { + n, supported := namespaceMap[ns.Type] + if !supported { + return nil, fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) + } + opts.Namespaces |= n.CloneFlag + } + + if procSpec != nil { + opts.Cwd = procSpec.Cwd + // Use the environment defined by the process spec. + opts.ClearEnv = true + opts.Env = procSpec.Env + + opts.UID = int(procSpec.User.UID) + opts.GID = int(procSpec.User.GID) + if n := len(procSpec.User.AdditionalGids); n > 0 { + opts.Groups = make([]int, n) + for i, g := range procSpec.User.AdditionalGids { + opts.Groups[i] = int(g) + } + } + } + return opts, nil +} + +// --- OCI convenience helper functions + +func ReadSpec(specPath string) (spec *specs.Spec, err error) { + err = decodeFileJSON(spec, src) +} + +func ReadSpecProcess(src string) (proc *specs.Process, err error) { + if src == "" { + return nil, nil + } + err = decodeFileJSON(proc, src) +} diff --git a/cmd/utils.go b/cmd/utils.go index dff5e9d8..8bef9103 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "github.com/pkg/errors" "os" @@ -88,3 +89,35 @@ func parseSignal(sig string) unix.Signal { } return unix.SignalNum(s) } + +func decodeFileJSON(obj interface{}, src string) error { + // #nosec + f, err := os.Open(src) + if err != nil { + return err + } + // #nosec + spec := &specs.Spec{} + err = json.NewDecoder(f).Decode(obj) + if err != nil { + f.Close() + return err + } + return f.Close() +} + +func encodeFileJSON(dst string, obj interface{}, int flags, mode uint32) error { + f, err := os.OpenFile(dst, flags, mode) + if err != nil { + return errors.Wrapf(err, "failed to create file %q", dst) + } + c.CreatedAt = time.Now() + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + err = enc.Encode(c) + if err != nil { + f.Close() + return errors.Wrap(err, "failed to write JSON to file %q", dst) + } + return f.Close() +} From e9167d4d894d3dffe74cf896e2fff5d481e29ecc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 17:24:55 +0100 Subject: [PATCH 098/373] refactor: Several fixes. Fix nil pointer in process spec deserialization. Signed-off-by: Ruben Jenster --- cmd/cli.go | 3 +++ cmd/container.go | 12 +++++++++--- cmd/runtime.go | 43 +++++++++++++++++++------------------------ cmd/utils.go | 44 +++++++++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 92b959ee..541ec173 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -465,6 +465,9 @@ func doExec(ctx *cli.Context) error { if err != nil { return err } + if procSpec != nil { + args = procSpec.Args + } if detach { pid, err := clxc.ExecDetached(args, procSpec) diff --git a/cmd/container.go b/cmd/container.go index 5d386e60..ecf70cc7 100644 --- a/cmd/container.go +++ b/cmd/container.go @@ -34,7 +34,7 @@ type ContainerInfo struct { Apparmor bool CgroupDevices bool - *specs.Spec + *specs.Spec `json:"-"` } // RuntimePath returns the absolute path witin the container root @@ -71,9 +71,15 @@ func (c *ContainerInfo) Load() error { func (c *ContainerInfo) Create() error { p := c.RuntimePath("container.json") + c.CreatedAt = time.Now() return encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) } -func(c *ContainerInfo) ReadSpec() error { - return decodeFileJSON(c.Spec, filepath.Join(c.BundlePath, "config.json")) +func (c ContainerInfo) SpecPath() string { + return filepath.Join(c.BundlePath, "config.json") +} + +func (c *ContainerInfo) ReadSpec() error { + c.Spec = &specs.Spec{} + return decodeFileJSON(c.Spec, c.SpecPath()) } diff --git a/cmd/runtime.go b/cmd/runtime.go index ced4625a..d9a5bcda 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -93,10 +93,6 @@ func (c *Runtime) createContainer() error { // load spec if err := c.ReadSpec(); err != nil { - return err - } - spec, err := - if err != nil { return err } @@ -115,13 +111,13 @@ func (c *Runtime) createContainer() error { return errors.Wrap(err, "failed to close empty config file") } - if spec.Linux.CgroupsPath == "" { + if c.Spec.Linux.CgroupsPath == "" { return fmt.Errorf("empty cgroups path in spec") } if c.SystemdCgroup { - c.CgroupDir = parseSystemdCgroupPath(spec.Linux.CgroupsPath) + c.CgroupDir = parseSystemdCgroupPath(c.Spec.Linux.CgroupsPath) } else { - c.CgroupDir = spec.Linux.CgroupsPath + c.CgroupDir = c.Spec.Linux.CgroupsPath } c.MonitorCgroupDir = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") @@ -159,7 +155,7 @@ func (c *Runtime) loadContainer() error { container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { - return errors.Wrap(err, "failed to load container") + return errors.Wrap(err, "failed to create new lxc container") } err = container.LoadConfigFile(c.ConfigFilePath()) if err != nil { @@ -253,7 +249,6 @@ func (c *Runtime) configureLogging() error { // NOTE Unfortunately it's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 - //log = zerolog.New(c.LogFile).With().Timestamp().CallerWithSkipFrameCount(-1). log = zerolog.New(c.LogFile).With().Timestamp().Caller(). Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() @@ -628,7 +623,7 @@ func (c *Runtime) Delete(force bool) error { func (c *Runtime) State() (*specs.State, error) { err := c.loadContainer() if err != nil { - return nil, errors.Wrapf(err, "failed to load container") + return nil, err } pid, err := c.Pid() @@ -657,7 +652,7 @@ func (c *Runtime) State() (*specs.State, error) { func (c *Runtime) Kill(signum unix.Signal) error { err := c.loadContainer() if err != nil { - return errors.Wrap(err, "failed to load container") + return err } state, err := c.getContainerState() @@ -673,7 +668,7 @@ func (c *Runtime) Kill(signum unix.Signal) error { func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { opts, err := attachOptions(c.Spec, proc) if err != nil { - return err + return 0, err } log.Info().Strs("args", args). @@ -683,13 +678,12 @@ func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err return c.Container.RunCommandNoWait(args, opts) } -func (c *Runtime) Exec(args []string, procSpec *specs.Process) (exitStatus int, err error) { +func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { opts, err := attachOptions(c.Spec, proc) if err != nil { - return err + return 0, err } - - return c.RunCommandStatus(args, attachOpts) + return c.Container.RunCommandStatus(args, opts) } // -- LXC helper functions that should be static @@ -728,8 +722,8 @@ func supportsConfigItem(keys ...string) bool { return true } -func attachOptions(spec *specs.Spec, procSpec *specs.Process) (*lxc.AttachOptions, error) { - opts := &lxc.AttachOptions{ +func attachOptions(spec *specs.Spec, procSpec *specs.Process) (lxc.AttachOptions, error) { + opts := lxc.AttachOptions{ StdinFd: 0, StdoutFd: 1, StderrFd: 2, @@ -738,7 +732,7 @@ func attachOptions(spec *specs.Spec, procSpec *specs.Process) (*lxc.AttachOption for _, ns := range spec.Linux.Namespaces { n, supported := namespaceMap[ns.Type] if !supported { - return nil, fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) + return opts, fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) } opts.Namespaces |= n.CloneFlag } @@ -761,15 +755,16 @@ func attachOptions(spec *specs.Spec, procSpec *specs.Process) (*lxc.AttachOption return opts, nil } -// --- OCI convenience helper functions - -func ReadSpec(specPath string) (spec *specs.Spec, err error) { +func ReadSpec(src string) (spec *specs.Spec, err error) { err = decodeFileJSON(spec, src) + return } -func ReadSpecProcess(src string) (proc *specs.Process, err error) { +func ReadSpecProcess(src string) (*specs.Process, error) { if src == "" { return nil, nil } - err = decodeFileJSON(proc, src) + proc := new(specs.Process) + err := decodeFileJSON(proc, src) + return proc, err } diff --git a/cmd/utils.go b/cmd/utils.go index 8bef9103..5c1de6a1 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "github.com/pkg/errors" "os" "path/filepath" "strconv" @@ -12,8 +11,6 @@ import ( "golang.org/x/sys/unix" ) -const undefined = -1 - // createPidFile atomically creates a pid file for the given pid at the given path func createPidFile(path string, pid int) error { tmpDir := filepath.Dir(path) @@ -38,37 +35,37 @@ func createPidFile(path string, pid int) error { func canExecute(cmds ...string) error { for _, c := range cmds { if err := unix.Access(c, unix.X_OK); err != nil { - return errors.Wrapf(err, "failed to access cmd %s", c) + return fmt.Errorf("can not execute %q: %w", c, err) } } return nil } -func filesystemName(fsName string) int64 { +func fsMagic(fsName string) int64 { switch fsName { case "proc", "procfs": return unix.PROC_SUPER_MAGIC case "cgroup2", "cgroup2fs": return unix.CGROUP2_SUPER_MAGIC default: - return undefined + return -1 } } // TODO check whether dir is the filsystem root (use /proc/mounts) func isFilesystem(dir string, fsName string) error { - fsType := filesystemName(fsName) - if fsType == undefined { + fsType := fsMagic(fsName) + if fsType == -1 { return fmt.Errorf("undefined filesystem %q", fsName) } var stat unix.Statfs_t err := unix.Statfs(dir, &stat) if err != nil { - return errors.Wrapf(err, "fstat failed for directory %s", dir) + return fmt.Errorf("fstat failed for %q: %w", dir, err) } if stat.Type != fsType { - return fmt.Errorf("%s is not on %q filesystem", dir, fsName) + return fmt.Errorf("%q is not on filesystem %s", dir, fsName) } return nil } @@ -94,30 +91,35 @@ func decodeFileJSON(obj interface{}, src string) error { // #nosec f, err := os.Open(src) if err != nil { - return err + return fmt.Errorf("failed to open %s: %w", src, err) } // #nosec - spec := &specs.Spec{} err = json.NewDecoder(f).Decode(obj) if err != nil { f.Close() - return err + return fmt.Errorf("failed to decode JSON from %s: %w", src, err) + } + err = f.Close() + if err != nil { + return fmt.Errorf("failed to close %s: %w", src, err) } - return f.Close() + return nil } -func encodeFileJSON(dst string, obj interface{}, int flags, mode uint32) error { - f, err := os.OpenFile(dst, flags, mode) +func encodeFileJSON(dst string, obj interface{}, flags int, mode uint32) error { + f, err := os.OpenFile(dst, flags, os.FileMode(mode)) if err != nil { - return errors.Wrapf(err, "failed to create file %q", dst) + return fmt.Errorf("failed to open %s: %w", dst, err) } - c.CreatedAt = time.Now() enc := json.NewEncoder(f) enc.SetIndent("", " ") - err = enc.Encode(c) + err = enc.Encode(obj) if err != nil { f.Close() - return errors.Wrap(err, "failed to write JSON to file %q", dst) + return fmt.Errorf("failed to encode JSON to %s: %w", dst, err) } - return f.Close() + if err != nil { + return fmt.Errorf("failed to close %s: %w", dst, err) + } + return nil } From c870ecced4164a3664c3a20bc8ef0034405c2bb0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 2 Dec 2020 20:00:11 +0100 Subject: [PATCH 099/373] Load bundle.json once. Cache Namespaces and Annotations in container.json. Signed-off-by: Ruben Jenster --- cmd/container.go | 21 +++++++++++---------- cmd/create.go | 11 ++++++++--- cmd/namespaces.go | 12 ++++++++++++ cmd/runtime.go | 37 +++++++++++++++++-------------------- cmd/utils.go | 2 +- 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/cmd/container.go b/cmd/container.go index ecf70cc7..d1589fbb 100644 --- a/cmd/container.go +++ b/cmd/container.go @@ -20,7 +20,7 @@ type ContainerInfo struct { RuntimeRoot string BundlePath string - ConsoleSocket string `json;,omitempty` + ConsoleSocket string `json;",omitempty"` // PidFile is the absolute path to the PID file of the container monitor process (crio-lxc-start) PidFile string MonitorCgroupDir string @@ -34,7 +34,11 @@ type ContainerInfo struct { Apparmor bool CgroupDevices bool - *specs.Spec `json:"-"` + // values duplicated from bundle.json + // annotations are required for 'state' + Annotations map[string]string `json:",omitempty"` + // namespaces are required for 'exec' + Namespaces []specs.LinuxNamespace `json:",omitempty"` } // RuntimePath returns the absolute path witin the container root @@ -62,11 +66,7 @@ func (c ContainerInfo) CreatePidFile(pid int) error { // RuntimeRoot and ContainerID must be set func (c *ContainerInfo) Load() error { - p := c.RuntimePath("container.json") - if err := decodeFileJSON(c, p); err != nil { - return err - } - return c.ReadSpec() + return decodeFileJSON(c, c.RuntimePath("container.json")) } func (c *ContainerInfo) Create() error { @@ -79,7 +79,8 @@ func (c ContainerInfo) SpecPath() string { return filepath.Join(c.BundlePath, "config.json") } -func (c *ContainerInfo) ReadSpec() error { - c.Spec = &specs.Spec{} - return decodeFileJSON(c.Spec, c.SpecPath()) +func (c *ContainerInfo) ReadSpec() (*specs.Spec, error) { + spec := new(specs.Spec) + err := decodeFileJSON(spec, c.SpecPath()) + return spec, err } diff --git a/cmd/create.go b/cmd/create.go index 51f78f18..565211c5 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -36,18 +36,23 @@ func doCreateInternal() error { return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) } - err = clxc.createContainer() + spec, err := clxc.ReadSpec() + if err != nil { + return err + } + + err = clxc.createContainer(spec) if err != nil { return errors.Wrap(err, "failed to create container") } - if err := configureContainer(clxc.Spec); err != nil { + if err := configureContainer(spec); err != nil { return errors.Wrap(err, "failed to configure container") } // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) - if err := runStartCmd(startCmd, clxc.Spec); err != nil { + if err := runStartCmd(startCmd, spec); err != nil { return errors.Wrap(err, "failed to start container process") } log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") diff --git a/cmd/namespaces.go b/cmd/namespaces.go index 9deb99bf..64f0740c 100644 --- a/cmd/namespaces.go +++ b/cmd/namespaces.go @@ -24,6 +24,18 @@ var namespaceMap = map[specs.LinuxNamespaceType]namespace{ specs.UTSNamespace: namespace{"uts", unix.CLONE_NEWUTS}, } +func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { + flags := 0 + for _, ns := range namespaces { + n, exist := namespaceMap[ns.Type] + if !exist { + return 0, fmt.Errorf("namespace %s is not supported", ns.Type) + } + flags |= n.CloneFlag + } + return flags, nil +} + func configureNamespaces(namespaces []specs.LinuxNamespace) error { seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} for _, ns := range namespaces { diff --git a/cmd/runtime.go b/cmd/runtime.go index d9a5bcda..8a032471 100644 --- a/cmd/runtime.go +++ b/cmd/runtime.go @@ -86,16 +86,11 @@ type Runtime struct { // createContainer creates a new container. // It must only be called once during the lifecycle of a container. -func (c *Runtime) createContainer() error { +func (c *Runtime) createContainer(spec *specs.Spec) error { if _, err := os.Stat(c.ConfigFilePath()); err == nil { return errContainerExist } - // load spec - if err := c.ReadSpec(); err != nil { - return err - } - if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { return errors.Wrap(err, "failed to create container dir") } @@ -111,13 +106,13 @@ func (c *Runtime) createContainer() error { return errors.Wrap(err, "failed to close empty config file") } - if c.Spec.Linux.CgroupsPath == "" { + if spec.Linux.CgroupsPath == "" { return fmt.Errorf("empty cgroups path in spec") } if c.SystemdCgroup { - c.CgroupDir = parseSystemdCgroupPath(c.Spec.Linux.CgroupsPath) + c.CgroupDir = parseSystemdCgroupPath(spec.Linux.CgroupsPath) } else { - c.CgroupDir = c.Spec.Linux.CgroupsPath + c.CgroupDir = spec.Linux.CgroupsPath } c.MonitorCgroupDir = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") @@ -126,6 +121,9 @@ func (c *Runtime) createContainer() error { return err } + c.Annotations = spec.Annotations + c.Namespaces = spec.Linux.Namespaces + if err := c.ContainerInfo.Create(); err != nil { return err } @@ -157,11 +155,12 @@ func (c *Runtime) loadContainer() error { if err != nil { return errors.Wrap(err, "failed to create new lxc container") } + c.Container = container + err = container.LoadConfigFile(c.ConfigFilePath()) if err != nil { return errors.Wrap(err, "failed to load config file") } - c.Container = container return c.setContainerLogLevel() } @@ -636,7 +635,7 @@ func (c *Runtime) State() (*specs.State, error) { ID: c.Container.Name(), Bundle: c.BundlePath, Pid: pid, - Annotations: c.Spec.Annotations, + Annotations: c.Annotations, } s, err := c.getContainerState() @@ -666,7 +665,7 @@ func (c *Runtime) Kill(signum unix.Signal) error { } func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { - opts, err := attachOptions(c.Spec, proc) + opts, err := attachOptions(proc, c.Namespaces) if err != nil { return 0, err } @@ -679,7 +678,7 @@ func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err } func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { - opts, err := attachOptions(c.Spec, proc) + opts, err := attachOptions(proc, c.Namespaces) if err != nil { return 0, err } @@ -722,20 +721,18 @@ func supportsConfigItem(keys ...string) bool { return true } -func attachOptions(spec *specs.Spec, procSpec *specs.Process) (lxc.AttachOptions, error) { +func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.AttachOptions, error) { opts := lxc.AttachOptions{ StdinFd: 0, StdoutFd: 1, StderrFd: 2, } - for _, ns := range spec.Linux.Namespaces { - n, supported := namespaceMap[ns.Type] - if !supported { - return opts, fmt.Errorf("can not attach to %s: unsupported namespace", ns.Type) - } - opts.Namespaces |= n.CloneFlag + clone, err := cloneFlags(ns) + if err != nil { + return opts, err } + opts.Namespaces = clone if procSpec != nil { opts.Cwd = procSpec.Cwd diff --git a/cmd/utils.go b/cmd/utils.go index 5c1de6a1..52cdf2c1 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -112,7 +112,7 @@ func encodeFileJSON(dst string, obj interface{}, flags int, mode uint32) error { return fmt.Errorf("failed to open %s: %w", dst, err) } enc := json.NewEncoder(f) - enc.SetIndent("", " ") + //enc.SetIndent("", " ") err = enc.Encode(obj) if err != nil { f.Close() From 2c8c130ee1af2e5a98766d93f6f9b4d350017e8a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 02:46:33 +0100 Subject: [PATCH 100/373] refactor: Introduce lxcontainer package. Signed-off-by: Ruben Jenster --- cmd/cli.go | 94 ++----------------- cmd/util.go | 73 +++++++++++++++ {cmd => lxcontainer}/cgroup.go | 12 +-- {cmd => lxcontainer}/cgroup_test.go | 2 +- {cmd => lxcontainer}/container.go | 2 +- {cmd => lxcontainer}/create.go | 137 ++++++++++------------------ {cmd => lxcontainer}/init.go | 16 +--- {cmd => lxcontainer}/mount.go | 4 +- {cmd => lxcontainer}/mount_test.go | 2 +- {cmd => lxcontainer}/namespaces.go | 49 +++++++++- {cmd => lxcontainer}/runtime.go | 48 +++++++--- {cmd => lxcontainer}/seccomp.go | 21 +---- {cmd => lxcontainer}/utils.go | 8 +- 13 files changed, 239 insertions(+), 229 deletions(-) create mode 100644 cmd/util.go rename {cmd => lxcontainer}/cgroup.go (96%) rename {cmd => lxcontainer}/cgroup_test.go (98%) rename {cmd => lxcontainer}/container.go (99%) rename {cmd => lxcontainer}/create.go (80%) rename {cmd => lxcontainer}/init.go (91%) rename {cmd => lxcontainer}/mount.go (98%) rename {cmd => lxcontainer}/mount_test.go (99%) rename {cmd => lxcontainer}/namespaces.go (65%) rename {cmd => lxcontainer}/runtime.go (95%) rename {cmd => lxcontainer}/seccomp.go (88%) rename {cmd => lxcontainer}/utils.go (95%) diff --git a/cmd/cli.go b/cmd/cli.go index 541ec173..bdaf5482 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/lxc/crio-lxc/lxcontainer" "github.com/urfave/cli/v2" ) @@ -17,13 +18,13 @@ import ( var envFile = "/etc/default/crio-lxc" // The singelton that wraps the lxc.Container -var clxc Runtime +var clxc lxcontainer.Runtime func main() { app := cli.NewApp() app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" - app.Version = versionString() + app.Version = lxcontainer.Version() // Disable the default ExitErrHandler. // It will call os.Exit if a command returns an error that implements // the cli.ExitCoder interface. E.g an unwrapped error from os.Exec. @@ -44,14 +45,14 @@ func main() { Name: "log-level", Usage: "set the runtime log level (trace|debug|info|warn|error)", EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, - Value: defaultLogLevel.String(), + Value: "info", Destination: &clxc.LogLevel, }, &cli.StringFlag{ Name: "container-log-level", Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, - Value: strings.ToLower(defaultContainerLogLevel.String()), + Value: "warn", Destination: &clxc.ContainerLogLevel, }, &cli.StringFlag{ @@ -161,7 +162,7 @@ func main() { env, envErr := loadEnvFile(envFile) if env != nil { for key, val := range env { - if err := setEnvIfNew(key, val); err != nil { + if err := setEnv(key, val, false); err != nil { envErr = err break } @@ -179,35 +180,11 @@ func main() { return errors.New("missing container ID") } clxc.ContainerID = containerID - clxc.Command = ctx.Command.Name - if err := clxc.configureLogging(); err != nil { + if err := clxc.ConfigureLogging(ctx.Command.Name); err != nil { return err } - - if env != nil { - stat, _ := os.Stat(envFile) - if stat != nil && (stat.Mode().Perm()^0640) != 0 { - log.Warn().Str("file", envFile).Stringer("mode", stat.Mode().Perm()).Msgf("environment file should have mode %s", os.FileMode(0640)) - } - for key, val := range env { - log.Trace().Str("env", key).Str("val", val).Msg("environment file value") - } - log.Debug().Str("file", envFile).Msg("loaded environment variables from file") - } else { - if os.IsNotExist(envErr) { - log.Warn().Str("file", envFile).Msg("environment file does not exist") - } else { - return errors.Wrapf(envErr, "failed to load env file %s", envFile) - } - } - - for _, f := range ctx.Command.Flags { - name := f.Names()[0] - log.Trace().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") - } - - log.Debug().Strs("args", os.Args).Msg("run cmd") + // log.Debug().Strs("args", os.Args).Msg("run cmd") return nil } @@ -228,60 +205,9 @@ func main() { app.CommandNotFound = func(ctx *cli.Context, cmd string) { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } - + err := app.Run(os.Args) - cmdDuration := time.Since(startTime) - if err != nil { - log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") - } else { - log.Info().Dur("duration", cmdDuration).Msg("cmd completed") - } - - if err := clxc.release(); err != nil { - log.Error().Err(err).Msg("failed to release container") - } - - if err != nil { - if err, yes := err.(execError); yes { - os.Exit(err.ExitStatus()) - } else { - // write diagnostics message to stderr for crio/kubelet - println(err.Error()) - os.Exit(1) - } - } -} - -func setEnvIfNew(key, val string) error { - if _, exist := os.LookupEnv(key); !exist { - return os.Setenv(key, val) - } - return nil -} - -func loadEnvFile(envFile string) (map[string]string, error) { - // #nosec - data, err := ioutil.ReadFile(envFile) - if err != nil { - return nil, err - } - lines := strings.Split(string(data), "\n") - env := make(map[string]string, len(lines)) - for n, line := range lines { - trimmed := strings.TrimSpace(line) - // skip over comments and blank lines - if len(trimmed) == 0 || trimmed[0] == '#' { - continue - } - vals := strings.SplitN(trimmed, "=", 2) - if len(vals) != 2 { - return nil, fmt.Errorf("invalid environment variable at line %s:%d", envFile, n+1) - } - key := strings.TrimSpace(vals[0]) - val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) - env[key] = val - } - return env, nil + clxc.Release(err) } var createCmd = cli.Command{ diff --git a/cmd/util.go b/cmd/util.go new file mode 100644 index 00000000..76878d91 --- /dev/null +++ b/cmd/util.go @@ -0,0 +1,73 @@ +package main + +import ( + "fmt" + "github.com/pkg/errors" + "io/ioutil" + "os" + "strings" + "time" + + "github.com/lxc/crio-lxc/lxcontainer" + "github.com/urfave/cli/v2" +) + +func setEnv(key, val string, overwrite bool) error { + _, exist := os.LookupEnv(key) + if !exist || overwrite { + return os.Setenv(key, val) + } + return nil +} + +func loadEnvFile(envFile string) (map[string]string, error) { + // #nosec + data, err := ioutil.ReadFile(envFile) + if err != nil { + return nil, err + } + lines := strings.Split(string(data), "\n") + env := make(map[string]string, len(lines)) + for n, line := range lines { + trimmed := strings.TrimSpace(line) + // skip over comments and blank lines + if len(trimmed) == 0 || trimmed[0] == '#' { + continue + } + vals := strings.SplitN(trimmed, "=", 2) + if len(vals) != 2 { + return nil, fmt.Errorf("invalid environment variable at line %s:%d", envFile, n+1) + } + key := strings.TrimSpace(vals[0]) + val := strings.Trim(strings.TrimSpace(vals[1]), `"'`) + env[key] = val + } + return env, nil +} + +/* +func logEnv(log *zerolog.Log) + if env != nil { + stat, _ := os.Stat(envFile) + if stat != nil && (stat.Mode().Perm()^0640) != 0 { + log.Warn().Str("file", envFile).Stringer("mode", stat.Mode().Perm()).Msgf("environment file should have mode %s", os.FileMode(0640)) + } + for key, val := range env { + log.Trace().Str("env", key).Str("val", val).Msg("environment file value") + } + log.Debug().Str("file", envFile).Msg("loaded environment variables from file") + } else { + if os.IsNotExist(envErr) { + log.Warn().Str("file", envFile).Msg("environment file does not exist") + } else { + return errors.Wrapf(envErr, "failed to load env file %s", envFile) + } + } + + for _, f := range ctx.Command.Flags { + name := f.Names()[0] + log.Trace().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") + } + + } +*/ diff --git a/cmd/cgroup.go b/lxcontainer/cgroup.go similarity index 96% rename from cmd/cgroup.go rename to lxcontainer/cgroup.go index 6f617687..5d158938 100644 --- a/cmd/cgroup.go +++ b/lxcontainer/cgroup.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "bytes" @@ -18,9 +18,9 @@ import ( // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md // TODO New spec will contain a property Unified for cgroupv2 properties // https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#unified -func configureCgroup(spec *specs.Spec) error { +func configureCgroup(clxc *Runtime, spec *specs.Spec) error { if devices := spec.Linux.Resources.Devices; devices != nil { - if err := configureDeviceController(spec); err != nil { + if err := configureDeviceController(clxc, spec); err != nil { return err } } @@ -30,7 +30,7 @@ func configureCgroup(spec *specs.Spec) error { } if cpu := spec.Linux.Resources.CPU; cpu != nil { - if err := configureCPUController(cpu); err != nil { + if err := configureCPUController(clxc, cpu); err != nil { return err } } @@ -54,7 +54,7 @@ func configureCgroup(spec *specs.Spec) error { return nil } -func configureDeviceController(spec *specs.Spec) error { +func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { devicesAllow := "lxc.cgroup2.devices.allow" devicesDeny := "lxc.cgroup2.devices.deny" @@ -123,7 +123,7 @@ func configureDeviceController(spec *specs.Spec) error { return nil } -func configureCPUController(linux *specs.LinuxCPU) error { +func configureCPUController(clxc *Runtime, slinux *specs.LinuxCPU) error { // CPU resource restriction configuration // use strconv.FormatUint(n, 10) instead of fmt.Sprintf ? log.Debug().Msg("TODO configure cgroup cpu controller") diff --git a/cmd/cgroup_test.go b/lxcontainer/cgroup_test.go similarity index 98% rename from cmd/cgroup_test.go rename to lxcontainer/cgroup_test.go index 96f8ad81..72bb3e05 100644 --- a/cmd/cgroup_test.go +++ b/lxcontainer/cgroup_test.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "github.com/stretchr/testify/require" diff --git a/cmd/container.go b/lxcontainer/container.go similarity index 99% rename from cmd/container.go rename to lxcontainer/container.go index d1589fbb..6ad07c73 100644 --- a/cmd/container.go +++ b/lxcontainer/container.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "io/ioutil" diff --git a/cmd/create.go b/lxcontainer/create.go similarity index 80% rename from cmd/create.go rename to lxcontainer/create.go index 565211c5..bbd152a5 100644 --- a/cmd/create.go +++ b/lxcontainer/create.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "fmt" @@ -6,7 +6,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "time" @@ -19,7 +18,7 @@ import ( lxc "gopkg.in/lxc/go-lxc.v2" ) -func doCreateInternal() error { +func doCreateInternal(clxc *Runtime) error { err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return err @@ -46,13 +45,13 @@ func doCreateInternal() error { return errors.Wrap(err, "failed to create container") } - if err := configureContainer(spec); err != nil { + if err := configureContainer(clxc, spec); err != nil { return errors.Wrap(err, "failed to configure container") } // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) - if err := runStartCmd(startCmd, spec); err != nil { + if err := runStartCmd(clxc, startCmd, spec); err != nil { return errors.Wrap(err, "failed to start container process") } log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") @@ -64,8 +63,8 @@ func doCreateInternal() error { return createPidFile(clxc.PidFile, startCmd.Process.Pid) } -func configureContainer(spec *specs.Spec) error { - if err := configureRootfs(spec); err != nil { +func configureContainer(clxc *Runtime, spec *specs.Spec) error { + if err := configureRootfs(clxc, spec); err != nil { return err } @@ -77,19 +76,19 @@ func configureContainer(spec *specs.Spec) error { return err } - if err := configureInit(spec); err != nil { + if err := configureInit(clxc, spec); err != nil { return err } - if err := configureMounts(spec); err != nil { + if err := configureMounts(clxc, spec); err != nil { return err } - if err := configureReadonlyPaths(spec); err != nil { + if err := configureReadonlyPaths(clxc, spec); err != nil { return err } - if err := configureNamespaces(spec.Linux.Namespaces); err != nil { + if err := configureNamespaces(clxc, spec.Linux.Namespaces); err != nil { return errors.Wrap(err, "failed to configure namespaces") } @@ -106,7 +105,7 @@ func configureContainer(spec *specs.Spec) error { } if clxc.Apparmor { - if err := configureApparmor(spec); err != nil { + if err := configureApparmor(clxc, spec); err != nil { return errors.Wrap(err, "failed to configure apparmor") } } else { @@ -114,26 +113,42 @@ func configureContainer(spec *specs.Spec) error { } if clxc.Seccomp { - if err := configureSeccomp(spec); err != nil { - return errors.Wrap(err, "failed to configure seccomp") + if spec.Linux.Seccomp == nil || len(spec.Linux.Seccomp.Syscalls) == 0 { + } else { + profilePath := clxc.RuntimePath("seccomp.conf") + if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.seccomp.profile", profilePath); err != nil { + return err + } } } else { log.Warn().Msg("seccomp is disabled") } if clxc.Capabilities { - if err := configureCapabilities(spec); err != nil { + if err := configureCapabilities(clxc, spec); err != nil { return errors.Wrap(err, "failed to configure capabilities") } } else { log.Warn().Msg("capabilities are disabled") } - if err := setHostname(spec); err != nil { - return errors.Wrap(err, "set hostname") + if spec.Hostname != "" { + if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { + return err + } + + uts := getNamespace(specs.UTSNamespace, spec.Linux.Namespaces) + if uts != nil && uts.Path != "" { + if err := setHostname(uts.Path, spec.Hostname); err != nil { + return errors.Wrap(err, "set hostname") + } + } } - if err := ensureDefaultDevices(spec); err != nil { + if err := ensureDefaultDevices(clxc, spec); err != nil { return errors.Wrap(err, "failed to add default devices") } @@ -141,7 +156,7 @@ func configureContainer(spec *specs.Spec) error { return errors.Wrap(err, "failed to configure cgroups path") } - if err := configureCgroup(spec); err != nil { + if err := configureCgroup(clxc, spec); err != nil { return errors.Wrap(err, "failed to configure cgroups") } @@ -161,7 +176,7 @@ func configureContainer(spec *specs.Spec) error { return nil } -func configureRootfs(spec *specs.Spec) error { +func configureRootfs(clxc *Runtime, spec *specs.Spec) error { if err := clxc.setConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { return err } @@ -187,7 +202,7 @@ func configureRootfs(spec *specs.Spec) error { return nil } -func configureReadonlyPaths(spec *specs.Spec) error { +func configureReadonlyPaths(clxc *Runtime, spec *specs.Spec) error { rootmnt := clxc.getConfigItem("lxc.rootfs.mount") if rootmnt == "" { return errors.New("lxc.rootfs.mount unavailable") @@ -201,7 +216,7 @@ func configureReadonlyPaths(spec *specs.Spec) error { return nil } -func configureApparmor(spec *specs.Spec) error { +func configureApparmor(clxc *Runtime, spec *specs.Spec) error { // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. aaprofile := spec.Process.ApparmorProfile if aaprofile == "" { @@ -214,7 +229,7 @@ func configureApparmor(spec *specs.Spec) error { // See `man lxc.container.conf` lxc.cap.drop and lxc.cap.keep for details. // https://blog.container-solutions.com/linux-capabilities-in-practice // https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work -func configureCapabilities(spec *specs.Spec) error { +func configureCapabilities(clxc *Runtime, spec *specs.Spec) error { keepCaps := "none" if spec.Process.Capabilities != nil { var caps []string @@ -256,7 +271,7 @@ func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64 // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(spec *specs.Spec) error { +func ensureDefaultDevices(clxc *Runtime, spec *specs.Spec) error { // make sure autodev is disabled if err := clxc.setConfigItem("lxc.autodev", "0"); err != nil { return err @@ -305,7 +320,7 @@ func setenv(env []string, key, val string, overwrite bool) []string { return append(env, key+"="+val) } -func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { +func runStartCmd(clxc *Runtime, cmd *exec.Cmd, spec *specs.Spec) error { // Start container with a clean environment. // LXC will export variables defined in the config lxc.environment. // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. @@ -333,7 +348,7 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { if err := clxc.saveConfig(); err != nil { return err } - return runStartCmdConsole(cmd, clxc.ConsoleSocket) + return runStartCmdConsole(cmd, clxc.ConsoleSocket, clxc.ConsoleSocketTimeout) } if !spec.Process.Terminal { // Inherit stdio from calling process (conmon). @@ -350,22 +365,22 @@ func runStartCmd(cmd *exec.Cmd, spec *specs.Spec) error { return err } - if err := writeDevices(spec); err != nil { + if err := writeDevices(clxc.RuntimePath("devices.txt"), spec); err != nil { return errors.Wrap(err, "failed to create devices.txt") } - if err := writeMasked(spec); err != nil { + if err := writeMasked(clxc.RuntimePath("masked.txt"), spec); err != nil { return errors.Wrap(err, "failed to create masked.txt file") } return cmd.Start() } -func writeDevices(spec *specs.Spec) error { +func writeDevices(dst string, spec *specs.Spec) error { if spec.Linux.Devices == nil { return nil } - f, err := os.OpenFile(clxc.RuntimePath("devices.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } @@ -391,12 +406,12 @@ func writeDevices(spec *specs.Spec) error { return f.Close() } -func writeMasked(spec *specs.Spec) error { +func writeMasked(dst string, spec *specs.Spec) error { // #nosec if spec.Linux.MaskedPaths == nil { return nil } - f, err := os.OpenFile(clxc.RuntimePath("masked.txt"), os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } @@ -410,7 +425,7 @@ func writeMasked(spec *specs.Spec) error { return f.Close() } -func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { +func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string, timeout time.Duration) error { addr, err := net.ResolveUnixAddr("unix", consoleSocket) if err != nil { return errors.Wrap(err, "failed to resolve console socket") @@ -420,7 +435,7 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { return errors.Wrap(err, "connecting to console socket failed") } defer conn.Close() - deadline := time.Now().Add(clxc.ConsoleSocketTimeout) + deadline := time.Now().Add(timeout) err = conn.SetDeadline(deadline) if err != nil { return errors.Wrap(err, "failed to set connection deadline") @@ -447,57 +462,3 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string) error { } return ptmx.Close() } - -func setHostname(spec *specs.Spec) error { - if spec.Hostname == "" { - return nil - } - - if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { - return err - } - - // lxc does not set the hostname on shared namespaces - for _, ns := range spec.Linux.Namespaces { - if ns.Type != specs.UTSNamespace { - continue - } - - // namespace is not shared - if ns.Path == "" { - return nil - } - - // setns only affects the current thread - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - f, err := os.Open(ns.Path) - if err != nil { - return errors.Wrapf(err, "failed to open uts namespace %s", ns.Path) - } - // #nosec - defer f.Close() - - self, err := os.Open("/proc/self/ns/uts") - if err != nil { - return errors.Wrapf(err, "failed to open %s", "/proc/self/ns/uts") - } - // #nosec - defer self.Close() - - err = unix.Setns(int(f.Fd()), unix.CLONE_NEWUTS) - if err != nil { - return err - } - err = unix.Sethostname([]byte(spec.Hostname)) - if err != nil { - return err - } - err = unix.Setns(int(self.Fd()), unix.CLONE_NEWUTS) - if err != nil { - return err - } - } - return nil -} diff --git a/cmd/init.go b/lxcontainer/init.go similarity index 91% rename from cmd/init.go rename to lxcontainer/init.go index 4d53da80..a1d9640b 100644 --- a/cmd/init.go +++ b/lxcontainer/init.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "fmt" @@ -16,20 +16,14 @@ const ( initDir = "/.crio-lxc" ) -func syncFifoPath() string { - return clxc.RuntimePath(initDir, "syncfifo") -} - func createFifo(dst string, uid int, gid int, mode uint32) error { - //prevMask := unix.Umask(0000) // ? - //defer unix.Umask(prevMask) // ? if err := unix.Mkfifo(dst, mode); err != nil { return err } return unix.Chown(dst, uid, gid) } -func configureInit(spec *specs.Spec) error { +func configureInit(clxc *Runtime, spec *specs.Spec) error { runtimeInitDir := clxc.RuntimePath(initDir) rootfsInitDir := filepath.Join(spec.Root.Path, initDir) @@ -58,7 +52,7 @@ func configureInit(spec *specs.Spec) error { gid := int(spec.Process.User.GID) // create files required for crio-lxc-init - if err := createFifo(syncFifoPath(), uid, gid, 0600); err != nil { + if err := createFifo(clxc.syncFifoPath(), uid, gid, 0600); err != nil { return errors.Wrapf(err, "failed to create sync fifo") } @@ -72,7 +66,7 @@ func configureInit(spec *specs.Spec) error { return err } - if err := configureInitUser(spec); err != nil { + if err := configureInitUser(clxc, spec); err != nil { return err } @@ -129,7 +123,7 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err return unix.Chmod(dst, mode) } -func configureInitUser(spec *specs.Spec) error { +func configureInitUser(clxc *Runtime, spec *specs.Spec) error { // TODO ensure that the user namespace is enabled // See `man lxc.container.conf` lxc.idmap. for _, m := range spec.Linux.UIDMappings { diff --git a/cmd/mount.go b/lxcontainer/mount.go similarity index 98% rename from cmd/mount.go rename to lxcontainer/mount.go index 265e35f8..d291b85c 100644 --- a/cmd/mount.go +++ b/lxcontainer/mount.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "fmt" @@ -10,7 +10,7 @@ import ( "github.com/pkg/errors" ) -func configureMounts(spec *specs.Spec) error { +func configureMounts(clxc *Runtime, spec *specs.Spec) error { // excplicitly disable auto-mounting if err := clxc.setConfigItem("lxc.mount.auto", ""); err != nil { return err diff --git a/cmd/mount_test.go b/lxcontainer/mount_test.go similarity index 99% rename from cmd/mount_test.go rename to lxcontainer/mount_test.go index ca53770b..e1bbf71a 100644 --- a/cmd/mount_test.go +++ b/lxcontainer/mount_test.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "github.com/stretchr/testify/require" diff --git a/cmd/namespaces.go b/lxcontainer/namespaces.go similarity index 65% rename from cmd/namespaces.go rename to lxcontainer/namespaces.go index 64f0740c..e1bdc1a8 100644 --- a/cmd/namespaces.go +++ b/lxcontainer/namespaces.go @@ -1,7 +1,9 @@ -package main +package lxcontainer import ( "fmt" + "os" + "runtime" "strings" "github.com/opencontainers/runtime-spec/specs-go" @@ -36,7 +38,7 @@ func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { return flags, nil } -func configureNamespaces(namespaces []specs.LinuxNamespace) error { +func configureNamespaces(clxc *Runtime, namespaces []specs.LinuxNamespace) error { seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} for _, ns := range namespaces { if _, ok := seenNamespaceTypes[ns.Type]; ok { @@ -79,3 +81,46 @@ func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool } return false } + +func getNamespace(nsType specs.LinuxNamespaceType, namespaces []specs.LinuxNamespace) *specs.LinuxNamespace { + for _, n := range namespaces { + if n.Type == nsType { + return &n + } + } + return nil +} + +// lxc does not set the hostname on shared namespaces +func setHostname(nsPath string, hostname string) error { + // setns only affects the current thread + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + f, err := os.Open(nsPath) + if err != nil { + return fmt.Errorf("failed to open uts namespace %s: %w", nsPath, err) + } + // #nosec + defer f.Close() + + self, err := os.Open("/proc/self/ns/uts") + if err != nil { + return fmt.Errorf("failed to open /proc/self/ns/uts: %w", err) + } + // #nosec + defer func() { + unix.Setns(int(self.Fd()), unix.CLONE_NEWUTS) + self.Close() + }() + + err = unix.Setns(int(f.Fd()), unix.CLONE_NEWUTS) + if err != nil { + return fmt.Errorf("failed to switch to UTS namespace %s: %w", nsPath, err) + } + err = unix.Sethostname([]byte(hostname)) + if err != nil { + return fmt.Errorf("unix.Sethostname failed: %w", err) + } + return nil +} diff --git a/cmd/runtime.go b/lxcontainer/runtime.go similarity index 95% rename from cmd/runtime.go rename to lxcontainer/runtime.go index 8a032471..7e82dc73 100644 --- a/cmd/runtime.go +++ b/lxcontainer/runtime.go @@ -1,4 +1,4 @@ -package main +package lxcontainer import ( "context" @@ -22,9 +22,7 @@ import ( // logging constants const ( // liblxc timestamp formattime format - timeFormatLXCMillis = "20060102150405.000" - defaultContainerLogLevel = lxc.WARN - defaultLogLevel = zerolog.WarnLevel + timeFormatLXCMillis = "20060102150405.000" ) // ContainerState represents the state of a container. @@ -52,7 +50,7 @@ var errContainerExist = errors.New("container already exists") var version string -func versionString() string { +func Version() string { return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) } @@ -205,7 +203,7 @@ func (c *Runtime) configureCgroupPath() error { } // Release releases/closes allocated resources (lxc.Container, LogFile) -func (c Runtime) release() error { +func (c Runtime) Release(err error) error { if c.Container != nil { if err := c.Container.Release(); err != nil { log.Error().Err(err).Msg("failed to release container") @@ -217,7 +215,29 @@ func (c Runtime) release() error { return nil } -func (c *Runtime) configureLogging() error { + + cmdDuration := time.Since(startTime) + if err != nil { + log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") + } else { + log.Info().Dur("duration", cmdDuration).Msg("cmd completed") + } + + if err := clxc.Release(); err != nil { + log.Error().Err(err).Msg("failed to release container") + } + + if err != nil { + if err, yes := err.(execError); yes { + os.Exit(err.ExitStatus()) + } else { + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) + os.Exit(1) + } + } + +func (c *Runtime) ConfigureLogging(cmdName string) error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) if err != nil { @@ -249,11 +269,11 @@ func (c *Runtime) configureLogging() error { // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 log = zerolog.New(c.LogFile).With().Timestamp().Caller(). - Str("cmd", c.Command).Str("cid", c.ContainerID).Logger() + Str("cmd", cmdName).Str("cid", c.ContainerID).Logger() level, err := zerolog.ParseLevel(strings.ToLower(c.LogLevel)) if err != nil { - level = defaultLogLevel + level = zerolog.InfoLevel log.Warn().Err(err).Str("val", c.LogLevel).Stringer("default", level). Msg("failed to parse log-level - fallback to default") } @@ -298,9 +318,9 @@ func (c *Runtime) parseContainerLogLevel() lxc.LogLevel { return lxc.FATAL default: log.Warn().Str("val", c.ContainerLogLevel). - Stringer("default", defaultContainerLogLevel). + Stringer("default", lxc.WARN). Msg("failed to parse container-log-level - fallback to default") - return defaultContainerLogLevel + return lxc.WARN } } @@ -576,9 +596,13 @@ func (c *Runtime) Start(timeout time.Duration) error { return c.waitRunning(timeout) } +func (c *Runtime) syncFifoPath() string { + return c.RuntimePath(initDir, "syncfifo") +} + func (c *Runtime) readFifo() error { // #nosec - f, err := os.OpenFile(syncFifoPath(), os.O_RDONLY, 0) + f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) if err != nil { return errors.Wrap(err, "failed to open sync fifo") } diff --git a/cmd/seccomp.go b/lxcontainer/seccomp.go similarity index 88% rename from cmd/seccomp.go rename to lxcontainer/seccomp.go index 613c4257..938114ba 100644 --- a/cmd/seccomp.go +++ b/lxcontainer/seccomp.go @@ -1,8 +1,7 @@ -package main +package lxcontainer import ( "bufio" - "bytes" "fmt" "os" "strings" @@ -23,19 +22,6 @@ var seccompAction = map[specs.LinuxSeccompAction]string{ //specs.ActKillProcess: "kill_process", } -func configureSeccomp(spec *specs.Spec) error { - if spec.Linux.Seccomp == nil || len(spec.Linux.Seccomp.Syscalls) == 0 { - return nil - } - - profilePath := clxc.RuntimePath("seccomp.conf") - if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { - return err - } - - return clxc.setConfigItem("lxc.seccomp.profile", profilePath) -} - // Note seccomp flags (see `man 2 seccomp`) are currently not supported // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md#seccomp func writeSeccompProfile(profilePath string, seccomp *specs.LinuxSeccomp) error { @@ -118,11 +104,6 @@ func seccompArchs(seccomp *specs.LinuxSeccomp) ([]string, error) { return archs, nil } -func nullTerminatedString(data []byte) string { - i := bytes.Index(data, []byte{0}) - return string(data[:i]) -} - func writeSeccompSyscall(w *bufio.Writer, sc specs.LinuxSyscall) error { for _, name := range sc.Names { action, ok := seccompAction[sc.Action] diff --git a/cmd/utils.go b/lxcontainer/utils.go similarity index 95% rename from cmd/utils.go rename to lxcontainer/utils.go index 52cdf2c1..2e9c8bd6 100644 --- a/cmd/utils.go +++ b/lxcontainer/utils.go @@ -1,6 +1,7 @@ -package main +package lxcontainer import ( + "bytes" "encoding/json" "fmt" "os" @@ -123,3 +124,8 @@ func encodeFileJSON(dst string, obj interface{}, flags int, mode uint32) error { } return nil } + +func nullTerminatedString(data []byte) string { + i := bytes.Index(data, []byte{0}) + return string(data[:i]) +} From d8c5ba61fde131c16bd847cee38436df3d666ac0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 09:24:25 +0100 Subject: [PATCH 101/373] refactor: Move logger to runtime instance. Signed-off-by: Ruben Jenster --- cmd/cli.go | 27 ++++++++++++++++++++++----- cmd/util.go | 4 ++-- lxcontainer/runtime.go | 28 +++------------------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index bdaf5482..21776035 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -4,9 +4,7 @@ import ( "encoding/json" "fmt" "github.com/pkg/errors" - "io/ioutil" "os" - "strings" "time" "github.com/lxc/crio-lxc/lxcontainer" @@ -184,7 +182,7 @@ func main() { if err := clxc.ConfigureLogging(ctx.Command.Name); err != nil { return err } - // log.Debug().Strs("args", os.Args).Msg("run cmd") + // log.Debug().Strs("args", os.Args).Msg("run cmd") return nil } @@ -205,9 +203,28 @@ func main() { app.CommandNotFound = func(ctx *cli.Context, cmd string) { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } - + err := app.Run(os.Args) - clxc.Release(err) + + if err := clxc.Release(); err != nil { + clxc.Log.Error().Err(err).Msg("failed to release container") + } + + cmdDuration := time.Since(startTime) + + if err == nil { + clxc.Debug().Dur("duration", cmdDuration).Msg("cmd completed") + return + } + + clxc.Log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") + // exit with exit status of executed command + if err, yes := err.(execError); yes { + os.Exit(err.ExitStatus()) + } + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) + os.Exit(1) } var createCmd = cli.Command{ diff --git a/cmd/util.go b/cmd/util.go index 76878d91..23b128b5 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -13,8 +13,8 @@ import ( ) func setEnv(key, val string, overwrite bool) error { - _, exist := os.LookupEnv(key) - if !exist || overwrite { + _, exist := os.LookupEnv(key) + if !exist || overwrite { return os.Setenv(key, val) } return nil diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 7e82dc73..c5da8703 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -43,8 +43,6 @@ const ( StateStopped ContainerState = "stopped" ) -var log zerolog.Logger - var errContainerNotExist = errors.New("container does not exist") var errContainerExist = errors.New("container already exists") @@ -80,6 +78,8 @@ type Runtime struct { // start flags StartTimeout time.Duration + + Log zerolog.Logger } // createContainer creates a new container. @@ -203,7 +203,7 @@ func (c *Runtime) configureCgroupPath() error { } // Release releases/closes allocated resources (lxc.Container, LogFile) -func (c Runtime) Release(err error) error { +func (c Runtime) Release() error { if c.Container != nil { if err := c.Container.Release(); err != nil { log.Error().Err(err).Msg("failed to release container") @@ -215,28 +215,6 @@ func (c Runtime) Release(err error) error { return nil } - - cmdDuration := time.Since(startTime) - if err != nil { - log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") - } else { - log.Info().Dur("duration", cmdDuration).Msg("cmd completed") - } - - if err := clxc.Release(); err != nil { - log.Error().Err(err).Msg("failed to release container") - } - - if err != nil { - if err, yes := err.(execError); yes { - os.Exit(err.ExitStatus()) - } else { - // write diagnostics message to stderr for crio/kubelet - println(err.Error()) - os.Exit(1) - } - } - func (c *Runtime) ConfigureLogging(cmdName string) error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) From f86bb7ad2e72e9fe93f0637b64b672f2beff153a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 09:44:58 +0100 Subject: [PATCH 102/373] cgroup: Get rid of errors package. Use runtime for logging. Signed-off-by: Ruben Jenster --- lxcontainer/cgroup.go | 29 +++++++++------------- lxcontainer/create.go | 57 ++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 47 deletions(-) diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 5d158938..73d13ad8 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -11,7 +11,6 @@ import ( "time" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -26,7 +25,7 @@ func configureCgroup(clxc *Runtime, spec *specs.Spec) error { } if mem := spec.Linux.Resources.Memory; mem != nil { - log.Debug().Msg("TODO cgroup memory controller not implemented") + clxc.Log.Debug().Msg("TODO cgroup memory controller not implemented") } if cpu := spec.Linux.Resources.CPU; cpu != nil { @@ -41,15 +40,15 @@ func configureCgroup(clxc *Runtime, spec *specs.Spec) error { } } if blockio := spec.Linux.Resources.BlockIO; blockio != nil { - log.Debug().Msg("TODO cgroup blockio controller not implemented") + clxc.Log.Debug().Msg("TODO cgroup blockio controller not implemented") } if hugetlb := spec.Linux.Resources.HugepageLimits; hugetlb != nil { // set Hugetlb limit (in bytes) - log.Debug().Msg("TODO cgroup hugetlb controller not implemented") + clxc.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") } if net := spec.Linux.Resources.Network; net != nil { - log.Debug().Msg("TODO cgroup network controller not implemented") + clxc.Log.Debug().Msg("TODO cgroup network controller not implemented") } return nil } @@ -59,7 +58,7 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { devicesDeny := "lxc.cgroup2.devices.deny" if !clxc.CgroupDevices { - log.Warn().Msg("cgroup device controller is disabled (access to all devices is granted)") + clxc.Log.Warn().Msg("cgroup device controller is disabled (access to all devices is granted)") // allow read-write-mknod access to all char and block devices if err := clxc.setConfigItem(devicesAllow, "b *:* rwm"); err != nil { return err @@ -126,7 +125,7 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { func configureCPUController(clxc *Runtime, slinux *specs.LinuxCPU) error { // CPU resource restriction configuration // use strconv.FormatUint(n, 10) instead of fmt.Sprintf ? - log.Debug().Msg("TODO configure cgroup cpu controller") + clxc.Log.Debug().Msg("TODO configure cgroup cpu controller") /* if cpu.Shares != nil && *cpu.Shares > 0 { if err := clxc.setConfigItem("lxc.cgroup2.cpu.shares", fmt.Sprintf("%d", *cpu.Shares)); err != nil { @@ -197,7 +196,7 @@ func (cg *cgroupInfo) loadProcs() error { // #nosec procsData, err := ioutil.ReadFile(cgroupProcsPath) if err != nil { - return errors.Wrapf(err, "failed to read control group process list %s", cgroupProcsPath) + return fmt.Errorf("failed to read cgroup.procs: %w", err) } // cgroup.procs contains one PID per line and is newline separated. // A trailing newline is always present. @@ -210,7 +209,7 @@ func (cg *cgroupInfo) loadProcs() error { for _, s := range pidStrings { pid, err := strconv.Atoi(s) if err != nil { - return errors.Wrapf(err, "failed to convert PID %q to number", s) + return fmt.Errorf("failed to convert PID %q to number: %w", s, err) } cg.Procs = append(cg.Procs, pid) } @@ -247,14 +246,12 @@ func killCgroupProcs(cgroupName string, sig unix.Signal) error { fullPath := filepath.Join(dirName, i.Name()) cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) if err != nil { - log.Warn().Err(err).Str("file", fullPath).Msg("failed to read cgroup proces") - return err + return fmt.Errorf("failed to load cgroup %s: %w", i.Name(), err) } for _, pid := range cg.Procs { - log.Warn().Int("pid", pid).Msg("killing left-over process") err := unix.Kill(pid, sig) if err != nil && err != unix.ESRCH { - return errors.Wrapf(err, "failed to kill %d", pid) + return fmt.Errorf("failed to kill %d: %w", pid, err) } } } @@ -293,9 +290,8 @@ func drainCgroup(cgroupName string, sig unix.Signal, timeout time.Duration) erro } err = killCgroupProcs(cgroupName, sig) if err != nil { - return errors.Wrapf(err, "failed to kill cgroup procs %s", cgroupName) + return fmt.Errorf("failed to kill cgroup procs: %w", err) } - log.Trace().Str("cgroup", cgroupName).Msg("waiting for cgroup to drain") time.Sleep(time.Millisecond * 50) } return fmt.Errorf("timeout") @@ -323,8 +319,7 @@ func deleteCgroup(cgroupName string) error { p := filepath.Join(dirName, i.Name()) err := unix.Rmdir(p) if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", p).Msg("failed to remove cgroup dir") - return err + return fmt.Errorf("failed to dir %s: %w", p, err) } } } diff --git a/lxcontainer/create.go b/lxcontainer/create.go index bbd152a5..cc35c31a 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -9,12 +9,9 @@ import ( "strings" "time" - "golang.org/x/sys/unix" - "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - + "golang.org/x/sys/unix" lxc "gopkg.in/lxc/go-lxc.v2" ) @@ -42,22 +39,22 @@ func doCreateInternal(clxc *Runtime) error { err = clxc.createContainer(spec) if err != nil { - return errors.Wrap(err, "failed to create container") + return fmt.Errorf("failed to create container: %w", err) } if err := configureContainer(clxc, spec); err != nil { - return errors.Wrap(err, "failed to configure container") + return fmt.Errorf("failed to configure container: %w", err) } // #nosec startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) if err := runStartCmd(clxc, startCmd, spec); err != nil { - return errors.Wrap(err, "failed to start container process") + return fmt.Errorf("failed to start container process: %w", err) } - log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + clxc.Log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") if err := clxc.waitCreated(time.Second * 10); err != nil { - log.Error().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + clxc.Log.Error().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") return err } return createPidFile(clxc.PidFile, startCmd.Process.Pid) @@ -89,7 +86,7 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { } if err := configureNamespaces(clxc, spec.Linux.Namespaces); err != nil { - return errors.Wrap(err, "failed to configure namespaces") + return fmt.Errorf("failed to configure namespaces: %w", err) } if spec.Process.OOMScoreAdj != nil { @@ -106,10 +103,10 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { if clxc.Apparmor { if err := configureApparmor(clxc, spec); err != nil { - return errors.Wrap(err, "failed to configure apparmor") + return fmt.Errorf("failed to configure apparmor: %w", err) } } else { - log.Warn().Msg("apparmor is disabled (unconfined)") + clxc.Log.Warn().Msg("apparmor is disabled (unconfined)") } if clxc.Seccomp { @@ -124,15 +121,15 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { } } } else { - log.Warn().Msg("seccomp is disabled") + clxc.Log.Warn().Msg("seccomp is disabled") } if clxc.Capabilities { if err := configureCapabilities(clxc, spec); err != nil { - return errors.Wrap(err, "failed to configure capabilities") + return fmt.Errorf("failed to configure capabilities: %w", err) } } else { - log.Warn().Msg("capabilities are disabled") + clxc.Log.Warn().Msg("capabilities are disabled") } if spec.Hostname != "" { @@ -143,21 +140,21 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { uts := getNamespace(specs.UTSNamespace, spec.Linux.Namespaces) if uts != nil && uts.Path != "" { if err := setHostname(uts.Path, spec.Hostname); err != nil { - return errors.Wrap(err, "set hostname") + return fmt.Errorf("failed to set hostname: %w", err) } } } if err := ensureDefaultDevices(clxc, spec); err != nil { - return errors.Wrap(err, "failed to add default devices") + return fmt.Errorf("failed to add default devices: %w", err) } if err := clxc.configureCgroupPath(); err != nil { - return errors.Wrap(err, "failed to configure cgroups path") + return fmt.Errorf("failed to configure cgroups path: %w", err) } if err := configureCgroup(clxc, spec); err != nil { - return errors.Wrap(err, "failed to configure cgroups") + return fmt.Errorf("failed to configure cgroups: %w", err) } for key, val := range spec.Linux.Sysctl { @@ -205,12 +202,12 @@ func configureRootfs(clxc *Runtime, spec *specs.Spec) error { func configureReadonlyPaths(clxc *Runtime, spec *specs.Spec) error { rootmnt := clxc.getConfigItem("lxc.rootfs.mount") if rootmnt == "" { - return errors.New("lxc.rootfs.mount unavailable") + return fmt.Errorf("lxc.rootfs.mount unavailable") } for _, p := range spec.Linux.ReadonlyPaths { mnt := fmt.Sprintf("%s %s %s %s", filepath.Join(rootmnt, p), strings.TrimPrefix(p, "/"), "bind", "bind,ro,optional") if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { - return errors.Wrap(err, "failed to make path readonly") + return fmt.Errorf("failed to make path readonly: %w", err) } } return nil @@ -354,7 +351,7 @@ func runStartCmd(clxc *Runtime, cmd *exec.Cmd, spec *specs.Spec) error { // Inherit stdio from calling process (conmon). // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc if err := clxc.setConfigItem("lxc.console.path", "none"); err != nil { - return errors.Wrap(err, "failed to disable PTY") + return fmt.Errorf("failed to disable PTY: %w", err) } cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout @@ -366,11 +363,11 @@ func runStartCmd(clxc *Runtime, cmd *exec.Cmd, spec *specs.Spec) error { } if err := writeDevices(clxc.RuntimePath("devices.txt"), spec); err != nil { - return errors.Wrap(err, "failed to create devices.txt") + return fmt.Errorf("failed to create devices.txt: %w", err) } if err := writeMasked(clxc.RuntimePath("masked.txt"), spec); err != nil { - return errors.Wrap(err, "failed to create masked.txt file") + return fmt.Errorf("failed to create masked.txt: %w", err) } return cmd.Start() @@ -428,26 +425,26 @@ func writeMasked(dst string, spec *specs.Spec) error { func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string, timeout time.Duration) error { addr, err := net.ResolveUnixAddr("unix", consoleSocket) if err != nil { - return errors.Wrap(err, "failed to resolve console socket") + return fmt.Errorf("failed to resolve console socket: %w", err) } conn, err := net.DialUnix("unix", nil, addr) if err != nil { - return errors.Wrap(err, "connecting to console socket failed") + return fmt.Errorf("connecting to console socket failed: %w", err) } defer conn.Close() deadline := time.Now().Add(timeout) err = conn.SetDeadline(deadline) if err != nil { - return errors.Wrap(err, "failed to set connection deadline") + return fmt.Errorf("failed to set connection deadline: %w", err) } sockFile, err := conn.File() if err != nil { - return errors.Wrap(err, "failed to get file from unix connection") + return fmt.Errorf("failed to get file from unix connection: %w", err) } ptmx, err := pty.Start(cmd) if err != nil { - return errors.Wrap(err, "failed to start with pty") + return fmt.Errorf("failed to start with pty: %w", err) } // Send the pty file descriptor over the console socket (to the 'conmon' process) @@ -458,7 +455,7 @@ func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string, timeout time.Durati // Don't know whether 'terminal' is the right data to send, but conmon doesn't care anyway. err = unix.Sendmsg(int(sockFile.Fd()), []byte("terminal"), oob, nil, 0) if err != nil { - return errors.Wrap(err, "failed to send console fd") + return fmt.Errorf("failed to send console fd: %w", err) } return ptmx.Close() } From 000a8d3b0205a26b04c2d6e10e67fadf7e19cb08 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 14:44:54 +0100 Subject: [PATCH 103/373] refactor: Move non cli code to runtime struct. Signed-off-by: Ruben Jenster --- cmd/cli.go | 169 +++++++++++++--------- cmd/util.go | 23 ++- lxcontainer/cgroup.go | 102 ++++++++++---- lxcontainer/cgroup_test.go | 6 +- lxcontainer/container.go | 2 +- lxcontainer/create.go | 186 +++++++++++------------- lxcontainer/init.go | 16 +-- lxcontainer/mount.go | 29 ++-- lxcontainer/mount_test.go | 3 +- lxcontainer/namespaces.go | 3 +- lxcontainer/runtime.go | 281 ++++++++++++++----------------------- lxcontainer/seccomp.go | 5 +- lxcontainer/utils.go | 21 +-- 13 files changed, 418 insertions(+), 428 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 21776035..a3f442be 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -1,10 +1,11 @@ package main import ( + "context" "encoding/json" "fmt" - "github.com/pkg/errors" "os" + "os/exec" "time" "github.com/lxc/crio-lxc/lxcontainer" @@ -16,7 +17,17 @@ import ( var envFile = "/etc/default/crio-lxc" // The singelton that wraps the lxc.Container -var clxc lxcontainer.Runtime +var clxc struct { + lxcontainer.Runtime + + Command string + CreateHook string + + CreateTimeout time.Duration + StartTimeout time.Duration + KillTimeout time.Duration + DeleteTimeout time.Duration +} func main() { app := cli.NewApp() @@ -100,26 +111,6 @@ func main() { Value: "/usr/local/bin/crio-lxc-container-hook", Destination: &clxc.ContainerHook, }, - &cli.StringFlag{ - Name: "runtime-hook", - Usage: "absolute path to runtime hook executable", - EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK"}, - Destination: &clxc.RuntimeHook, - }, - &cli.DurationFlag{ - Name: "runtime-hook-timeout", - Usage: "duration after which the runtime hook is killed", - EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK_TIMEOUT"}, - Value: time.Second * 5, - Destination: &clxc.RuntimeHookTimeout, - }, - &cli.BoolFlag{ - Name: "runtime-hook-always", - Usage: "if true runtime hook will run on every create - not only on error", - EnvVars: []string{"CRIO_LXC_RUNTIME_HOOK_RUN_ALWAYS"}, - Value: false, - Destination: &clxc.RuntimeHookRunAlways, - }, &cli.BoolFlag{ Name: "apparmor", Usage: "set apparmor profile defined in container spec", @@ -157,12 +148,17 @@ func main() { // FIXME when calling '--help' defaults are overwritten with environment variables. // So you will never see the real default value if either an environment file is present // or an environment variable is set. - env, envErr := loadEnvFile(envFile) + env, err := loadEnvFile(envFile) + if err != nil { + println(err.Error()) + os.Exit(1) + } if env != nil { for key, val := range env { if err := setEnv(key, val, false); err != nil { - envErr = err - break + err = fmt.Errorf("failed to set environment variable \"%s=%s\": %w", err) + println(err.Error()) + os.Exit(1) } } } @@ -175,15 +171,11 @@ func main() { setupCmd := func(ctx *cli.Context) error { containerID := ctx.Args().Get(0) if len(containerID) == 0 { - return errors.New("missing container ID") + return fmt.Errorf("missing container ID") } clxc.ContainerID = containerID - if err := clxc.ConfigureLogging(ctx.Command.Name); err != nil { - return err - } - // log.Debug().Strs("args", os.Args).Msg("run cmd") - return nil + return clxc.ConfigureLogging(ctx.Command.Name) } // Disable the default error messages for cmdline errors. @@ -204,7 +196,7 @@ func main() { fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) } - err := app.Run(os.Args) + err = app.Run(os.Args) if err := clxc.Release(); err != nil { clxc.Log.Error().Err(err).Msg("failed to release container") @@ -213,7 +205,7 @@ func main() { cmdDuration := time.Since(startTime) if err == nil { - clxc.Debug().Dur("duration", cmdDuration).Msg("cmd completed") + clxc.Log.Debug().Dur("duration", cmdDuration).Msg("cmd completed") return } @@ -250,19 +242,49 @@ var createCmd = cli.Command{ Destination: &clxc.PidFile, }, &cli.DurationFlag{ - Name: "socket-timeout", - Usage: "timeout for sending pty master to socket", - EnvVars: []string{"CRIO_LXC_CREATE_SOCKET_TIMEOUT"}, + Name: "timeout", + Usage: "maximum duration for create to complete", + EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, Value: time.Second * 60, - Destination: &clxc.ConsoleSocketTimeout, + Destination: &clxc.CreateTimeout, + }, + &cli.StringFlag{ + Name: "create-hook", + Usage: "absolute path to executable to run after create", + EnvVars: []string{"CRIO_LXC_CREATE_HOOK"}, + Destination: &clxc.CreateHook, }, }, } -func doCreate(ctx *cli.Context) error { - err := doCreateInternal() - if err != nil || clxc.RuntimeHookRunAlways { - clxc.executeRuntimeHook(err) +func doCreate(unused *cli.Context) error { + ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateTimeout) + defer cancel() + + err := clxc.Create(ctx) + + if clxc.CreateHook != "" { + env := []string{ + "CONTAINER_ID=" + clxc.ContainerID, + "LXC_CONFIG=" + clxc.ConfigFilePath(), + "RUNTIME_CMD=" + clxc.Command, + "RUNTIME_PATH=" + clxc.RuntimePath(), + "BUNDLE_PATH=" + clxc.BundlePath, + "SPEC_PATH=" + clxc.SpecPath(), + "LOG_FILE=" + clxc.LogFilePath, + } + if err != nil { + env = append(env, "RUNTIME_ERROR="+err.Error()) + } + cmd := exec.CommandContext(ctx, clxc.CreateHook) + cmd.Env = env + + clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("execute create hook") + if err := cmd.Run(); err != nil { + clxc.Log.Error().Err(err).Str("file", clxc.CreateHook).Msg("failed to execute create hook") + } else { + clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("failed to execute runtime hook") + } } return err } @@ -277,16 +299,19 @@ starts `, Flags: []cli.Flag{ &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for reading from syncfifo", - EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, - Value: time.Second * 5, + Name: "timeout", + Usage: "timeout for reading from syncfifo", + EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, + Value: time.Second * 30, + Destination: &clxc.StartTimeout, }, }, } -func doStart(ctx *cli.Context) error { - return clxc.Start(ctx.Duration("timeout")) +func doStart(unused *cli.Context) error { + ctx, cancel := context.WithTimeout(context.Background(), clxc.StartTimeout) + defer cancel() + return clxc.Start(ctx) } var stateCmd = cli.Command{ @@ -300,14 +325,17 @@ var stateCmd = cli.Command{ Flags: []cli.Flag{}, } -func doState(ctx *cli.Context) error { +func doState(unused *cli.Context) error { state, err := clxc.State() - if j, err := json.Marshal(state); err == nil { - fmt.Fprint(os.Stdout, string(j)) - log.Trace().RawJSON("state", j).Msg("container state") - } else { - return errors.Wrap(err, "failed to marshal json") + if err != nil { + return err } + j, err := json.Marshal(state) + if err != nil { + return fmt.Errorf("failed to marshal json: %w", err) + } + clxc.Log.Trace().RawJSON("state", j).Msg("container state") + _, err = fmt.Fprint(os.Stdout, string(j)) return err } @@ -320,6 +348,15 @@ var killCmd = cli.Command{ is the ID of the container to send a signal to [signal] signal name or numerical value (e.g [9|kill|KILL|sigkill|SIGKILL]) `, + Flags: []cli.Flag{ + &cli.DurationFlag{ + Name: "timeout", + Usage: "timeout for killing all processes in container cgroup", + EnvVars: []string{"CRIO_LXC_KILL_TIMEOUT"}, + Value: time.Second * 10, + Destination: &clxc.KillTimeout, + }, + }, } func doKill(ctx *cli.Context) error { @@ -328,7 +365,9 @@ func doKill(ctx *cli.Context) error { if signum == 0 { return fmt.Errorf("invalid signal param %q", sig) } - return clxc.Kill(signum) + c, cancel := context.WithTimeout(context.Background(), clxc.KillTimeout) + defer cancel() + return clxc.Kill(c, signum) } var deleteCmd = cli.Command{ @@ -344,11 +383,20 @@ var deleteCmd = cli.Command{ Name: "force", Usage: "force deletion", }, + &cli.DurationFlag{ + Name: "timeout", + Usage: "timeout for deleting container", + EnvVars: []string{"CRIO_LXC_DELETE_TIMEOUT"}, + Value: time.Second * 10, + Destination: &clxc.DeleteTimeout, + }, }, } func doDelete(ctx *cli.Context) error { - return clxc.Delete(ctx.Bool("force")) + c, cancel := context.WithTimeout(context.Background(), clxc.DeleteTimeout) + defer cancel() + return clxc.Delete(c, ctx.Bool("force")) } var execCmd = cli.Command{ @@ -396,15 +444,10 @@ func doExec(ctx *cli.Context) error { detach := ctx.Bool("detach") if detach && pidFile == "" { - log.Warn().Msg("detaching process but pid-file value is unset") - } - - err := clxc.loadContainer() - if err != nil { - return err + clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := ReadSpecProcess(ctx.String("process")) + procSpec, err := lxcontainer.ReadSpecProcess(ctx.String("process")) if err != nil { return err } @@ -418,7 +461,7 @@ func doExec(ctx *cli.Context) error { return err } if pidFile != "" { - return createPidFile(pidFile, pid) + return lxcontainer.CreatePidFile(pidFile, pid) } } else { status, err := clxc.Exec(args, procSpec) diff --git a/cmd/util.go b/cmd/util.go index 23b128b5..d57ead1a 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -2,14 +2,12 @@ package main import ( "fmt" - "github.com/pkg/errors" "io/ioutil" "os" + "strconv" "strings" - "time" - "github.com/lxc/crio-lxc/lxcontainer" - "github.com/urfave/cli/v2" + "golang.org/x/sys/unix" ) func setEnv(key, val string, overwrite bool) error { @@ -45,6 +43,23 @@ func loadEnvFile(envFile string) (map[string]string, error) { return env, nil } +func parseSignal(sig string) unix.Signal { + if sig == "" { + return unix.SIGTERM + } + // handle numerical signal value + if num, err := strconv.Atoi(sig); err == nil { + return unix.Signal(num) + } + + // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' + s := strings.ToUpper(sig) + if !strings.HasPrefix(s, "SIG") { + s = "SIG" + s + } + return unix.SignalNum(s) +} + /* func logEnv(log *zerolog.Log) if env != nil { diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 73d13ad8..6e74ae57 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -2,6 +2,7 @@ package lxcontainer import ( "bytes" + "context" "fmt" "io/ioutil" "os" @@ -10,8 +11,14 @@ import ( "strings" "time" - "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +const ( + allControllers = "+cpuset +cpu +io +memory +hugetlb +pids +rdma" + cgroupRoot = "/sys/fs/cgroup" ) // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md @@ -192,7 +199,7 @@ type cgroupInfo struct { } func (cg *cgroupInfo) loadProcs() error { - cgroupProcsPath := filepath.Join("/sys/fs/cgroup", cg.Name, "cgroup.procs") + cgroupProcsPath := filepath.Join(cgroupRoot, cg.Name, "cgroup.procs") // #nosec procsData, err := ioutil.ReadFile(cgroupProcsPath) if err != nil { @@ -225,7 +232,7 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { } func killCgroupProcs(cgroupName string, sig unix.Signal) error { - dirName := filepath.Join("/sys/fs/cgroup", cgroupName) + dirName := filepath.Join(cgroupRoot, cgroupName) // #nosec dir, err := os.Open(dirName) if os.IsNotExist(err) { @@ -243,7 +250,6 @@ func killCgroupProcs(cgroupName string, sig unix.Signal) error { } for _, i := range entries { if i.IsDir() && i.Name() != "." && i.Name() != ".." { - fullPath := filepath.Join(dirName, i.Name()) cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) if err != nil { return fmt.Errorf("failed to load cgroup %s: %w", i.Name(), err) @@ -262,8 +268,8 @@ func killCgroupProcs(cgroupName string, sig unix.Signal) error { // TODO maybe use polling instead // fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} // n, err := unix.Poll(fds, timeout) -func drainCgroup(cgroupName string, sig unix.Signal, timeout time.Duration) error { - p := filepath.Join("/sys/fs/cgroup", cgroupName, "cgroup.events") +func drainCgroup(ctx context.Context, cgroupName string, sig unix.Signal) error { + p := filepath.Join(cgroupRoot, cgroupName, "cgroup.events") f, err := os.OpenFile(p, os.O_RDONLY, 0) if err != nil { return err @@ -271,34 +277,38 @@ func drainCgroup(cgroupName string, sig unix.Signal, timeout time.Duration) erro var buf bytes.Buffer buf.Grow(64) - deadline := time.Now().Add(timeout) - for time.Now().Before(deadline) { - buf.Reset() - _, err = f.Seek(0, os.SEEK_SET) - if err != nil { - return err - } - _, err := buf.ReadFrom(f) - if err != nil { - return err - } - for _, line := range strings.Split(buf.String(), "\n") { - if line == "populated 0" { - return nil + for { + select { + case <-ctx.Done(): + return fmt.Errorf("drain group aborted: %w", ctx.Err()) + default: + buf.Reset() + _, err = f.Seek(0, os.SEEK_SET) + if err != nil { + return err } + _, err := buf.ReadFrom(f) + if err != nil { + return err + } + + for _, line := range strings.Split(buf.String(), "\n") { + if line == "populated 0" { + return nil + } + } + err = killCgroupProcs(cgroupName, sig) + if err != nil { + return fmt.Errorf("failed to kill cgroup procs: %w", err) + } + time.Sleep(time.Millisecond * 50) } - err = killCgroupProcs(cgroupName, sig) - if err != nil { - return fmt.Errorf("failed to kill cgroup procs: %w", err) - } - time.Sleep(time.Millisecond * 50) } - return fmt.Errorf("timeout") } func deleteCgroup(cgroupName string) error { - dirName := filepath.Join("/sys/fs/cgroup", cgroupName) + dirName := filepath.Join(cgroupRoot, cgroupName) // #nosec dir, err := os.Open(dirName) if os.IsNotExist(err) { @@ -325,3 +335,41 @@ func deleteCgroup(cgroupName string) error { } return unix.Rmdir(dirName) } + +func createCgroup(cg string, controllers string) error { + // #nosec + cgPath := filepath.Join(cgroupRoot, cg) + if err := os.MkdirAll(cgPath, 755); err != nil { + return err + } + + base := cgroupRoot + for _, elem := range strings.Split(cg, "/") { + base = filepath.Join(base, elem) + c := filepath.Join(base, "cgroup.subtree_control") + err := ioutil.WriteFile(c, []byte(strings.TrimSpace(controllers)+"\n"), 0) + if err != nil { + return fmt.Errorf("failed to enable cgroup controllers: %w", err) + } + } + return nil +} + +func getControllers(cg string) (string, error) { + // enable all available controllers in the scope + data, err := ioutil.ReadFile(filepath.Join(cgroupRoot, cg, "group.controllers")) + if err != nil { + return "", fmt.Errorf("failed to read cgroup.controllers: %w", err) + } + controllers := strings.Split(strings.TrimSpace(string(data)), " ") + + var b strings.Builder + for i, c := range controllers { + if i > 0 { + b.WriteByte(' ') + } + b.WriteByte('+') + b.WriteString(c) + } + return b.String(), nil +} diff --git a/lxcontainer/cgroup_test.go b/lxcontainer/cgroup_test.go index 72bb3e05..f10bbbf9 100644 --- a/lxcontainer/cgroup_test.go +++ b/lxcontainer/cgroup_test.go @@ -1,9 +1,11 @@ package lxcontainer import ( - "github.com/stretchr/testify/require" - "golang.org/x/sys/unix" "testing" + + "golang.org/x/sys/unix" + + "github.com/stretchr/testify/require" ) func TestParseSystemCgroupPath(t *testing.T) { diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 6ad07c73..03f12b15 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -61,7 +61,7 @@ func (c ContainerInfo) Pid() (int, error) { } func (c ContainerInfo) CreatePidFile(pid int) error { - return createPidFile(c.PidFile, pid) + return CreatePidFile(c.PidFile, pid) } // RuntimeRoot and ContainerID must be set diff --git a/lxcontainer/create.go b/lxcontainer/create.go index cc35c31a..abfa3b4f 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -1,21 +1,22 @@ package lxcontainer import ( + "context" "fmt" "net" "os" "os/exec" "path/filepath" "strings" - "time" + + "golang.org/x/sys/unix" "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/sys/unix" - lxc "gopkg.in/lxc/go-lxc.v2" + "gopkg.in/lxc/go-lxc.v2" ) -func doCreateInternal(clxc *Runtime) error { +func (clxc *Runtime) Create(ctx context.Context) error { err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return err @@ -45,35 +46,64 @@ func doCreateInternal(clxc *Runtime) error { if err := configureContainer(clxc, spec); err != nil { return fmt.Errorf("failed to configure container: %w", err) } + return clxc.runStartCmd(ctx, spec) +} +func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { // #nosec - startCmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) - if err := runStartCmd(clxc, startCmd, spec); err != nil { - return fmt.Errorf("failed to start container process: %w", err) + cmd := exec.CommandContext(ctx, clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) + cmd.Env = []string{} + cmd.Dir = clxc.RuntimePath() + + if clxc.ConsoleSocket == "" && !spec.Process.Terminal { + // Inherit stdio from calling process (conmon). + // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc + if err := clxc.setConfigItem("lxc.console.path", "none"); err != nil { + return err + } + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr } - clxc.Log.Info().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") - if err := clxc.waitCreated(time.Second * 10); err != nil { - clxc.Log.Error().Int("cpid", startCmd.Process.Pid).Int("pid", os.Getpid()).Int("ppid", os.Getppid()).Msg("started container process") + if err := clxc.saveConfig(); err != nil { return err } - return createPidFile(clxc.PidFile, startCmd.Process.Pid) -} -func configureContainer(clxc *Runtime, spec *specs.Spec) error { - if err := configureRootfs(clxc, spec); err != nil { - return err + if clxc.ConsoleSocket != "" { + err = runStartCmdConsole(ctx, cmd, clxc.ConsoleSocket) + } else { + err = cmd.Run() } - // pass context information as environment variables to hook scripts - if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { - return err + if err != nil { + return fmt.Errorf("failed to execute container process: %w", err) } - if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { + + if err := clxc.waitCreated(ctx); err != nil { return err } - if err := configureInit(clxc, spec); err != nil { + clxc.Log.Info().Int("pid", cmd.Process.Pid).Msg("container process is running") + return CreatePidFile(clxc.PidFile, cmd.Process.Pid) +} + +func configureContainer(clxc *Runtime, spec *specs.Spec) error { + + if spec.Hostname != "" { + if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { + return err + } + + uts := getNamespace(specs.UTSNamespace, spec.Linux.Namespaces) + if uts != nil && uts.Path != "" { + if err := setHostname(uts.Path, spec.Hostname); err != nil { + return fmt.Errorf("failed to set hostname: %w", err) + } + } + } + + if err := configureRootfs(clxc, spec); err != nil { return err } @@ -132,21 +162,24 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { clxc.Log.Warn().Msg("capabilities are disabled") } - if spec.Hostname != "" { - if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { - return err - } + if err := ensureDefaultDevices(clxc, spec); err != nil { + return fmt.Errorf("failed to add default devices: %w", err) + } - uts := getNamespace(specs.UTSNamespace, spec.Linux.Namespaces) - if uts != nil && uts.Path != "" { - if err := setHostname(uts.Path, spec.Hostname); err != nil { - return fmt.Errorf("failed to set hostname: %w", err) - } - } + if err := writeDevices(clxc.RuntimePath("devices.txt"), spec); err != nil { + return fmt.Errorf("failed to create devices.txt: %w", err) } - if err := ensureDefaultDevices(clxc, spec); err != nil { - return fmt.Errorf("failed to add default devices: %w", err) + if err := writeMasked(clxc.RuntimePath("masked.txt"), spec); err != nil { + return fmt.Errorf("failed to create masked.txt: %w", err) + } + + // pass context information as environment variables to hook scripts + if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { + return err + } + if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { + return err } if err := clxc.configureCgroupPath(); err != nil { @@ -170,7 +203,8 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { return err } } - return nil + + return configureInit(clxc, spec) } func configureRootfs(clxc *Runtime, spec *specs.Spec) error { @@ -317,62 +351,6 @@ func setenv(env []string, key, val string, overwrite bool) []string { return append(env, key+"="+val) } -func runStartCmd(clxc *Runtime, cmd *exec.Cmd, spec *specs.Spec) error { - // Start container with a clean environment. - // LXC will export variables defined in the config lxc.environment. - // The environment variables defined by the container spec are exported within the init cmd CRIO_LXC_INIT_CMD. - // This is required because environment variables defined by containers contain newlines and other tokens - // that can not be handled properly within the lxc config file. - cmd.Env = []string{} - /* - if cmd.SysProcAttr == nil { - cmd.SysProcAttr = &unix.SysProcAttr{} - } - - //cmd.SysProcAttr.Noctty = true - sig, err := getParentDeathSignal() - if err != nil { - return err - } - cmd.SysProcAttr.Pdeathsig = sig - //cmd.SysProcAttr.Foreground = false - //cmd.SysProcAttr.Setsid = true - */ - - cmd.Dir = clxc.RuntimePath() - - if clxc.ConsoleSocket != "" { - if err := clxc.saveConfig(); err != nil { - return err - } - return runStartCmdConsole(cmd, clxc.ConsoleSocket, clxc.ConsoleSocketTimeout) - } - if !spec.Process.Terminal { - // Inherit stdio from calling process (conmon). - // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc - if err := clxc.setConfigItem("lxc.console.path", "none"); err != nil { - return fmt.Errorf("failed to disable PTY: %w", err) - } - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - - if err := clxc.saveConfig(); err != nil { - return err - } - - if err := writeDevices(clxc.RuntimePath("devices.txt"), spec); err != nil { - return fmt.Errorf("failed to create devices.txt: %w", err) - } - - if err := writeMasked(clxc.RuntimePath("masked.txt"), spec); err != nil { - return fmt.Errorf("failed to create masked.txt: %w", err) - } - - return cmd.Start() -} - func writeDevices(dst string, spec *specs.Spec) error { if spec.Linux.Devices == nil { return nil @@ -382,11 +360,11 @@ func writeDevices(dst string, spec *specs.Spec) error { return err } for _, d := range spec.Linux.Devices { - uid := spec.Process.User.UID // FIXME use 0 instead ? + uid := spec.Process.User.UID if d.UID != nil { uid = *d.UID } - gid := spec.Process.User.GID // FIXME use 0 instead ? + gid := spec.Process.User.GID if d.GID == nil { gid = *d.GID } @@ -422,20 +400,24 @@ func writeMasked(dst string, spec *specs.Spec) error { return f.Close() } -func runStartCmdConsole(cmd *exec.Cmd, consoleSocket string, timeout time.Duration) error { - addr, err := net.ResolveUnixAddr("unix", consoleSocket) - if err != nil { - return fmt.Errorf("failed to resolve console socket: %w", err) - } - conn, err := net.DialUnix("unix", nil, addr) +func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string) error { + dialer := net.Dialer{} + c, err := dialer.DialContext(ctx, "unix", consoleSocket) if err != nil { return fmt.Errorf("connecting to console socket failed: %w", err) } - defer conn.Close() - deadline := time.Now().Add(timeout) - err = conn.SetDeadline(deadline) - if err != nil { - return fmt.Errorf("failed to set connection deadline: %w", err) + defer c.Close() + + conn, ok := c.(*net.UnixConn) + if !ok { + return fmt.Errorf("expected a unix connection but was %T", conn) + } + + if deadline, ok := ctx.Deadline(); ok { + err = conn.SetDeadline(deadline) + if err != nil { + return fmt.Errorf("failed to set connection deadline: %w", err) + } } sockFile, err := conn.File() diff --git a/lxcontainer/init.go b/lxcontainer/init.go index a1d9640b..ba38b2c8 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -2,12 +2,12 @@ package lxcontainer import ( "fmt" - "github.com/pkg/errors" - "golang.org/x/sys/unix" "os" "path/filepath" "strings" + "golang.org/x/sys/unix" + "github.com/opencontainers/runtime-spec/specs-go" ) @@ -29,12 +29,12 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { err := os.MkdirAll(rootfsInitDir, 0) if err != nil { - return errors.Wrapf(err, "failed to create init dir in rootfs %q", rootfsInitDir) + return fmt.Errorf("failed to create init dir in rootfs %q: %w", rootfsInitDir, err) } // #nosec err = os.MkdirAll(runtimeInitDir, 0755) if err != nil { - return errors.Wrapf(err, "failed to create runtime init dir %q", runtimeInitDir) + return fmt.Errorf("failed to create runtime init dir %q: %w", runtimeInitDir, err) } spec.Mounts = append(spec.Mounts, specs.Mount{ @@ -53,7 +53,7 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { // create files required for crio-lxc-init if err := createFifo(clxc.syncFifoPath(), uid, gid, 0600); err != nil { - return errors.Wrapf(err, "failed to create sync fifo") + return fmt.Errorf("failed to create sync fifo: %w", err) } if err := createList(filepath.Join(runtimeInitDir, "cmdline"), spec.Process.Args, uid, gid, 0400); err != nil { @@ -74,7 +74,7 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { initCmdPath := filepath.Join(runtimeInitDir, "init") err = touchFile(initCmdPath, 0) if err != nil { - return errors.Wrapf(err, "failed to create %s", initCmdPath) + return fmt.Errorf("failed to create %s: %w", initCmdPath, err) } initCmd := filepath.Join(initDir, "init") spec.Mounts = append(spec.Mounts, specs.Mount{ @@ -99,7 +99,7 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err // #nosec f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) if err != nil { - return errors.Wrapf(err, "failed to create init list %s", dst) + return fmt.Errorf("failed to create init list %s: %w", dst, err) } for _, arg := range entries { @@ -145,7 +145,7 @@ func configureInitUser(clxc *Runtime, spec *specs.Spec) error { return err } - if len(spec.Process.User.AdditionalGids) > 0 && supportsConfigItem("lxc.init.groups") { + if len(spec.Process.User.AdditionalGids) > 0 && clxc.supportsConfigItem("lxc.init.groups") { var b strings.Builder for i, gid := range spec.Process.User.AdditionalGids { if i > 0 { diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index d291b85c..d8b35e32 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) func configureMounts(clxc *Runtime, spec *specs.Spec) error { @@ -33,18 +32,18 @@ func configureMounts(clxc *Runtime, spec *specs.Spec) error { mountDest, err := resolveMountDestination(spec.Root.Path, ms.Destination) // Intermediate path resolution failed. This is not an error, since // the remaining directories / files are automatically created (create=dir|file) - log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") + clxc.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. if !filepath.HasPrefix(mountDest, spec.Root.Path) { // refuses mount destinations that escape from rootfs - return fmt.Errorf("security violation: resolved mount destination path %s escapes from container root %s", mountDest, spec.Root.Path) + return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, spec.Root.Path) } ms.Destination = mountDest err = createMountDestination(spec, &ms) if err != nil { - return errors.Wrapf(err, "failed to create mount destination %s", ms.Destination) + return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) } mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, strings.Join(ms.Options, ",")) @@ -69,38 +68,32 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { info, err := os.Stat(ms.Source) if err != nil && ms.Type == "bind" { // check if mountpoint is optional ? - return errors.Wrapf(err, "failed to access source %s for bind mount", ms.Source) + return fmt.Errorf("failed to access source %s for bind mount: %w", ms.Source, err) } if err == nil && !info.IsDir() { ms.Options = append(ms.Options, "create=file") // source exists and is not a directory // create a target file that can be used as target for a bind mount - err := os.MkdirAll(filepath.Dir(ms.Destination), 0750) - log.Debug().Err(err).Str("file", ms.Destination).Msg("create parent directory for file bind mount") - if err != nil { - return errors.Wrap(err, "failed to create mount destination dir") + if err := os.MkdirAll(filepath.Dir(ms.Destination), 0750); err != nil { + return fmt.Errorf("failed to create mount destination dir: %w", err) } f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0440) - log.Debug().Err(err).Str("file", ms.Destination).Msg("create file bind mount destination") if err != nil { - return errors.Wrap(err, "failed to create file mountpoint") + return fmt.Errorf("failed to create file mountpoint: %w", err) } return f.Close() } ms.Options = append(ms.Options, "create=dir") // FIXME exclude all directories that are below other mounts // only directories / files on the readonly rootfs must be created - err = os.MkdirAll(ms.Destination, 0750) - log.Debug().Err(err).Str("file", ms.Destination).Msg("create mount destination directory") - if err != nil { - return errors.Wrap(err, "failed to create mount destination") + if err := os.MkdirAll(ms.Destination, 0750); err != nil { + return fmt.Errorf("failed to create mount target dir: %w", err) } return nil } func resolvePathRelative(rootfs string, currentPath string, subPath string) (string, error) { - log.Trace().Str("file", currentPath).Str("sub", subPath).Msg("resolve path relative") p := filepath.Join(currentPath, subPath) stat, err := os.Lstat(p) @@ -110,7 +103,6 @@ func resolvePathRelative(rootfs string, currentPath string, subPath string) (str } if stat.Mode()&os.ModeSymlink == 0 { - log.Trace().Str("file", p).Msg("is not a symlink") return p, nil } // resolve symlink @@ -120,8 +112,6 @@ func resolvePathRelative(rootfs string, currentPath string, subPath string) (str return p, err } - log.Trace().Str("link", p).Str("dst", linkDst).Msg("symlink detected") - // The destination of an absolute link must be prefixed with the rootfs if filepath.IsAbs(linkDst) { if filepath.HasPrefix(linkDst, rootfs) { @@ -161,7 +151,6 @@ func resolveMountDestination(rootfs string, dst string) (dstPath string, err err // start path resolution at rootfs for i, entry := range entries { currentPath, err = resolvePathRelative(rootfs, currentPath, entry) - log.Trace().Err(err).Str("file", currentPath).Msg("path resolved") if err != nil { // The already resolved path is concatenated with the remaining path, // if resolution of path fails at some point. diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index e1bbf71a..18577518 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -1,11 +1,12 @@ package lxcontainer import ( - "github.com/stretchr/testify/require" "io/ioutil" "os" "path/filepath" "testing" + + "github.com/stretchr/testify/require" ) func TestResolveMountDestination_absolute(t *testing.T) { diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index e1bdc1a8..83f74547 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -6,8 +6,9 @@ import ( "runtime" "strings" - "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" + + "github.com/opencontainers/runtime-spec/specs-go" ) type namespace struct { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index c5da8703..a5fb6ced 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -3,17 +3,16 @@ package lxcontainer import ( "context" "fmt" - "github.com/pkg/errors" - "golang.org/x/sys/unix" "io/ioutil" "os" - "os/exec" "path/filepath" "runtime" "strconv" "strings" "time" + "golang.org/x/sys/unix" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "gopkg.in/lxc/go-lxc.v2" @@ -43,8 +42,8 @@ const ( StateStopped ContainerState = "stopped" ) -var errContainerNotExist = errors.New("container does not exist") -var errContainerExist = errors.New("container already exists") +var errContainerNotExist = fmt.Errorf("container does not exist") +var errContainerExist = fmt.Errorf("container already exists") var version string @@ -56,8 +55,6 @@ type Runtime struct { Container *lxc.Container ContainerInfo - Command string - // [ global settings ] LogFile *os.File LogFilePath string @@ -66,18 +63,9 @@ type Runtime struct { SystemdCgroup bool MonitorCgroup string - StartCommand string - InitCommand string - ContainerHook string - RuntimeHook string - RuntimeHookTimeout time.Duration - RuntimeHookRunAlways bool - - // create flags - ConsoleSocketTimeout time.Duration - - // start flags - StartTimeout time.Duration + StartCommand string + InitCommand string + ContainerHook string Log zerolog.Logger } @@ -90,7 +78,7 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { } if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { - return errors.Wrap(err, "failed to create container dir") + return fmt.Errorf("failed to create container dir: %w", err) } // An empty tmpfile is created to ensure that createContainer can only succeed once. @@ -101,7 +89,7 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { return err } if err := f.Close(); err != nil { - return errors.Wrap(err, "failed to close empty config file") + return fmt.Errorf("failed to close empty config file: %w", err) } if spec.Linux.CgroupsPath == "" { @@ -115,7 +103,7 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { c.MonitorCgroupDir = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") - if err := enableCgroupControllers(filepath.Dir(c.CgroupDir)); err != nil { + if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { return err } @@ -146,18 +134,18 @@ func (c *Runtime) loadContainer() error { return errContainerNotExist } if err != nil { - return errors.Wrap(err, "failed to access config file") + return fmt.Errorf("failed to access config file: %w", err) } container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { - return errors.Wrap(err, "failed to create new lxc container") + return fmt.Errorf("failed to create new lxc container: %w", err) } c.Container = container err = container.LoadConfigFile(c.ConfigFilePath()) if err != nil { - return errors.Wrap(err, "failed to load config file") + return fmt.Errorf("failed to load config file: %w", err) } return c.setContainerLogLevel() @@ -172,7 +160,7 @@ func (c *Runtime) configureCgroupPath() error { return err } - if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if c.supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { return err } @@ -206,7 +194,7 @@ func (c *Runtime) configureCgroupPath() error { func (c Runtime) Release() error { if c.Container != nil { if err := c.Container.Release(); err != nil { - log.Error().Err(err).Msg("failed to release container") + c.Log.Error().Err(err).Msg("failed to release container") } } if c.LogFile != nil { @@ -219,12 +207,12 @@ func (c *Runtime) ConfigureLogging(cmdName string) error { logDir := filepath.Dir(c.LogFilePath) err := os.MkdirAll(logDir, 0750) if err != nil { - return errors.Wrapf(err, "failed to create log file directory %s", logDir) + return fmt.Errorf("failed to create log file directory %s: %w", logDir, err) } c.LogFile, err = os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { - return errors.Wrapf(err, "failed to open log file %s", c.LogFilePath) + return fmt.Errorf("failed to open log file %s: %w", c.LogFilePath, err) } zerolog.LevelFieldName = "l" @@ -246,13 +234,13 @@ func (c *Runtime) ConfigureLogging(cmdName string) error { // NOTE Unfortunately it's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered // see https://github.com/rs/zerolog/issues/109 - log = zerolog.New(c.LogFile).With().Timestamp().Caller(). + c.Log = zerolog.New(c.LogFile).With().Timestamp().Caller(). Str("cmd", cmdName).Str("cid", c.ContainerID).Logger() level, err := zerolog.ParseLevel(strings.ToLower(c.LogLevel)) if err != nil { level = zerolog.InfoLevel - log.Warn().Err(err).Str("val", c.LogLevel).Stringer("default", level). + c.Log.Warn().Err(err).Str("val", c.LogLevel).Stringer("default", level). Msg("failed to parse log-level - fallback to default") } zerolog.SetGlobalLevel(level) @@ -266,10 +254,10 @@ func (c *Runtime) setContainerLogLevel() error { // The log level for a running container is set, and may change, per runtime call. err := c.Container.SetLogLevel(c.parseContainerLogLevel()) if err != nil { - return errors.Wrap(err, "failed to set container loglevel") + return fmt.Errorf("failed to set container loglevel: %w", err) } if err := c.Container.SetLogFile(c.LogFilePath); err != nil { - return errors.Wrap(err, "failed to set container log file") + return fmt.Errorf("failed to set container log file: %w", err) } return nil } @@ -295,83 +283,56 @@ func (c *Runtime) parseContainerLogLevel() lxc.LogLevel { case "fatal": return lxc.FATAL default: - log.Warn().Str("val", c.ContainerLogLevel). + c.Log.Warn().Str("val", c.ContainerLogLevel). Stringer("default", lxc.WARN). Msg("failed to parse container-log-level - fallback to default") return lxc.WARN } } -// executeRuntimeHook executes the runtime hook executable if defined. -// Execution errors are logged at log level error. -func (c *Runtime) executeRuntimeHook(runtimeError error) { - if c.RuntimeHook == "" { - return - } - env := []string{ - "CONTAINER_ID=" + c.ContainerID, - "LXC_CONFIG=" + c.ConfigFilePath(), - "RUNTIME_CMD=" + c.Command, - "RUNTIME_PATH=" + c.RuntimePath(), - "BUNDLE_PATH=" + c.BundlePath, - "SPEC_PATH=" + c.SpecPath(), - "LOG_FILE=" + c.LogFilePath, - } - - if runtimeError != nil { - env = append(env, "RUNTIME_ERROR="+runtimeError.Error()) - } - - log.Debug().Str("file", c.RuntimeHook).Msg("execute runtime hook") - // TODO drop privileges, capabilities ? - ctx, cancel := context.WithTimeout(context.Background(), c.RuntimeHookTimeout) - defer cancel() - // #nosec - cmd := exec.CommandContext(ctx, c.RuntimeHook) - cmd.Env = env - cmd.Dir = c.RuntimePath() - if err := cmd.Run(); err != nil { - log.Error().Err(err).Str("file", c.RuntimeHook). - Bool("timeout-expired", ctx.Err() == context.DeadlineExceeded).Msg("runtime hook failed") - } -} - func (c *Runtime) isContainerStopped() bool { return c.Container.State() == lxc.STOPPED } -func (c *Runtime) waitCreated(timeout time.Duration) error { - if !c.Container.Wait(lxc.RUNNING, timeout) { - return fmt.Errorf("timeout starting init cmd") - } - - initState, err := c.getContainerInitState() - if err != nil { - return err - } - if initState != StateCreated { - return fmt.Errorf("unexpected init state %q", initState) +func (c *Runtime) waitCreated(ctx context.Context) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + if !c.Container.Wait(lxc.RUNNING, time.Second) { + continue + } + initState, err := c.getContainerInitState() + if err != nil { + return err + } + if initState != StateCreated { + return fmt.Errorf("unexpected init state %q", initState) + } + } } - return nil } -func (c *Runtime) waitRunning(timeout time.Duration) error { - deadline := time.Now().Add(timeout) - for time.Now().Before(deadline) { - initState, err := c.getContainerInitState() - if err != nil { - return err - } - if initState == StateRunning { - return nil - } - if initState == StateCreated { +func (c *Runtime) waitRunning(ctx context.Context) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + initState, err := c.getContainerInitState() + if err != nil { + return err + } + if initState == StateRunning { + return nil + } + if initState != StateCreated { + return fmt.Errorf("unexpected init state %q", initState) + } time.Sleep(time.Millisecond * 10) - continue } - return fmt.Errorf("unexpected init state %q", initState) } - return fmt.Errorf("timeout") } // getContainerInitState returns the runtime state of the container. @@ -416,49 +377,7 @@ func (c *Runtime) getContainerInitState() (ContainerState, error) { return StateRunning, nil } -func enableCgroupControllers(cg string) error { - //slice := cg.ScopePath() - // #nosec - cgPath := filepath.Join("/sys/fs/cgroup", cg) - if err := os.MkdirAll(cgPath, 755); err != nil { - return err - } - /* - // enable all available controllers in the scope - data, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") - if err != nil { - return errors.Wrap(err, "failed to read cgroup.controllers") - } - controllers := strings.Split(strings.TrimSpace(string(data)), " ") - - var b strings.Builder - for i, c := range controllers { - if i > 0 { - b.WriteByte(' ') - } - b.WriteByte('+') - b.WriteString(c) - } - b.WriteString("\n") - - s := b.String() - */ - s := "+cpuset +cpu +io +memory +hugetlb +pids +rdma\n" - - base := "/sys/fs/cgroup" - for _, elem := range strings.Split(cg, "/") { - base = filepath.Join(base, elem) - c := filepath.Join(base, "cgroup.subtree_control") - err := ioutil.WriteFile(c, []byte(s), 0) - if err != nil { - return errors.Wrapf(err, "failed to enable cgroup controllers in %s", base) - } - log.Info().Str("file", base).Str("controllers", strings.TrimSpace(s)).Msg("cgroup activated") - } - return nil -} - -func (c *Runtime) killContainer(signum unix.Signal) error { +func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { if signum == unix.SIGKILL || signum == unix.SIGTERM { if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { return err @@ -466,18 +385,22 @@ func (c *Runtime) killContainer(signum unix.Signal) error { if err := c.Container.Stop(); err != nil { return err } - if !c.Container.Wait(lxc.STOPPED, time.Second*10) { - log.Warn().Msg("failed to stop lxc container") + timeout := time.Second + if deadline, ok := ctx.Deadline(); ok { + timeout = deadline.Sub(time.Now()) + } + if !c.Container.Wait(lxc.STOPPED, timeout) { + c.Log.Warn().Msg("failed to stop lxc container") } // draining the cgroup is required to catch processes that escaped from the // 'kill' e.g a bash for loop that spawns a new child immediately. start := time.Now() - err := drainCgroup(c.CgroupDir, signum, time.Second*10) + err := drainCgroup(ctx, c.CgroupDir, signum) if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") } else { - log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") + c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") } return err } @@ -485,14 +408,14 @@ func (c *Runtime) killContainer(signum unix.Signal) error { // send non-terminating signals to monitor process pid, err := c.Pid() if err != nil && !os.IsNotExist(err) { - return errors.Wrapf(err, "failed to load pidfile") + return fmt.Errorf("failed to load pidfile: %w", err) } if pid > 1 { - log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") + c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") if err := unix.Kill(pid, 0); err == nil { err := unix.Kill(pid, signum) if err != unix.ESRCH { - return errors.Wrapf(err, "failed to send signal %d to container process %d", signum, pid) + return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) } } } @@ -506,13 +429,13 @@ func (c *Runtime) killContainer(signum unix.Signal) error { func (c *Runtime) destroy() error { if c.Container != nil { if err := c.Container.Destroy(); err != nil { - return errors.Wrap(err, "failed to destroy container") + return fmt.Errorf("failed to destroy container: %w", err) } } err := deleteCgroup(c.CgroupDir) if err != nil && !os.IsNotExist(err) { - log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") } return os.RemoveAll(c.RuntimePath()) @@ -526,7 +449,7 @@ func (c *Runtime) saveConfig() error { // createContainer creates the tmpfile tmpFile := c.RuntimePath(".config") if _, err := os.Stat(tmpFile); err != nil { - return errors.Wrap(err, "failed to stat config tmpfile") + return fmt.Errorf("failed to stat config tmpfile: %w", err) } // Don't overwrite an existing config. cfgFile := c.ConfigFilePath() @@ -535,16 +458,16 @@ func (c *Runtime) saveConfig() error { } err := c.Container.SaveConfigFile(tmpFile) if err != nil { - return errors.Wrapf(err, "failed to save config file to '%s'", tmpFile) + return fmt.Errorf("failed to save config file to %q: %w", tmpFile, err) } if err := os.Rename(tmpFile, cfgFile); err != nil { - return errors.Wrap(err, "failed to rename config file") + return fmt.Errorf("failed to rename config file: %w", err) } return nil } -func (c *Runtime) Start(timeout time.Duration) error { - log.Info().Msg("notify init to start container process") +func (c *Runtime) Start(ctx context.Context) error { + c.Log.Info().Msg("notify init to start container process") err := c.loadContainer() if err != nil { @@ -565,13 +488,14 @@ func (c *Runtime) Start(timeout time.Duration) error { }() select { + case <-ctx.Done(): + return fmt.Errorf("syncfifo timeout: %w", ctx.Err()) case err := <-done: - return err - case <-time.After(time.Second * 5): - return fmt.Errorf("timeout reading from syncfifo") + if err != nil { + return err + } } - - return c.waitRunning(timeout) + return c.waitRunning(ctx) } func (c *Runtime) syncFifoPath() string { @@ -582,7 +506,7 @@ func (c *Runtime) readFifo() error { // #nosec f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) if err != nil { - return errors.Wrap(err, "failed to open sync fifo") + return fmt.Errorf("failed to open sync fifo: %w", err) } // can not set deadline on fifo // #nosec @@ -591,15 +515,15 @@ func (c *Runtime) readFifo() error { data := make([]byte, len(c.ContainerID)) _, err = f.Read(data) if err != nil { - return errors.Wrap(err, "problem reading from fifo") + return fmt.Errorf("problem reading from fifo: %w", err) } if c.ContainerID != string(data) { - return errors.Errorf("bad fifo content: %s", string(data)) + return fmt.Errorf("bad fifo content: %s", string(data)) } return nil } -func (c *Runtime) Delete(force bool) error { +func (c *Runtime) Delete(ctx context.Context, force bool) error { err := c.loadContainer() if err == errContainerNotExist { return nil @@ -608,14 +532,14 @@ func (c *Runtime) Delete(force bool) error { return err } - log.Info().Bool("force", force).Msg("delete container") + c.Log.Info().Bool("force", force).Msg("delete container") if !c.isContainerStopped() { if !force { return fmt.Errorf("container is not not stopped (current state %s)", c.Container.State()) } - if err := c.killContainer(unix.SIGKILL); err != nil { - return errors.Wrap(err, "failed to kill container") + if err := c.killContainer(ctx, unix.SIGKILL); err != nil { + return fmt.Errorf("failed to kill container: %w", err) } } return c.destroy() @@ -629,7 +553,7 @@ func (c *Runtime) State() (*specs.State, error) { pid, err := c.Pid() if err != nil { - return nil, errors.Wrapf(err, "failed to load pidfile") + return nil, fmt.Errorf("failed to load pidfile: %w", err) } state := &specs.State{ @@ -646,11 +570,11 @@ func (c *Runtime) State() (*specs.State, error) { return nil, err } - log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") + c.Log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") return state, nil } -func (c *Runtime) Kill(signum unix.Signal) error { +func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { err := c.loadContainer() if err != nil { return err @@ -663,16 +587,21 @@ func (c *Runtime) Kill(signum unix.Signal) error { if !(state == StateCreated || state == StateRunning) { return fmt.Errorf("can only kill container in state Created|Running but was %q", state) } - return c.killContainer(signum) + return c.killContainer(ctx, signum) } func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { + err = c.loadContainer() + if err != nil { + return 0, err + } + opts, err := attachOptions(proc, c.Namespaces) if err != nil { return 0, err } - log.Info().Strs("args", args). + c.Log.Info().Strs("args", args). Int("uid", opts.UID).Int("gid", opts.GID). Ints("groups", opts.Groups).Msg("execute cmd") @@ -680,6 +609,10 @@ func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err } func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { + err = c.loadContainer() + if err != nil { + return 0, err + } opts, err := attachOptions(proc, c.Namespaces) if err != nil { return 0, err @@ -705,18 +638,16 @@ func (c *Runtime) getConfigItem(key string) string { func (c *Runtime) setConfigItem(key, value string) error { err := c.Container.SetConfigItem(key, value) if err != nil { - return errors.Wrapf(err, "failed to set config item '%s=%s'", key, value) + return fmt.Errorf("failed to set config item '%s=%s': %w", key, value, err) } - log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") + c.Log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") return nil } -// -- LXC helper functions - -func supportsConfigItem(keys ...string) bool { +func (c *Runtime) supportsConfigItem(keys ...string) bool { for _, key := range keys { if !lxc.IsSupportedConfigItem(key) { - log.Info().Str("lxc.config", key).Msg("unsupported config item") + c.Log.Info().Str("lxc.config", key).Msg("unsupported config item") return false } } diff --git a/lxcontainer/seccomp.go b/lxcontainer/seccomp.go index 938114ba..53e76edb 100644 --- a/lxcontainer/seccomp.go +++ b/lxcontainer/seccomp.go @@ -9,7 +9,6 @@ import ( "golang.org/x/sys/unix" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) var seccompAction = map[specs.LinuxSeccompAction]string{ @@ -46,9 +45,8 @@ func writeSeccompProfile(profilePath string, seccomp *specs.LinuxSeccomp) error platformArchs, err := seccompArchs(seccomp) if err != nil { - return errors.Wrap(err, "Failed to detect platform architecture") + return fmt.Errorf("failed to detect platform architecture: %w", err) } - log.Debug().Str("action", action).Strs("archs", platformArchs).Msg("create seccomp profile") for _, arch := range platformArchs { fmt.Fprintf(w, "[%s]\n", arch) for _, sc := range seccomp.Syscalls { @@ -75,7 +73,6 @@ func defaultAction(seccomp *specs.LinuxSeccomp) (string, error) { case specs.ActAllow: return "allow", nil case specs.ActTrace, specs.ActLog: // Not (yet) supported by lxc - log.Warn().Str("action", string(seccomp.DefaultAction)).Msg("unsupported seccomp default action") fallthrough //case specs.ActKillProcess: fallthrough // specs > 1.0.2 default: diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 2e9c8bd6..66428a78 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -6,14 +6,12 @@ import ( "fmt" "os" "path/filepath" - "strconv" - "strings" "golang.org/x/sys/unix" ) // createPidFile atomically creates a pid file for the given pid at the given path -func createPidFile(path string, pid int) error { +func CreatePidFile(path string, pid int) error { tmpDir := filepath.Dir(path) tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) @@ -71,23 +69,6 @@ func isFilesystem(dir string, fsName string) error { return nil } -func parseSignal(sig string) unix.Signal { - if sig == "" { - return unix.SIGTERM - } - // handle numerical signal value - if num, err := strconv.Atoi(sig); err == nil { - return unix.Signal(num) - } - - // gracefully handle all string variants e.g 'sigkill|SIGKILL|kill|KILL' - s := strings.ToUpper(sig) - if !strings.HasPrefix(s, "SIG") { - s = "SIG" + s - } - return unix.SignalNum(s) -} - func decodeFileJSON(obj interface{}, src string) error { // #nosec f, err := os.Open(src) From 9b64531899b28b3412d0feb6276baf0d4c7dcf20 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 15:03:35 +0100 Subject: [PATCH 104/373] refactor: Move version to cli. Signed-off-by: Ruben Jenster --- cmd/cli.go | 5 ++++- lxcontainer/runtime.go | 7 ------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index a3f442be..f4baad58 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -29,11 +29,14 @@ var clxc struct { DeleteTimeout time.Duration } +var version string + func main() { app := cli.NewApp() app.Name = "crio-lxc" app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" - app.Version = lxcontainer.Version() + app.Version = version + // Disable the default ExitErrHandler. // It will call os.Exit if a command returns an error that implements // the cli.ExitCoder interface. E.g an unwrapped error from os.Exec. diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index a5fb6ced..5a27e0d7 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -6,7 +6,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "strconv" "strings" "time" @@ -45,12 +44,6 @@ const ( var errContainerNotExist = fmt.Errorf("container does not exist") var errContainerExist = fmt.Errorf("container already exists") -var version string - -func Version() string { - return fmt.Sprintf("%s (%s) (lxc:%s)", version, runtime.Version(), lxc.Version()) -} - type Runtime struct { Container *lxc.Container ContainerInfo From 687ab95e6e2abc0c88c12fd19e7a94ed869c68b4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 15:04:37 +0100 Subject: [PATCH 105/373] Do not include path in wrapped os.Open.. errors. Signed-off-by: Ruben Jenster --- lxcontainer/init.go | 2 +- lxcontainer/mount.go | 2 +- lxcontainer/namespaces.go | 4 ++-- lxcontainer/runtime.go | 4 ++-- lxcontainer/utils.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lxcontainer/init.go b/lxcontainer/init.go index ba38b2c8..ec591f99 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -99,7 +99,7 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err // #nosec f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) if err != nil { - return fmt.Errorf("failed to create init list %s: %w", dst, err) + return err } for _, arg := range entries { diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index d8b35e32..a41007dd 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -68,7 +68,7 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { info, err := os.Stat(ms.Source) if err != nil && ms.Type == "bind" { // check if mountpoint is optional ? - return fmt.Errorf("failed to access source %s for bind mount: %w", ms.Source, err) + return fmt.Errorf("failed to access source for bind mount: %w", err) } if err == nil && !info.IsDir() { diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index 83f74547..afb35654 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -100,14 +100,14 @@ func setHostname(nsPath string, hostname string) error { f, err := os.Open(nsPath) if err != nil { - return fmt.Errorf("failed to open uts namespace %s: %w", nsPath, err) + return fmt.Errorf("failed to open container uts namespace: %w", nsPath, err) } // #nosec defer f.Close() self, err := os.Open("/proc/self/ns/uts") if err != nil { - return fmt.Errorf("failed to open /proc/self/ns/uts: %w", err) + return fmt.Errorf("failed to open uts namespace : %w", err) } // #nosec defer func() { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 5a27e0d7..37c3a2fa 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -205,7 +205,7 @@ func (c *Runtime) ConfigureLogging(cmdName string) error { c.LogFile, err = os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { - return fmt.Errorf("failed to open log file %s: %w", c.LogFilePath, err) + return err } zerolog.LevelFieldName = "l" @@ -499,7 +499,7 @@ func (c *Runtime) readFifo() error { // #nosec f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) if err != nil { - return fmt.Errorf("failed to open sync fifo: %w", err) + return err } // can not set deadline on fifo // #nosec diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 66428a78..61eb5ca0 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -73,7 +73,7 @@ func decodeFileJSON(obj interface{}, src string) error { // #nosec f, err := os.Open(src) if err != nil { - return fmt.Errorf("failed to open %s: %w", src, err) + return err } // #nosec err = json.NewDecoder(f).Decode(obj) @@ -91,7 +91,7 @@ func decodeFileJSON(obj interface{}, src string) error { func encodeFileJSON(dst string, obj interface{}, flags int, mode uint32) error { f, err := os.OpenFile(dst, flags, os.FileMode(mode)) if err != nil { - return fmt.Errorf("failed to open %s: %w", dst, err) + return err } enc := json.NewEncoder(f) //enc.SetIndent("", " ") From d7c4567852c75cea2ed81058dc187908228047dc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 15:41:36 +0100 Subject: [PATCH 106/373] Fix container release and logging. Signed-off-by: Ruben Jenster --- cmd/cli.go | 54 ++++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index f4baad58..f6e39923 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -166,6 +166,18 @@ func main() { } } + app.CommandNotFound = func(ctx *cli.Context, cmd string) { + fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) + } + // Disable the default error messages for cmdline errors. + // By default the app/cmd help is printed to stdout, which produces garbage in cri-o log output. + // Instead the cmdline is printed to stderr to identify cmdline interface errors. + errUsage := func(context *cli.Context, err error, isSubcommand bool) error { + fmt.Fprintf(os.Stderr, "usage error %s: %s\n", err, os.Args) + return err + } + app.OnUsageError = errUsage + app.Before = func(ctx *cli.Context) error { clxc.Command = ctx.Args().Get(0) return nil @@ -177,49 +189,35 @@ func main() { return fmt.Errorf("missing container ID") } clxc.ContainerID = containerID - return clxc.ConfigureLogging(ctx.Command.Name) } - // Disable the default error messages for cmdline errors. - // By default the app/cmd help is printed to stdout, which produces garbage in cri-o log output. - // Instead the cmdline is printed to stderr to identify cmdline interface errors. - errUsage := func(context *cli.Context, err error, isSubcommand bool) error { - fmt.Fprintf(os.Stderr, "usage error %s: %s\n", err, os.Args) - return err - } - app.OnUsageError = errUsage - for _, cmd := range app.Commands { cmd.Before = setupCmd cmd.OnUsageError = errUsage } - app.CommandNotFound = func(ctx *cli.Context, cmd string) { - fmt.Fprintf(os.Stderr, "undefined subcommand %q cmdline%s\n", cmd, os.Args) - } - err = app.Run(os.Args) - if err := clxc.Release(); err != nil { - clxc.Log.Error().Err(err).Msg("failed to release container") - } - cmdDuration := time.Since(startTime) - if err == nil { - clxc.Log.Debug().Dur("duration", cmdDuration).Msg("cmd completed") - return + if err != nil { + clxc.Log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") + clxc.Release() + // exit with exit status of executed command + if err, yes := err.(execError); yes { + os.Exit(err.ExitStatus()) + } + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) + os.Exit(1) } - clxc.Log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") - // exit with exit status of executed command - if err, yes := err.(execError); yes { - os.Exit(err.ExitStatus()) + clxc.Log.Debug().Dur("duration", cmdDuration).Msg("cmd completed") + if clxc.Release(); err != nil { + println(err.Error()) + os.Exit(1) } - // write diagnostics message to stderr for crio/kubelet - println(err.Error()) - os.Exit(1) } var createCmd = cli.Command{ From 5ace4c42d7d2f22e857bce0b9da627d59746c48c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 17:50:49 +0100 Subject: [PATCH 107/373] Add caller information to lxcontainer OCI API methods. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 24 ++++++++------ lxcontainer/runtime.go | 74 ++++++++++++++++++++++++------------------ lxcontainer/utils.go | 10 ++++++ 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index abfa3b4f..cfa85677 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -19,34 +19,38 @@ import ( func (clxc *Runtime) Create(ctx context.Context) error { err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { - return err + return errorf("access check failed: %w", err) } if err := isFilesystem("/proc", "proc"); err != nil { - return err + return errorf("procfs not mounted on /proc: %w", err) } - if err := isFilesystem("/sys/fs/cgroup", "cgroup2"); err != nil { - return err + if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { + return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) } // TODO test this version if !lxc.VersionAtLeast(4, 0, 5) { - return fmt.Errorf("LXC runtime version >= 4.0.5 required, but was %s", lxc.Version()) + return errorf("liblxc runtime version is %s, but >= 4.0.5 is required", lxc.Version()) } spec, err := clxc.ReadSpec() if err != nil { - return err + return errorf("failed to load container spec from bundle: %w", err) } err = clxc.createContainer(spec) if err != nil { - return fmt.Errorf("failed to create container: %w", err) + return errorf("failed to create container: %w", err) } if err := configureContainer(clxc, spec); err != nil { - return fmt.Errorf("failed to configure container: %w", err) + return errorf("failed to configure container: %w", err) } - return clxc.runStartCmd(ctx, spec) + + if err := clxc.runStartCmd(ctx, spec); err != nil { + return errorf("failed to run container process: %w", err) + } + return nil } func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { @@ -77,7 +81,7 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err } if err != nil { - return fmt.Errorf("failed to execute container process: %w", err) + return err } if err := clxc.waitCreated(ctx); err != nil { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 37c3a2fa..46920b7b 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -119,23 +119,17 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { // It returns an error if the config file does not exist. func (c *Runtime) loadContainer() error { if err := c.ContainerInfo.Load(); err != nil { - return err + return fmt.Errorf("failed to load container config: %w", err) } - _, err := os.Stat(c.ConfigFilePath()) - if os.IsNotExist(err) { - return errContainerNotExist - } - if err != nil { - return fmt.Errorf("failed to access config file: %w", err) + if _, err := os.Stat(c.ConfigFilePath()); err != nil { + return fmt.Errorf("failed to load lxc config file: %w", err) } - container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) if err != nil { return fmt.Errorf("failed to create new lxc container: %w", err) } c.Container = container - err = container.LoadConfigFile(c.ConfigFilePath()) if err != nil { return fmt.Errorf("failed to load config file: %w", err) @@ -464,12 +458,12 @@ func (c *Runtime) Start(ctx context.Context) error { err := c.loadContainer() if err != nil { - return err + return errorf("failed to load container: %w", err) } state, err := c.getContainerState() if err != nil { - return err + return errorf("failed to get container state: %w", err) } if state != StateCreated { return fmt.Errorf("invalid container state. expected %q, but was %q", StateCreated, state) @@ -482,13 +476,16 @@ func (c *Runtime) Start(ctx context.Context) error { select { case <-ctx.Done(): - return fmt.Errorf("syncfifo timeout: %w", ctx.Err()) + return errorf("syncfifo timeout: %w", ctx.Err()) case err := <-done: if err != nil { - return err + return errorf("failed to read from syncfifo: %w", err) } } - return c.waitRunning(ctx) + if err := c.waitRunning(ctx); err != nil { + return errorf("container is not running: %w", err) + } + return nil } func (c *Runtime) syncFifoPath() string { @@ -522,31 +519,34 @@ func (c *Runtime) Delete(ctx context.Context, force bool) error { return nil } if err != nil { - return err + return errorf("failed to load container: %w", err) } c.Log.Info().Bool("force", force).Msg("delete container") if !c.isContainerStopped() { if !force { - return fmt.Errorf("container is not not stopped (current state %s)", c.Container.State()) + return errorf("container is not not stopped (current state %s)", c.Container.State()) } if err := c.killContainer(ctx, unix.SIGKILL); err != nil { - return fmt.Errorf("failed to kill container: %w", err) + return errorf("failed to kill container: %w", err) } } - return c.destroy() + if err := c.destroy(); err != nil { + return errorf("failed to destroy container: %w", err) + } + return nil } func (c *Runtime) State() (*specs.State, error) { err := c.loadContainer() if err != nil { - return nil, err + return nil, errorf("failed to load container: %w", err) } pid, err := c.Pid() if err != nil { - return nil, fmt.Errorf("failed to load pidfile: %w", err) + return nil, errorf("failed to load pidfile: %w", err) } state := &specs.State{ @@ -560,7 +560,7 @@ func (c *Runtime) State() (*specs.State, error) { s, err := c.getContainerState() state.Status = string(s) if err != nil { - return nil, err + return nil, errorf("failed to get container state: %w", err) } c.Log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") @@ -570,47 +570,57 @@ func (c *Runtime) State() (*specs.State, error) { func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { err := c.loadContainer() if err != nil { - return err + return errorf("failed to load container: %w", err) } - state, err := c.getContainerState() if err != nil { - return err + return errorf("failed to get container state: %w", err) } if !(state == StateCreated || state == StateRunning) { - return fmt.Errorf("can only kill container in state Created|Running but was %q", state) + return errorf("can only kill container in state Created|Running but was %q", state) + } + if err := c.killContainer(ctx, signum); err != nil { + return errorf("failed to kill container: %w", err) } - return c.killContainer(ctx, signum) + return nil } func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { err = c.loadContainer() if err != nil { - return 0, err + return 0, errorf("failed to load container: %w", err) } opts, err := attachOptions(proc, c.Namespaces) if err != nil { - return 0, err + return 0, errorf("failed to create attach options: %w", err) } c.Log.Info().Strs("args", args). Int("uid", opts.UID).Int("gid", opts.GID). Ints("groups", opts.Groups).Msg("execute cmd") - return c.Container.RunCommandNoWait(args, opts) + pid, err = c.Container.RunCommandNoWait(args, opts) + if err != nil { + return pid, errorf("failed to run exec cmd detached: %w", err) + } + return pid, nil } func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { err = c.loadContainer() if err != nil { - return 0, err + return 0, errorf("failed to load container: %w", err) } opts, err := attachOptions(proc, c.Namespaces) if err != nil { - return 0, err + return 0, errorf("failed to create attach options: %w", err) + } + exitStatus, err = c.Container.RunCommandNoWait(args, opts) + if err != nil { + return exitStatus, errorf("failed to run exec cmd: %w", err) } - return c.Container.RunCommandStatus(args, opts) + return exitStatus, nil } // -- LXC helper functions that should be static diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 61eb5ca0..116d9005 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -6,6 +6,8 @@ import ( "fmt" "os" "path/filepath" + "runtime" + "strconv" "golang.org/x/sys/unix" ) @@ -110,3 +112,11 @@ func nullTerminatedString(data []byte) string { i := bytes.Index(data, []byte{0}) return string(data[:i]) } + +func errorf(sfmt string, args ...interface{}) error { + _, file, line, ok := runtime.Caller(1) + if ok { + return fmt.Errorf(filepath.Base(file)+":"+strconv.Itoa(line)+" "+sfmt, args...) + } + return fmt.Errorf(sfmt, args...) +} From 49ae7e643c828cd5a56ae48f3223cee1802a1c05 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 20:55:02 +0100 Subject: [PATCH 108/373] refactor: Fix regressions. Signed-off-by: Ruben Jenster --- cmd/cli.go | 69 +++++++++++++++++++++++++--------------- lxcontainer/container.go | 7 ++++ lxcontainer/create.go | 17 +++++++--- lxcontainer/runtime.go | 27 ++++++++-------- 4 files changed, 77 insertions(+), 43 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index f6e39923..bc6c3a27 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -3,6 +3,7 @@ package main import ( "context" "encoding/json" + "errors" "fmt" "os" "os/exec" @@ -20,8 +21,9 @@ var envFile = "/etc/default/crio-lxc" var clxc struct { lxcontainer.Runtime - Command string - CreateHook string + Command string + CreateHook string + CreateHookTimeout time.Duration CreateTimeout time.Duration StartTimeout time.Duration @@ -255,6 +257,13 @@ var createCmd = cli.Command{ EnvVars: []string{"CRIO_LXC_CREATE_HOOK"}, Destination: &clxc.CreateHook, }, + &cli.DurationFlag{ + Name: "hook-timeout", + Usage: "maximum duration for hook to complete", + EnvVars: []string{"CRIO_LXC_CREATE_HOOK_TIMEOUT"}, + Value: time.Second * 5, + Destination: &clxc.CreateHookTimeout, + }, }, } @@ -263,33 +272,36 @@ func doCreate(unused *cli.Context) error { defer cancel() err := clxc.Create(ctx) - if clxc.CreateHook != "" { - env := []string{ - "CONTAINER_ID=" + clxc.ContainerID, - "LXC_CONFIG=" + clxc.ConfigFilePath(), - "RUNTIME_CMD=" + clxc.Command, - "RUNTIME_PATH=" + clxc.RuntimePath(), - "BUNDLE_PATH=" + clxc.BundlePath, - "SPEC_PATH=" + clxc.SpecPath(), - "LOG_FILE=" + clxc.LogFilePath, - } - if err != nil { - env = append(env, "RUNTIME_ERROR="+err.Error()) - } - cmd := exec.CommandContext(ctx, clxc.CreateHook) - cmd.Env = env - - clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("execute create hook") - if err := cmd.Run(); err != nil { - clxc.Log.Error().Err(err).Str("file", clxc.CreateHook).Msg("failed to execute create hook") - } else { - clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("failed to execute runtime hook") - } + runCreateHook(err) } return err } +func runCreateHook(err error) { + env := []string{ + "CONTAINER_ID=" + clxc.ContainerID, + "LXC_CONFIG=" + clxc.ConfigFilePath(), + "RUNTIME_CMD=" + clxc.Command, + "RUNTIME_PATH=" + clxc.RuntimePath(), + "BUNDLE_PATH=" + clxc.BundlePath, + "SPEC_PATH=" + clxc.SpecPath(), + "LOG_FILE=" + clxc.LogFilePath, + } + if err != nil { + env = append(env, "RUNTIME_ERROR="+err.Error()) + } + ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateHookTimeout) + defer cancel() + cmd := exec.CommandContext(ctx, clxc.CreateHook) + cmd.Env = env + + clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("execute create hook") + if err := cmd.Run(); err != nil { + clxc.Log.Error().Err(err).Str("file", clxc.CreateHook).Msg("failed to execute create hook") + } +} + var startCmd = cli.Command{ Name: "start", Usage: "starts a container", @@ -301,7 +313,7 @@ starts Flags: []cli.Flag{ &cli.DurationFlag{ Name: "timeout", - Usage: "timeout for reading from syncfifo", + Usage: "start timeout", EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, Value: time.Second * 30, Destination: &clxc.StartTimeout, @@ -397,7 +409,12 @@ var deleteCmd = cli.Command{ func doDelete(ctx *cli.Context) error { c, cancel := context.WithTimeout(context.Background(), clxc.DeleteTimeout) defer cancel() - return clxc.Delete(c, ctx.Bool("force")) + err := clxc.Delete(c, ctx.Bool("force")) + if errors.Is(err, lxcontainer.ErrNotExist) { + clxc.Log.Warn().Msg("container does not exist") + return nil + } + return err } var execCmd = cli.Command{ diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 03f12b15..e5e1fa41 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -46,6 +46,13 @@ func (c ContainerInfo) RuntimePath(subPath ...string) string { return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) } +func (c ContainerInfo) runtimePathExists() bool { + if _, err := os.Stat(c.RuntimePath()); err == nil { + return true + } + return false +} + func (c ContainerInfo) ConfigFilePath() string { return c.RuntimePath("config") } diff --git a/lxcontainer/create.go b/lxcontainer/create.go index cfa85677..13786b53 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -17,6 +17,10 @@ import ( ) func (clxc *Runtime) Create(ctx context.Context) error { + if clxc.runtimePathExists() { + return ErrExist + } + err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) if err != nil { return errorf("access check failed: %w", err) @@ -55,7 +59,7 @@ func (clxc *Runtime) Create(ctx context.Context) error { func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { // #nosec - cmd := exec.CommandContext(ctx, clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) + cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) cmd.Env = []string{} cmd.Dir = clxc.RuntimePath() @@ -74,16 +78,18 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err return err } + clxc.Log.Debug().Msg("starting lxc monitor process") if clxc.ConsoleSocket != "" { err = runStartCmdConsole(ctx, cmd, clxc.ConsoleSocket) } else { - err = cmd.Run() + err = cmd.Start() } if err != nil { return err } + clxc.Log.Debug().Msg("waiting for init") if err := clxc.waitCreated(ctx); err != nil { return err } @@ -111,6 +117,10 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { return err } + if err := configureInit(clxc, spec); err != nil { + return err + } + if err := configureMounts(clxc, spec); err != nil { return err } @@ -207,8 +217,7 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { return err } } - - return configureInit(clxc, spec) + return nil } func configureRootfs(clxc *Runtime, spec *specs.Spec) error { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 46920b7b..449d5e8d 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -41,8 +41,8 @@ const ( StateStopped ContainerState = "stopped" ) -var errContainerNotExist = fmt.Errorf("container does not exist") -var errContainerExist = fmt.Errorf("container already exists") +var ErrNotExist = fmt.Errorf("container does not exist") +var ErrExist = fmt.Errorf("container already exists") type Runtime struct { Container *lxc.Container @@ -66,8 +66,8 @@ type Runtime struct { // createContainer creates a new container. // It must only be called once during the lifecycle of a container. func (c *Runtime) createContainer(spec *specs.Spec) error { - if _, err := os.Stat(c.ConfigFilePath()); err == nil { - return errContainerExist + if c.runtimePathExists() { + return ErrExist } if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { @@ -118,6 +118,10 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { // loadContainer checks for the existence of the lxc config file. // It returns an error if the config file does not exist. func (c *Runtime) loadContainer() error { + if !c.runtimePathExists() { + return ErrNotExist + } + if err := c.ContainerInfo.Load(); err != nil { return fmt.Errorf("failed to load container config: %w", err) } @@ -287,16 +291,18 @@ func (c *Runtime) waitCreated(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() default: - if !c.Container.Wait(lxc.RUNNING, time.Second) { + c.Log.Debug().Msg("wait lxc.RUNNING") + if !c.Container.Wait(lxc.RUNNING, time.Second*2) { continue } initState, err := c.getContainerInitState() if err != nil { return err } - if initState != StateCreated { - return fmt.Errorf("unexpected init state %q", initState) + if initState == StateCreated { + return nil } + return fmt.Errorf("unexpected init state %q", initState) } } } @@ -515,9 +521,6 @@ func (c *Runtime) readFifo() error { func (c *Runtime) Delete(ctx context.Context, force bool) error { err := c.loadContainer() - if err == errContainerNotExist { - return nil - } if err != nil { return errorf("failed to load container: %w", err) } @@ -616,15 +619,13 @@ func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err if err != nil { return 0, errorf("failed to create attach options: %w", err) } - exitStatus, err = c.Container.RunCommandNoWait(args, opts) + exitStatus, err = c.Container.RunCommandStatus(args, opts) if err != nil { return exitStatus, errorf("failed to run exec cmd: %w", err) } return exitStatus, nil } -// -- LXC helper functions that should be static - func (c *Runtime) getConfigItem(key string) string { vals := c.Container.ConfigItem(key) if len(vals) > 0 { From ccd3a0ad323221f0d42a10ce2e0cbc4e621fbfef Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 23:00:30 +0100 Subject: [PATCH 109/373] state: try to handle transient container states. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 59 +++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 449d5e8d..e54f907e 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -291,8 +291,10 @@ func (c *Runtime) waitCreated(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() default: - c.Log.Debug().Msg("wait lxc.RUNNING") - if !c.Container.Wait(lxc.RUNNING, time.Second*2) { + state := c.Container.State() + if !(state == lxc.RUNNING) { + c.Log.Debug().Stringer("state", state).Msg("wait for state lxc.RUNNING") + time.Sleep(time.Millisecond * 100) continue } initState, err := c.getContainerInitState() @@ -307,33 +309,38 @@ func (c *Runtime) waitCreated(ctx context.Context) error { } } -func (c *Runtime) waitRunning(ctx context.Context) error { +func (c *Runtime) waitStarted(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: - initState, err := c.getContainerInitState() - if err != nil { - return err + state := c.Container.State() + if !(state == lxc.RUNNING) { + return fmt.Errorf("container state must be lxc.RUNNING (was %q)", state) } + initState, _ := c.getContainerInitState() if initState == StateRunning { return nil } - if initState != StateCreated { - return fmt.Errorf("unexpected init state %q", initState) - } time.Sleep(time.Millisecond * 10) } } } -// getContainerInitState returns the runtime state of the container. -// It is used to determine whether the container state is 'created' or 'running'. -// The init process environment contains #envStateCreated if the the container -// is created, but not yet running/started. -// This requires the proc filesystem to be mounted on the host. -func (c *Runtime) getContainerState() (ContainerState, error) { +func (c *Runtime) getContainerState() (state ContainerState, err error) { + for i := 0; i < 5; i++ { + state, err = c.getContainerStateOnce() + if err == nil { + return state, nil + } + c.Log.Trace().Err(err).Msg("transient container state - retry") + time.Sleep(time.Millisecond * 5) + } + return state, err +} + +func (c *Runtime) getContainerStateOnce() (ContainerState, error) { state := c.Container.State() switch state { case lxc.STOPPED: @@ -348,16 +355,17 @@ func (c *Runtime) getContainerState() (ContainerState, error) { } // getContainerInitState returns the detailed state of the container init process. -// If the init process is not running StateStopped is returned along with an error. +// This should be called if the container is in state lxc.RUNNING. +// On error the caller should call getContainerState() again func (c *Runtime) getContainerInitState() (ContainerState, error) { initPid := c.Container.InitPid() if initPid < 1 { - return StateStopped, fmt.Errorf("init cmd is not running") + return StateStopped, fmt.Errorf("failed to retrieve init pid") } - commPath := fmt.Sprintf("/proc/%d/cmdline", initPid) - cmdline, err := ioutil.ReadFile(commPath) + cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) + cmdline, err := ioutil.ReadFile(cmdlinePath) if err != nil { - // can not determine state, caller may try again + // either init process died or proc filesystem was unmounted (very unlikely) return StateStopped, err } @@ -488,7 +496,7 @@ func (c *Runtime) Start(ctx context.Context) error { return errorf("failed to read from syncfifo: %w", err) } } - if err := c.waitRunning(ctx); err != nil { + if err := c.waitStarted(ctx); err != nil { return errorf("container is not running: %w", err) } return nil @@ -575,12 +583,9 @@ func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { if err != nil { return errorf("failed to load container: %w", err) } - state, err := c.getContainerState() - if err != nil { - return errorf("failed to get container state: %w", err) - } - if !(state == StateCreated || state == StateRunning) { - return errorf("can only kill container in state Created|Running but was %q", state) + state := c.Container.State() + if state != lxc.RUNNING { + return errorf("can only kill container in state lxc.RUNNING but was %q", state) } if err := c.killContainer(ctx, signum); err != nil { return errorf("failed to kill container: %w", err) From c5894d3740ed588596be3afe419ff3a15dc310dd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 3 Dec 2020 23:20:37 +0100 Subject: [PATCH 110/373] kill: replace lxc.Container.Wait with polling. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index e54f907e..e1e9261c 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -323,11 +323,27 @@ func (c *Runtime) waitStarted(ctx context.Context) error { if initState == StateRunning { return nil } + // use a short interval here because we wait for the + // the time it may take for crio-lxc-init to exec the container process time.Sleep(time.Millisecond * 10) } } } +func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { + for { + select { + case <-ctx.Done(): + return false + default: + if c.Container.State() == state { + return true + } + time.Sleep(time.Millisecond * 100) + } + } +} + func (c *Runtime) getContainerState() (state ContainerState, err error) { for i := 0; i < 5; i++ { state, err = c.getContainerStateOnce() @@ -379,6 +395,7 @@ func (c *Runtime) getContainerInitState() (ContainerState, error) { } func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { + c.Log.Info().Int("signum", int(signum)).Msg("killing container process") if signum == unix.SIGKILL || signum == unix.SIGTERM { if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { return err @@ -386,11 +403,8 @@ func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { if err := c.Container.Stop(); err != nil { return err } - timeout := time.Second - if deadline, ok := ctx.Deadline(); ok { - timeout = deadline.Sub(time.Now()) - } - if !c.Container.Wait(lxc.STOPPED, timeout) { + + if !c.wait(ctx, lxc.STOPPED) { c.Log.Warn().Msg("failed to stop lxc container") } From 82165858bc59b1d4f717c8b3c7498b33b51bbb5d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 00:53:12 +0100 Subject: [PATCH 111/373] delete: Cleanup runtime dir and cgroups when create has failed Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index e1e9261c..e892972b 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -82,7 +82,7 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { return err } if err := f.Close(); err != nil { - return fmt.Errorf("failed to close empty config file: %w", err) + return fmt.Errorf("failed to close empty config tmpfile: %w", err) } if spec.Linux.CgroupsPath == "" { @@ -448,9 +448,11 @@ func (c *Runtime) destroy() error { } } - err := deleteCgroup(c.CgroupDir) - if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + if c.ContainerInfo.CgroupDir != "" { + err := deleteCgroup(c.CgroupDir) + if err != nil && !os.IsNotExist(err) { + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + } } return os.RemoveAll(c.RuntimePath()) @@ -543,13 +545,12 @@ func (c *Runtime) readFifo() error { func (c *Runtime) Delete(ctx context.Context, force bool) error { err := c.loadContainer() - if err != nil { - return errorf("failed to load container: %w", err) + if err == ErrNotExist { + c.Log.Info().Msg("container does not exist") + return nil } - c.Log.Info().Bool("force", force).Msg("delete container") - - if !c.isContainerStopped() { + if err == nil && !c.isContainerStopped() { if !force { return errorf("container is not not stopped (current state %s)", c.Container.State()) } From 38b231f212a6c31fa05b34fd392bd3d883e2aeb4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 17:55:43 +0100 Subject: [PATCH 112/373] go mod tidy Signed-off-by: Ruben Jenster --- go.mod | 1 - go.sum | 98 ---------------------------------------------------------- 2 files changed, 99 deletions(-) diff --git a/go.mod b/go.mod index fe8eff63..aa549639 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/lxc/crio-lxc require ( github.com/creack/pty v1.1.11 github.com/opencontainers/runtime-spec v1.0.2 - github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.20.0 github.com/stretchr/testify v1.3.0 github.com/urfave/cli/v2 v2.3.0 diff --git a/go.sum b/go.sum index 4bf904e5..753e2c06 100644 --- a/go.sum +++ b/go.sum @@ -8,41 +8,9 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= -github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -50,87 +18,21 @@ github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= -github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= -github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM= golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M= -golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201110201400-7099162a900a h1:5E6TPwSBG74zT8xSrVc8W59K4ch4NFobVTnh2BYzHyU= -golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b h1:nZGkhEMZTXoUuojsilSBJNYZV75IczUo+92qHeXnH8o= -gopkg.in/lxc/go-lxc.v2 v2.0.0-20200826211823-2dd0dc9c018b/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From cb82607638e8dca9ab829ea3ac1b56d98fc7b683 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 18:49:10 +0100 Subject: [PATCH 113/373] runtime: check liblxc version for supportsConfigItem Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index e892972b..1e6bfd19 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -669,11 +669,16 @@ func (c *Runtime) setConfigItem(key, value string) error { } func (c *Runtime) supportsConfigItem(keys ...string) bool { + canCheck := lxc.VersionAtLeast(4, 0, 6) + if !canCheck { + c.Log.Warn().Msg("lxc.IsSupportedConfigItem is broken in liblxc < 4.0.6") + } for _, key := range keys { - if !lxc.IsSupportedConfigItem(key) { - c.Log.Info().Str("lxc.config", key).Msg("unsupported config item") - return false + if canCheck && lxc.IsSupportedConfigItem(key) { + continue } + c.Log.Info().Str("lxc.config", key).Msg("unsupported config item") + return false } return true } From f72415080ec33b78c55e8b46ad2fb8a0dda5c30d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 20:07:53 +0100 Subject: [PATCH 114/373] crio-lxc-init: Don't ignore errors from setenv. Cleanup documentation. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 102 ++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 2f9a3afa..284b499f 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -32,7 +32,6 @@ int writefifo(const char *fifo, const char *msg) { int fd; - // Open FIFO for write only fd = open(fifo, O_WRONLY | O_CLOEXEC); if (fd == -1) return -1; @@ -43,8 +42,13 @@ int writefifo(const char *fifo, const char *msg) return close(fd); } -/* reads up to maxlines-1 lines from path into lines */ -int load_cmdline(const char *path, char *buf, int buflen, char **lines, int maxlines) +/* load_cmdline reads up to maxargs-1 cmdline arguments from path into args. + * path is the path of the cmdline file. + * The cmdline files contains a list of null terminated arguments + * similar to /proc//cmdline. + * Each argument must have a maximum length of buflen (including null). + */ +int load_cmdline(const char *path, char *buf, int buflen, char **args, int maxargs) { int fd; FILE *f; @@ -58,10 +62,10 @@ int load_cmdline(const char *path, char *buf, int buflen, char **lines, int maxl if (f == NULL) return 201; - for (n = 0; n < maxlines - 1; n++) { + for (n = 0; n < maxargs - 1; n++) { char c; int i; - // read until next '\0' or EOF + /* read until next '\0' or EOF */ for (i = 0; i < buflen; i++) { c = getc(f); if (c == EOF) { @@ -72,29 +76,35 @@ int load_cmdline(const char *path, char *buf, int buflen, char **lines, int maxl break; } - if (errno != 0) // getc failed + if (errno != 0) /* getc failed */ return 202; if (c == EOF) { - if (i > 0) // trailing garbage + if (i > 0) /* trailing garbage */ return 203; - lines[n] = (char *)NULL; + args[n] = (char *)NULL; break; } - lines[n] = strndup(buf, i); - if (errno != 0) // strndup failed + args[n] = strndup(buf, i); + if (errno != 0) /* strndup failed */ return 204; } - // empty cmdline - if (n < 1) + /* cmdline is empty */ + if (n == 0) return 205; return 0; } -// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 -int load_environment(const char *path, char *buf, int buflen) +/* load_environ loads environment variables from path, + * and adds them to the process environment. + * path is the path to a list of + * null terminated environment variables like /proc//environ + * Each variable must have a maximum length of buflen (including null) + * see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 + */ +int load_environ(const char *path, char *buf, int buflen) { int fd; FILE *f; @@ -111,7 +121,7 @@ int load_environment(const char *path, char *buf, int buflen) char *key = NULL; char c; int i; - // read until next '\0' or EOF + /* read until next '\0' or EOF */ for (i = 0; i < buflen; i++) { c = getc(f); if (c == EOF) { @@ -121,24 +131,23 @@ int load_environment(const char *path, char *buf, int buflen) if (c == '\0') break; - // split at first '=' + /* split at first '=' */ if (key == NULL && c == '=') { buf[i] = '\0'; key = buf; } } - if (errno != 0) // getc failed + if (errno != 0) /* getc failed */ return 212; if (c == EOF) { - if (i > 0) // trailing garbage + if (i > 0) /* trailing garbage */ return 213; break; } - // malformed content e.g - // e.g 'fooo\0' or 'fooo=' + /* malformed content e.g 'fooo\0' or 'fooo=' */ if (key == NULL || i == strlen(key)) return 214; @@ -148,36 +157,40 @@ int load_environment(const char *path, char *buf, int buflen) return 0; } -// Ensure_HOME_exists sets the HOME environment variable if it is not set. -// E.g this is required for running 'cilium v1.9.0' -void ensure_HOME_exists() +/* Ensure_HOME_exists sets the HOME environment variable if it is not set. + * There are containers that don't run without HOME being set e.g 'cilium v1.9.0' + */ +int ensure_HOME_exists() { struct passwd *pw; pw = getpwuid(geteuid()); + /* ignore error from getpwuid */ + errno = 0; if (pw != NULL && pw->pw_dir != NULL) - setenv("HOME", pw->pw_dir, 0); + return setenv("HOME", pw->pw_dir, 0); else - setenv("HOME", "/", 0); // required for cilium to work - - // ignore errors - errno = 0; + return setenv("HOME", "/", 0); } int main(int argc, char **argv) { - // Buffer for reading arguments and environment variables. - // There is not a limit per environment variable, but we limit it to 1MiB here - // https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes - // For arguments "Additionally, the limit per string is 32 pages (the kernel - // constant MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF." + /* Buffer for reading arguments and environment variables. + * There is not a limit per environment variable, but we limit it to 1MiB here + * https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes. + * + * For arguments "Additionally, the limit per string is 32 pages + * (the kernel constant MAX_ARG_STRLEN), + * and the maximum number of strings is 0x7FFFFFFF." + */ char buf[1024 * 1024]; - // see 'man 2 execve' 'Limits on size of arguments and environment' - // ... ARG_MAX constant (either defined in or available at - // run time using the call sysconf(_SC_ARG_MAX)) - char *args[256]; // > _POSIX_ARG_MAX+1 - const char *cid; + /* Null terminated list of cmline arguments. + * See 'man 2 execve' 'Limits on size of arguments and environment' + */ + char *args[256]; + + const char *container_id; int ret = 0; @@ -186,12 +199,12 @@ int main(int argc, char **argv) fprintf(stderr, "usage: %s \n", argv[0]); exit(-1); } - cid = argv[1]; + container_id = argv[1]; - // clear environment + /* clear environment */ environ = NULL; - ret = load_environment(environ_path, buf, sizeof(buf)); + ret = load_environ(environ_path, buf, sizeof(buf)); if (ret != 0) { if (errno != 0) fprintf(stderr, "error reading environment file \"%s\": %s\n", @@ -207,9 +220,12 @@ int main(int argc, char **argv) exit(ret); } - ensure_HOME_exists(); + if (ensure_HOME_exists() == -1) { + fprintf(stderr, "error setenv HOME: %s\n", strerror(errno)); + exit(ret); + } - if (writefifo(syncfifo_path, cid) == -1) { + if (writefifo(syncfifo_path, container_id) == -1) { perror("failed to write syncfifo"); exit(220); } From 8924ac85c22c47fd28017093a5af60b5dc1559cf Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 23:40:00 +0100 Subject: [PATCH 115/373] init: Write errors to termination-log if exists Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 75 ++++++++++++++++++++++------------------ lxcontainer/init.go | 6 ++++ 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 284b499f..8bf38816 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -13,6 +13,7 @@ const char *syncfifo_path = "syncfifo"; const char *cmdline_path = "cmdline"; const char *environ_path = "environ"; +const char *termination_log = "termination-log"; // A conformance test that will fail if SETENV_OVERWRITE is set to 0 // is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] @@ -28,6 +29,12 @@ const char *environ_path = "environ"; #define SETENV_OVERWRITE 1 #endif +#define ERROR(...) \ + { \ + dprintf(errfd, __VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } + int writefifo(const char *fifo, const char *msg) { int fd; @@ -56,11 +63,11 @@ int load_cmdline(const char *path, char *buf, int buflen, char **args, int maxar fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) - return 200; + return -1; f = fdopen(fd, "r"); if (f == NULL) - return 201; + return -1; for (n = 0; n < maxargs - 1; n++) { char c; @@ -77,22 +84,22 @@ int load_cmdline(const char *path, char *buf, int buflen, char **args, int maxar } if (errno != 0) /* getc failed */ - return 202; + return -1; if (c == EOF) { if (i > 0) /* trailing garbage */ - return 203; + return -1; args[n] = (char *)NULL; break; } args[n] = strndup(buf, i); if (errno != 0) /* strndup failed */ - return 204; + return -1; } /* cmdline is empty */ if (n == 0) - return 205; + return -1; return 0; } @@ -111,11 +118,11 @@ int load_environ(const char *path, char *buf, int buflen) fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) - return 210; + return -1; f = fopen(path, "r"); if (f == NULL) - return 211; + return -1; for (;;) { char *key = NULL; @@ -139,20 +146,20 @@ int load_environ(const char *path, char *buf, int buflen) } if (errno != 0) /* getc failed */ - return 212; + return -1; if (c == EOF) { if (i > 0) /* trailing garbage */ - return 213; + return -1; break; } /* malformed content e.g 'fooo\0' or 'fooo=' */ if (key == NULL || i == strlen(key)) - return 214; + return -1; if (setenv(key, buf + strlen(key) + 1, SETENV_OVERWRITE) == -1) - return 215; + return -1; } return 0; } @@ -169,8 +176,8 @@ int ensure_HOME_exists() errno = 0; if (pw != NULL && pw->pw_dir != NULL) return setenv("HOME", pw->pw_dir, 0); - else - return setenv("HOME", "/", 0); + + return setenv("HOME", "/", 0); } int main(int argc, char **argv) @@ -194,10 +201,16 @@ int main(int argc, char **argv) int ret = 0; + int errfd; + + errfd = open(termination_log, O_WRONLY | O_CLOEXEC); + if (errfd == -1) + errfd = 2; + if (argc != 2) { - fprintf(stderr, "invalid number of arguments %d\n", argc); - fprintf(stderr, "usage: %s \n", argv[0]); - exit(-1); + ERROR("invalid number of arguments %d\n" + "usage: %s \n", + argc, argv[0]); } container_id = argv[1]; @@ -205,38 +218,34 @@ int main(int argc, char **argv) environ = NULL; ret = load_environ(environ_path, buf, sizeof(buf)); - if (ret != 0) { + if (ret == -1) { if (errno != 0) - fprintf(stderr, "error reading environment file \"%s\": %s\n", - environ_path, strerror(errno)); - exit(ret); + ERROR("error reading environment file \"%s\": %s\n", + environ_path, strerror(errno)); } ret = load_cmdline(cmdline_path, buf, sizeof(buf), args, sizeof(args)); - if (ret != 0) { + if (ret == -1) { if (errno != 0) - fprintf(stderr, "error reading cmdline file \"%s\": %s\n", - cmdline_path, strerror(errno)); - exit(ret); + ERROR("error reading cmdline file \"%s\": %s\n", + cmdline_path, strerror(errno)); } if (ensure_HOME_exists() == -1) { - fprintf(stderr, "error setenv HOME: %s\n", strerror(errno)); - exit(ret); + ERROR("failed to set HOME environment variable: %s\n", + strerror(errno)); } if (writefifo(syncfifo_path, container_id) == -1) { - perror("failed to write syncfifo"); - exit(220); + ERROR("failed to write syncfifo: %s\n", strerror(errno)); } if (chdir("cwd") == -1) { - perror("failed to change working directory"); - exit(221); + ERROR("failed to change working directory: %s\n", + strerror(errno)); } if (execvp(args[0], args) == -1) { - fprintf(stderr, "failed to exec \"%s\": %s\n", args[0], strerror(errno)); - exit(222); + ERROR("failed to exec \"%s\": %s\n", args[0], strerror(errno)); } } diff --git a/lxcontainer/init.go b/lxcontainer/init.go index ec591f99..622c3d6b 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -66,6 +66,12 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { return err } + if p := spec.Annotations["io.kubernetes.container.terminationMessagePath"]; p != "" { + if err := os.Symlink(p, filepath.Join(runtimeInitDir, "termination-log")); err != nil { + return err + } + } + if err := configureInitUser(clxc, spec); err != nil { return err } From 7d4b370adee275cf332459ce4ac2d648ee59d41a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 4 Dec 2020 23:48:30 +0100 Subject: [PATCH 116/373] hook: Fix formatting. Use macro for error handling. Signed-off-by: Ruben Jenster --- cmd/container-hook/hook.c | 106 ++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/cmd/container-hook/hook.c b/cmd/container-hook/hook.c index 0dd63113..9ce889ff 100644 --- a/cmd/container-hook/hook.c +++ b/cmd/container-hook/hook.c @@ -13,6 +13,13 @@ #include #include +#define ERROR(...) \ + { \ + printf(__VA_ARGS__); \ + ret = EXIT_FAILURE; \ + goto out; \ + } + int mask_paths_at(int rootfs, int runtime, const char *masked) { // limits.h PATH_MAX @@ -25,23 +32,24 @@ int mask_paths_at(int rootfs, int runtime, const char *masked) fd = openat(runtime, masked, O_RDONLY); if (fd == -1) { if (errno == ENOENT) { - printf("file \"%s\" does not exist\n", masked); + printf("file \"%s\" does not exist\n", masked); return 0; - } + } return -1; } f = fdopen(fd, "r"); if (f == NULL) { - printf("file descriptor for runtime directory is null: %s", strerror(errno)); + printf("file descriptor for runtime directory is null: %s", + strerror(errno)); close(fd); return -1; } if (fchdir(rootfs) != 0) { - printf("file to change to rootfs: %s\n", strerror(errno)); + printf("file to change to rootfs: %s\n", strerror(errno)); goto out; - } + } while (fgets(line, sizeof(line), f) != NULL) { line[strlen(line) - 1] = '\0'; // remove newline; @@ -61,7 +69,7 @@ int mask_paths_at(int rootfs, int runtime, const char *masked) if (mount("tmpfs", rel, "tmpfs", MS_RDONLY, NULL) == -1) goto out; } else { - printf("masking file %s\n", rel); + printf("masking file %s\n", rel); if (mount("/dev/null", rel, NULL, MS_BIND, NULL) == -1) goto out; } @@ -82,15 +90,16 @@ int create_devices_at(int rootfs, int runtime, const char *devices) fd = openat(runtime, devices, O_RDONLY); if (fd == -1) { if (errno == ENOENT) { - printf("file \"%s\" does not exist\n", devices); + printf("file \"%s\" does not exist\n", devices); return 0; - } + } return -1; } f = fdopen(fd, "r"); if (f == NULL) { - printf("file descriptor for runtime directory is null: %s", strerror(errno)); + printf("file descriptor for runtime directory is null: %s", + strerror(errno)); close(fd); return -1; } @@ -107,7 +116,7 @@ int create_devices_at(int rootfs, int runtime, const char *devices) int ret; if (fchdir(rootfs) == -1) { - printf("file to change to rootfs: %s\n", strerror(errno)); + printf("file to change to rootfs: %s\n", strerror(errno)); goto out; } @@ -162,7 +171,8 @@ int create_devices_at(int rootfs, int runtime, const char *devices) goto out; } if (chdir(dir) != 0) { - printf("%s:%d failed to change to directory \"%s\": %s\n", devices, line, dir, strerror(errno)); + printf("%s:%d failed to change to directory \"%s\": %s\n", + devices, line, dir, strerror(errno)); goto out; } } @@ -171,12 +181,14 @@ int create_devices_at(int rootfs, int runtime, const char *devices) dev, mode, major, minor, filemode, uid, gid); ret = mknod(dev, ft | filemode, makedev(major, minor)); if (ret == -1) { - printf("%s:%d failed to create device \"%s\"\n", devices, line, dev); + printf("%s:%d failed to create device \"%s\"\n", + devices, line, dev); goto out; } ret = chown(dev, uid, gid); if (ret == -1) { - printf("%s:%d failed to chown %d:%d device \"%s\"\n", devices, line, uid, gid, dev); + printf("%s:%d failed to chown %d:%d device \"%s\"\n", + devices, line, uid, gid, dev); goto out; } } @@ -190,60 +202,44 @@ int main(int argc, char **argv) const char *rootfs_mount; const char *config_file; const char *runtime_path; - int rootfs; - int runtime; + int rootfs_fd; + int runtime_fd; int ret = EXIT_SUCCESS; rootfs_mount = getenv("LXC_ROOTFS_MOUNT"); config_file = getenv("LXC_CONFIG_FILE"); - if (rootfs_mount == NULL) { - printf("LXC_ROOTFS_MOUNT environment variable not set\n"); - ret = 1; - goto out; - } - if (config_file == NULL) { - printf("LXC_CONFIG_FILE environment variable not set\n"); - ret = 2; - goto out; - } + if (rootfs_mount == NULL) + ERROR("LXC_ROOTFS_MOUNT environment variable not set\n"); - rootfs = open(rootfs_mount, O_PATH); - if (rootfs == -1) { - printf("failed to open rootfs mount directory: %s", strerror(errno)); - ret = 3; - goto out; - } + if (config_file == NULL) + ERROR("LXC_CONFIG_FILE environment variable not set\n"); + + rootfs_fd = open(rootfs_mount, O_PATH); + if (rootfs_fd == -1) + ERROR("failed to open rootfs mount directory: %s", + strerror(errno)); runtime_path = dirname(strdup(config_file)); - runtime = open(runtime_path, O_PATH); - if (rootfs == -1) { - printf("failed to open runtime directory: %s", strerror(errno)); - ret = 4; - goto out; - } + runtime_fd = open(runtime_path, O_PATH); - printf("create devices int container rootfs\n"); - if (create_devices_at(rootfs, runtime, "devices.txt") == -1) { - printf("failed to create devices: %s", strerror(errno)); - ret = 5; - goto out; - } + if (runtime_fd == -1) + ERROR("failed to open runtime directory: %s", strerror(errno)); - printf("masking files and directories in container rootfs\n"); - if (mask_paths_at(rootfs, runtime, "masked.txt") == -1) { - printf("failed to mask paths: %s", strerror(errno)); - ret = 6; - goto out; - } + printf("create devices int container rootfs\n"); + if (create_devices_at(rootfs_fd, runtime_fd, "devices.txt") == -1) + ERROR("failed to create devices: %s", strerror(errno)); + + printf("masking files and directories in container rootfs\n"); + if (mask_paths_at(rootfs_fd, runtime_fd, "masked.txt") == -1) + ERROR("failed to mask paths: %s", strerror(errno)); out: - if (rootfs >= 0) - close(rootfs); + if (rootfs_fd >= 0) + close(rootfs_fd); - if (runtime >= 0) - close(runtime); + if (runtime_fd >= 0) + close(runtime_fd); - printf("returning with %d\n", ret); - return ret; + exit(ret); } From ef3f598c464aeb747a85a84765beaa5037e89b5c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 5 Dec 2020 17:15:26 +0100 Subject: [PATCH 117/373] init: Create symlink to k8s termination log. Signed-off-by: Ruben Jenster --- lxcontainer/init.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 622c3d6b..5ead566b 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -66,9 +66,12 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { return err } - if p := spec.Annotations["io.kubernetes.container.terminationMessagePath"]; p != "" { - if err := os.Symlink(p, filepath.Join(runtimeInitDir, "termination-log")); err != nil { - return err + if spec.Annotations != nil { + msgPath := spec.Annotations["io.kubernetes.container.terminationMessagePath"] + if msgPath != "" { + if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "termination-log")); err != nil { + return err + } } } From 228ff6417bdf332744943a7d2dc5ed07c43c912e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 6 Dec 2020 16:50:08 +0100 Subject: [PATCH 118/373] init: Reset errno after if termination log is unavailable. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 8bf38816..22c36153 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -204,8 +204,10 @@ int main(int argc, char **argv) int errfd; errfd = open(termination_log, O_WRONLY | O_CLOEXEC); - if (errfd == -1) + if (errfd == -1) { + errno = 0; errfd = 2; + } if (argc != 2) { ERROR("invalid number of arguments %d\n" From 7e90d857e10279f482255b29a96a4b7fe04a52d4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 6 Dec 2020 17:07:24 +0100 Subject: [PATCH 119/373] init: Rename termination-log to error.log. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 5 +++-- lxcontainer/init.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 22c36153..1112312e 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -13,7 +13,7 @@ const char *syncfifo_path = "syncfifo"; const char *cmdline_path = "cmdline"; const char *environ_path = "environ"; -const char *termination_log = "termination-log"; +const char *error_log = "error.log"; // A conformance test that will fail if SETENV_OVERWRITE is set to 0 // is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] @@ -203,7 +203,8 @@ int main(int argc, char **argv) int errfd; - errfd = open(termination_log, O_WRONLY | O_CLOEXEC); + /* write errors to error_log if it exists otherwise to stderr */ + errfd = open(error_log, O_WRONLY | O_CLOEXEC); if (errfd == -1) { errno = 0; errfd = 2; diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 5ead566b..21717d74 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -69,7 +69,7 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { if spec.Annotations != nil { msgPath := spec.Annotations["io.kubernetes.container.terminationMessagePath"] if msgPath != "" { - if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "termination-log")); err != nil { + if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "error.log")); err != nil { return err } } From b4b99c9d45d356d8f473bd1d6b0601c5aca5f089 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 6 Dec 2020 17:07:42 +0100 Subject: [PATCH 120/373] Fix error handling for load_environ and load_cmdline. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 1112312e..25bccff9 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -118,7 +118,7 @@ int load_environ(const char *path, char *buf, int buflen) fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) - return -1; + return 0; f = fopen(path, "r"); if (f == NULL) @@ -222,16 +222,14 @@ int main(int argc, char **argv) ret = load_environ(environ_path, buf, sizeof(buf)); if (ret == -1) { - if (errno != 0) - ERROR("error reading environment file \"%s\": %s\n", - environ_path, strerror(errno)); + ERROR("error reading environment file \"%s\": %s\n", + environ_path, strerror(errno)); } ret = load_cmdline(cmdline_path, buf, sizeof(buf), args, sizeof(args)); if (ret == -1) { - if (errno != 0) - ERROR("error reading cmdline file \"%s\": %s\n", - cmdline_path, strerror(errno)); + ERROR("error reading cmdline file \"%s\": %s\n", cmdline_path, + strerror(errno)); } if (ensure_HOME_exists() == -1) { From 8e7132ef739f649480304af4dc783308c76448f5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 7 Dec 2020 08:46:27 +0100 Subject: [PATCH 121/373] Fix typo. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 25bccff9..4d24a7db 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -203,7 +203,7 @@ int main(int argc, char **argv) int errfd; - /* write errors to error_log if it exists otherwise to stderr */ + /* write errors to error.log if it exists otherwise to stderr */ errfd = open(error_log, O_WRONLY | O_CLOEXEC); if (errfd == -1) { errno = 0; From b8528db2c90997bc80934f4922ddbc26585cb86c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 7 Dec 2020 09:57:31 +0100 Subject: [PATCH 122/373] start: Do not wait for container start. The start command should return success after successfully writing to the syncfifo. It's not necessary to check the init state after this, since init may have failed to exec or the container process may have already returned or died. These failures are visible from either stderr or the kubernetes termination log. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 1e6bfd19..59c0ff24 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -309,27 +309,6 @@ func (c *Runtime) waitCreated(ctx context.Context) error { } } -func (c *Runtime) waitStarted(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - state := c.Container.State() - if !(state == lxc.RUNNING) { - return fmt.Errorf("container state must be lxc.RUNNING (was %q)", state) - } - initState, _ := c.getContainerInitState() - if initState == StateRunning { - return nil - } - // use a short interval here because we wait for the - // the time it may take for crio-lxc-init to exec the container process - time.Sleep(time.Millisecond * 10) - } - } -} - func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { for { select { @@ -344,19 +323,7 @@ func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { } } -func (c *Runtime) getContainerState() (state ContainerState, err error) { - for i := 0; i < 5; i++ { - state, err = c.getContainerStateOnce() - if err == nil { - return state, nil - } - c.Log.Trace().Err(err).Msg("transient container state - retry") - time.Sleep(time.Millisecond * 5) - } - return state, err -} - -func (c *Runtime) getContainerStateOnce() (ContainerState, error) { +func (c *Runtime) getContainerState() (ContainerState, error) { state := c.Container.State() switch state { case lxc.STOPPED: @@ -381,7 +348,8 @@ func (c *Runtime) getContainerInitState() (ContainerState, error) { cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := ioutil.ReadFile(cmdlinePath) if err != nil { - // either init process died or proc filesystem was unmounted (very unlikely) + // either init process died or returned already + // or proc filesystem was unmounted (very unlikely) return StateStopped, err } @@ -512,9 +480,6 @@ func (c *Runtime) Start(ctx context.Context) error { return errorf("failed to read from syncfifo: %w", err) } } - if err := c.waitStarted(ctx); err != nil { - return errorf("container is not running: %w", err) - } return nil } From 76894926262b2e962eacb3de019da307fbdd1ead Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 7 Dec 2020 20:00:31 +0100 Subject: [PATCH 123/373] state: Do not return an error when init has died. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 59c0ff24..cc629110 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -343,10 +343,13 @@ func (c *Runtime) getContainerState() (ContainerState, error) { func (c *Runtime) getContainerInitState() (ContainerState, error) { initPid := c.Container.InitPid() if initPid < 1 { - return StateStopped, fmt.Errorf("failed to retrieve init pid") + return StateStopped, nil } cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := ioutil.ReadFile(cmdlinePath) + if os.IsNotExist(err) { + return StateStopped, nil + } if err != nil { // either init process died or returned already // or proc filesystem was unmounted (very unlikely) From 9b6fba3273b4eed69a326974386e08443672043f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 7 Dec 2020 22:23:40 +0100 Subject: [PATCH 124/373] create: Fix permissions of mount destination paths if spec.Process.User.UID and GID are > 0. Signed-off-by: Ruben Jenster --- lxcontainer/mount.go | 8 +++++--- lxcontainer/utils.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index a41007dd..c2a1c878 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -70,15 +70,17 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { // check if mountpoint is optional ? return fmt.Errorf("failed to access source for bind mount: %w", err) } + uid := int(spec.Process.User.UID) + gid := int(spec.Process.User.GID) if err == nil && !info.IsDir() { ms.Options = append(ms.Options, "create=file") // source exists and is not a directory // create a target file that can be used as target for a bind mount - if err := os.MkdirAll(filepath.Dir(ms.Destination), 0750); err != nil { + if err := mkdirAll(filepath.Dir(ms.Destination), 0750, uid, gid); err != nil { return fmt.Errorf("failed to create mount destination dir: %w", err) } - f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0440) + f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0) if err != nil { return fmt.Errorf("failed to create file mountpoint: %w", err) } @@ -87,7 +89,7 @@ func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { ms.Options = append(ms.Options, "create=dir") // FIXME exclude all directories that are below other mounts // only directories / files on the readonly rootfs must be created - if err := os.MkdirAll(ms.Destination, 0750); err != nil { + if err = mkdirAll(ms.Destination, 0750, uid, gid); err != nil { return fmt.Errorf("failed to create mount target dir: %w", err) } return nil diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 116d9005..620b25b0 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -120,3 +120,47 @@ func errorf(sfmt string, args ...interface{}) error { } return fmt.Errorf(sfmt, args...) } + +// Modified version of golang standard library os.MkdirAll +func mkdirAll(path string, perm os.FileMode, uid int, gid int) error { + // Fast path: if we can tell whether path is a directory or file, stop with success or error. + dir, err := os.Stat(path) + if err == nil { + if dir.IsDir() { + return nil + } + return &os.PathError{"mkdir", path, unix.ENOTDIR} + } + + // Slow path: make sure parent exists and then call Mkdir for path. + i := len(path) + for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator. + i-- + } + + j := i + for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element. + j-- + } + + if j > 1 { + // Create parent. + err = mkdirAll(path[:j-1], perm, uid, gid) + if err != nil { + return err + } + } + + // Parent now exists; invoke Mkdir and use its result. + err = os.Mkdir(path, perm) + if err != nil { + // Handle arguments like "foo/." by + // double-checking that directory doesn't exist. + dir, err1 := os.Lstat(path) + if err1 == nil && dir.IsDir() { + return nil + } + return err + } + return unix.Chown(path, uid, gid) +} From a5a0a567ba1b96c00faf62309c9ccec760488e12 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 8 Dec 2020 09:04:42 +0100 Subject: [PATCH 125/373] cli: Add flag log-timestamp. Signed-off-by: Ruben Jenster --- cmd/cli.go | 7 +++++++ lxcontainer/runtime.go | 9 ++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index bc6c3a27..9a9063c8 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -76,6 +76,13 @@ func main() { Value: "/var/log/crio-lxc/crio-lxc.log", Destination: &clxc.LogFilePath, }, + &cli.StringFlag{ + Name: "log-timestamp", + Usage: "timestamp format for the runtime log (see golang time package), default matches liblxc timestamp", + EnvVars: []string{"CRIO_LXC_LOG_TIMESTAMP"}, // e.g '0102 15:04:05.000' + Value: "20060102150405.000", + Destination: &clxc.LogTimestamp, + }, &cli.StringFlag{ Name: "root", Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended.", diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index cc629110..5661d429 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -17,12 +17,6 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -// logging constants -const ( - // liblxc timestamp formattime format - timeFormatLXCMillis = "20060102150405.000" -) - // ContainerState represents the state of a container. type ContainerState string @@ -52,6 +46,7 @@ type Runtime struct { LogFile *os.File LogFilePath string LogLevel string + LogTimestamp string ContainerLogLevel string SystemdCgroup bool MonitorCgroup string @@ -211,7 +206,7 @@ func (c *Runtime) ConfigureLogging(cmdName string) error { // match liblxc timestamp format zerolog.TimestampFieldName = "t" - zerolog.TimeFieldFormat = timeFormatLXCMillis + zerolog.TimeFieldFormat = c.LogTimestamp zerolog.TimestampFunc = func() time.Time { return time.Now().UTC() } From 35f220527ddfb1238bfee92bad195a4538e535c0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 8 Dec 2020 10:13:32 +0100 Subject: [PATCH 126/373] runtime: Update comments and remove unused code. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 5661d429..d03fe62f 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -343,18 +343,16 @@ func (c *Runtime) getContainerInitState() (ContainerState, error) { cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := ioutil.ReadFile(cmdlinePath) if os.IsNotExist(err) { + // init process died or returned return StateStopped, nil } if err != nil { - // either init process died or returned already - // or proc filesystem was unmounted (very unlikely) + // it's a serious error if cmdlinePath exists but can't be read return StateStopped, err } - // comm contains a trailing newline initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) if string(cmdline) == initCmdline { - //if strings.HasPrefix(c.ContainerID, strings.TrimSpace(string(comm))) { return StateCreated, nil } return StateRunning, nil @@ -374,7 +372,7 @@ func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { c.Log.Warn().Msg("failed to stop lxc container") } - // draining the cgroup is required to catch processes that escaped from the + // draining the cgroup is required to catch processes that escaped from // 'kill' e.g a bash for loop that spawns a new child immediately. start := time.Now() err := drainCgroup(ctx, c.CgroupDir, signum) From 7c9dd7ede704af20aadc06c9cdae656d3d82e5fe Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 9 Dec 2020 18:48:48 +0100 Subject: [PATCH 127/373] create, start, init: Improve error logging. Signed-off-by: Ruben Jenster --- Makefile | 4 +- cmd/init/crio-lxc-init.c | 8 ++-- cmd/start/crio-lxc-start.c | 75 ++++++++++++++++++-------------------- lxcontainer/utils.go | 10 ++--- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index 7c67bd40..cfe35792 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,10 @@ crio-lxc: $(GO_SRC) Makefile go.mod go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c - $(CC) -Wall $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? + $(CC) -Wall -Wpedantic $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? crio-lxc-init: cmd/init/crio-lxc-init.c - /usr/local/musl/bin/musl-gcc -Wpedantic -Wall -static -g -o $@ $? + /usr/local/musl/bin/musl-gcc -Wall -Wpedantic -static -g -o $@ $? #musl-gcc -g3 -Wall -static $? -o $@ # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 4d24a7db..2ccde343 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -29,10 +29,10 @@ const char *error_log = "error.log"; #define SETENV_OVERWRITE 1 #endif -#define ERROR(...) \ - { \ - dprintf(errfd, __VA_ARGS__); \ - exit(EXIT_FAILURE); \ +#define ERROR(format, ...) \ + { \ + dprintf(errfd, "[crio-lxc-init] " format, ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ } int writefifo(const char *fifo, const char *msg) diff --git a/cmd/start/crio-lxc-start.c b/cmd/start/crio-lxc-start.c index e74f4dde..23d7c941 100644 --- a/cmd/start/crio-lxc-start.c +++ b/cmd/start/crio-lxc-start.c @@ -1,11 +1,11 @@ #define _GNU_SOURCE -#include -#include -#include +#include #include -#include #include -#include +#include +#include +#include +#include #include @@ -15,30 +15,30 @@ */ #define ENABLE_LXCINIT 0 +#define ERROR(format, ...) \ + { \ + fprintf(stderr, "[crio-lxc-start] " format, ##__VA_ARGS__); \ + ret = EXIT_FAILURE; \ + goto out; \ + } + /* NOTE lxc_execute.c was taken as guidline and some lines where copied. */ -int main(int argc, char** argv) +int main(int argc, char **argv) { - int ret; - struct lxc_container *c; - int err = EXIT_FAILURE; - const char * name; - const char * lxcpath; - const char * rcfile; + struct lxc_container *c = NULL; + int ret = EXIT_SUCCESS; + const char *name; + const char *lxcpath; + const char *rcfile; /* Ensure stdout and stderr are line bufferd. */ setvbuf(stdout, NULL, _IOLBF, -1); setvbuf(stderr, NULL, _IOLBF, -1); + errno = 0; - if (argc != 4) { - fprintf(stderr, "invalid cmdline: usage %s \n", argv[0]); - exit(err); - } - - ret = isatty(STDIN_FILENO); - if (ret < 0) { - perror("isatty"); - exit(96); - } + if (argc != 4) + ERROR("invalid argument count, usage: " + "$0 \n"); /* / If this is non interactive, get rid of our controlling terminal, @@ -46,38 +46,35 @@ int main(int argc, char** argv) / Ignore any error - because controlling terminal could be a PTY. */ setsid(); + errno = 0; name = argv[1]; lxcpath = argv[2]; rcfile = argv[3]; c = lxc_container_new(name, lxcpath); - if (!c) { - fprintf(stderr, "failed to create container"); - exit(err); - } + if (c == NULL) + ERROR("failed to create new container"); c->clear_config(c); - if (!c->load_config(c, rcfile)) { - fprintf(stderr, "failed to load container config file"); - goto out; - } + + if (!c->load_config(c, rcfile)) + ERROR("failed to load container config %s\n", rcfile); /* Do not daemonize - this would null the inherited stdio. */ c->daemonize = false; - if (!c->start(c, ENABLE_LXCINIT, NULL)) { - fprintf(stderr, "lxc container failed to start"); - goto out; - } + if (!c->start(c, ENABLE_LXCINIT, NULL)) + ERROR("failed to start container\n"); - if (WIFEXITED(c->error_num)) - err = WEXITSTATUS(c->error_num); - else + if (WIFSIGNALED(c->error_num)) /* Try to die with the same signal the task did. */ kill(0, WTERMSIG(c->error_num)); + if (WIFEXITED(c->error_num)) + ret = WEXITSTATUS(c->error_num); out: - lxc_container_put(c); - exit(err); + if (c != NULL) + lxc_container_put(c); + exit(ret); } diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 620b25b0..7aff621d 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -7,7 +7,6 @@ import ( "os" "path/filepath" "runtime" - "strconv" "golang.org/x/sys/unix" ) @@ -114,11 +113,10 @@ func nullTerminatedString(data []byte) string { } func errorf(sfmt string, args ...interface{}) error { - _, file, line, ok := runtime.Caller(1) - if ok { - return fmt.Errorf(filepath.Base(file)+":"+strconv.Itoa(line)+" "+sfmt, args...) - } - return fmt.Errorf(sfmt, args...) + bin := filepath.Base(os.Args[0]) + _, file, line, _ := runtime.Caller(1) + prefix := fmt.Sprintf("[%s:%s:%d] ", bin, filepath.Base(file), line) + return fmt.Errorf(prefix+sfmt, args...) } // Modified version of golang standard library os.MkdirAll From d24ce9e1b468a4a61cc4d9de5582f75436c89f0e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 10 Dec 2020 10:40:48 +0100 Subject: [PATCH 128/373] create: Stop polling for init status if crio-lxc-start has terminated. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 13786b53..e04f154c 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -89,6 +89,20 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err return err } + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + go func() { + // NOTE this goroutine may leak until crio-lxc is terminated + ps, err := cmd.Process.Wait() + if err != nil { + clxc.Log.Error().Err(err).Msg("failed to wait for start process") + } else { + clxc.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") + } + cancel() + }() + clxc.Log.Debug().Msg("waiting for init") if err := clxc.waitCreated(ctx); err != nil { return err From 43fc37b2d6b588a211ace480d62b7eb20b8ee384 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 8 Dec 2020 15:37:09 +0100 Subject: [PATCH 129/373] init: Prefer /root as value for HOME if it exists. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 2ccde343..ed7e87bc 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -170,6 +170,11 @@ int load_environ(const char *path, char *buf, int buflen) int ensure_HOME_exists() { struct passwd *pw; + int root_fd; + + // fast path + if (getenv("HOME") != NULL) + return 0; pw = getpwuid(geteuid()); /* ignore error from getpwuid */ @@ -177,6 +182,14 @@ int ensure_HOME_exists() if (pw != NULL && pw->pw_dir != NULL) return setenv("HOME", pw->pw_dir, 0); + root_fd = open("/root", O_PATH | O_CLOEXEC); + errno = 0; + if (root_fd != -1) { + close(root_fd); + errno = 0; + return setenv("HOME", "/root", 0); + } + return setenv("HOME", "/", 0); } From b24b6917b5bb33901a57b51f48e85057ad9d435f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 11 Dec 2020 16:08:37 +0100 Subject: [PATCH 130/373] init: Fix file descriptor leak to /.crio-lxc/environ on exec. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index ed7e87bc..c316cb1a 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -120,7 +120,7 @@ int load_environ(const char *path, char *buf, int buflen) if (fd == -1) return 0; - f = fopen(path, "r"); + f = fdopen(fd, "r"); if (f == NULL) return -1; From eeaabd0a5343223e31200ce71e668a3eeeccf8cd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 12 Dec 2020 01:09:52 +0100 Subject: [PATCH 131/373] init: Remove unused curly brackets. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index c316cb1a..2522a8ca 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -223,41 +223,36 @@ int main(int argc, char **argv) errfd = 2; } - if (argc != 2) { + if (argc != 2) ERROR("invalid number of arguments %d\n" "usage: %s \n", argc, argv[0]); - } + container_id = argv[1]; /* clear environment */ environ = NULL; ret = load_environ(environ_path, buf, sizeof(buf)); - if (ret == -1) { + if (ret == -1) ERROR("error reading environment file \"%s\": %s\n", environ_path, strerror(errno)); - } ret = load_cmdline(cmdline_path, buf, sizeof(buf), args, sizeof(args)); - if (ret == -1) { + if (ret == -1) ERROR("error reading cmdline file \"%s\": %s\n", cmdline_path, strerror(errno)); - } - if (ensure_HOME_exists() == -1) { + if (ensure_HOME_exists() == -1) ERROR("failed to set HOME environment variable: %s\n", strerror(errno)); - } - if (writefifo(syncfifo_path, container_id) == -1) { + if (writefifo(syncfifo_path, container_id) == -1) ERROR("failed to write syncfifo: %s\n", strerror(errno)); - } - if (chdir("cwd") == -1) { + if (chdir("cwd") == -1) ERROR("failed to change working directory: %s\n", strerror(errno)); - } if (execvp(args[0], args) == -1) { ERROR("failed to exec \"%s\": %s\n", args[0], strerror(errno)); From 20afa2326d6b47b68e827956da3506b8ab51b614 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 12 Dec 2020 01:10:00 +0100 Subject: [PATCH 132/373] init: Close all fds except stdio 0,1,2 Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index 2522a8ca..d5075c23 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -1,4 +1,5 @@ #define _GNU_SOURCE +#include #include #include #include @@ -193,6 +194,31 @@ int ensure_HOME_exists() return setenv("HOME", "/", 0); } +int close_extra_fds() +{ + // avoid leaking file descriptors + // although all fds are set to O_CLOEXEC we may leak + // interited file scriptors, so close all FDs except 0,1,2 + int fd; + DIR *dirp = NULL; + struct dirent *entry; + + fd = open("/proc/self/fd", O_RDONLY | O_CLOEXEC); + if (fd == -1) + return -1; + + dirp = fdopendir(fd); + if (dirp == NULL) + return -1; + + while ((entry = readdir(dirp)) != NULL) { + int xfd = atoi(entry->d_name); + if ((xfd > 2) && (xfd != fd)) + close(fd); + } + return closedir(dirp); +} + int main(int argc, char **argv) { /* Buffer for reading arguments and environment variables. @@ -254,6 +280,9 @@ int main(int argc, char **argv) ERROR("failed to change working directory: %s\n", strerror(errno)); + if (close_extra_fds() == -1) + ERROR("failed to close extra fds: %s\n", strerror(errno)); + if (execvp(args[0], args) == -1) { ERROR("failed to exec \"%s\": %s\n", args[0], strerror(errno)); } From 4b93a1d1794e788c74739b84f57bd8fa0a18df1d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 18 Dec 2020 21:45:37 +0100 Subject: [PATCH 133/373] create: Do not allow duplicate resource limits. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index e04f154c..46d9d911 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -224,8 +224,17 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { } } + // `man lxc.container.conf`: "A resource with no explicitly configured limitation will be inherited + // from the process starting up the container" + seenLimits := make([]string, 0, len(spec.Process.Rlimits)) for _, limit := range spec.Process.Rlimits { name := strings.TrimPrefix(strings.ToLower(limit.Type), "rlimit_") + for _, seen := range seenLimits { + if seen == name { + return fmt.Errorf("duplicate resource limit %q", limit.Type) + } + } + seenLimits = append(seenLimits, name) val := fmt.Sprintf("%d:%d", limit.Soft, limit.Hard) if err := clxc.setConfigItem("lxc.prlimit."+name, val); err != nil { return err From e534e96c813d413da011fff1375e1231f7b3c5d9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 18 Dec 2020 22:38:25 +0100 Subject: [PATCH 134/373] start: Wait for container to leave StateCreated. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index d03fe62f..0338c7da 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -304,6 +304,21 @@ func (c *Runtime) waitCreated(ctx context.Context) error { } } +func (c *Runtime) waitNot(ctx context.Context, state ContainerState) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + initState, _ := c.getContainerInitState() + if initState != state { + return nil + } + time.Sleep(time.Millisecond * 10) + } + } +} + func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { for { select { @@ -476,7 +491,8 @@ func (c *Runtime) Start(ctx context.Context) error { return errorf("failed to read from syncfifo: %w", err) } } - return nil + // wait for container state to change + return c.waitNot(ctx, StateCreated) } func (c *Runtime) syncFifoPath() string { From a12bf79b4d394b796b78362f43808b55619e3bba Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 19 Dec 2020 00:18:42 +0100 Subject: [PATCH 135/373] init: Ignore errors from close in close_extra_fds. Signed-off-by: Ruben Jenster --- cmd/init/crio-lxc-init.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/crio-lxc-init.c index d5075c23..1c85f68b 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/crio-lxc-init.c @@ -194,29 +194,33 @@ int ensure_HOME_exists() return setenv("HOME", "/", 0); } -int close_extra_fds() +/* To avoid leaking inherited file descriptors, + * all file descriptors except stdio (0,1,2) are closed. + * File descriptor leaks may lead to serious security issues. + */ +int close_extra_fds(int errfd) { - // avoid leaking file descriptors - // although all fds are set to O_CLOEXEC we may leak - // interited file scriptors, so close all FDs except 0,1,2 int fd; DIR *dirp = NULL; - struct dirent *entry; + struct dirent *entry = NULL; fd = open("/proc/self/fd", O_RDONLY | O_CLOEXEC); if (fd == -1) - return -1; + ERROR("open /proc/self/fd failed"); dirp = fdopendir(fd); if (dirp == NULL) - return -1; + ERROR("fdopendir for /proc/self/fd failed"); while ((entry = readdir(dirp)) != NULL) { int xfd = atoi(entry->d_name); if ((xfd > 2) && (xfd != fd)) close(fd); } - return closedir(dirp); + + closedir(dirp); + errno = 0; // ignore errors from close + return 0; } int main(int argc, char **argv) @@ -280,10 +284,9 @@ int main(int argc, char **argv) ERROR("failed to change working directory: %s\n", strerror(errno)); - if (close_extra_fds() == -1) + if (close_extra_fds(errfd) == -1) ERROR("failed to close extra fds: %s\n", strerror(errno)); - if (execvp(args[0], args) == -1) { + if (execvp(args[0], args) == -1) ERROR("failed to exec \"%s\": %s\n", args[0], strerror(errno)); - } } From de84a7399ed1db244840b2b980102748bfc1d254 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 19 Dec 2020 00:19:57 +0100 Subject: [PATCH 136/373] create: Small log message change. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 46d9d911..c0ada642 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -108,12 +108,11 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err return err } - clxc.Log.Info().Int("pid", cmd.Process.Pid).Msg("container process is running") + clxc.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") return CreatePidFile(clxc.PidFile, cmd.Process.Pid) } func configureContainer(clxc *Runtime, spec *specs.Spec) error { - if spec.Hostname != "" { if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { return err From 122e183416c7a70bd6c8e80959caacc20e7633e4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 00:40:26 +0100 Subject: [PATCH 137/373] readme: Update documentation to reflect latest changes. Signed-off-by: Ruben Jenster --- README.md | 85 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 31e203ee..e2693ec3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as a drop-in container runtime replacement for use by [CRI-O](https://github.com/kubernetes-sigs/cri-o). -## Installation +## Installation For the installation of the runtime see [INSTALL.md](INSTALL.md)
For the installation and initialization of a kubernetes cluster see [K8S.md](K8S.md) @@ -44,10 +44,10 @@ The runtime evaluates the flag value in the following order (lower order takes p ### Environment variables Currently you have to compile to environment file yourself.
-To get all available variables +To list all available variables: ``` -grep EnvVars cmd/*.go | grep -o CRIO_LXC_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" +grep EnvVars cmd/cli.go | grep -o CRIO_LXC_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" ``` ### Environment file @@ -62,25 +62,24 @@ In production it's recommended that you replace the environment file atomically. E.g the environment file `/etc/default/crio-lxc` could look like this: ``` -#CRIO_LXC_CONTAINER_HOOK= -#CRIO_LXC_CREATE_TIMEOUT=30s +CRIO_LXC_LOG_LEVEL=debug +CRIO_LXC_CONTAINER_LOG_LEVEL=debug +#CRIO_LXC_LOG_FILE= +#CRIO_LXC_LOG_TIMESTAMP= +#CRIO_LXC_MONITOR_CGROUP= #CRIO_LXC_INIT_CMD= #CRIO_LXC_START_CMD= -#CRIO_LXC_START_TIMEOUT=30s - -CRIO_LXC_APPARMOR=true -CRIO_LXC_CAPABILITIES=true -CRIO_LXC_CGROUP_DEVICES=true -CRIO_LXC_SECCOMP=true - -CRIO_LXC_LOG_FILE=/tmp/crio-lxc.log -CRIO_LXC_LOG_LEVEL=info -CRIO_LXC_CONTAINER_LOG_LEVEL=warn - -CRIO_LXC_MONITOR_CGROUP=crio-lxc-monitor.slice -CRIO_LXC_RUNTIME_HOOK=/usr/local/bin/crio-lxc-backup.sh -#CRIO_LXC_RUNTIME_HOOK_RUN_ALWAYS=false -#CRIO_LXC_RUNTIME_HOOK_TIMEOUT= +#CRIO_LXC_CONTAINER_HOOK= +#CRIO_LXC_APPARMOR= +#CRIO_LXC_CAPABILITIES= +#CRIO_LXC_CGROUP_DEVICES= +#CRIO_LXC_SECCOMP= +#CRIO_LXC_CREATE_TIMEOUT= +#CRIO_LXC_CREATE_HOOK=/usr/local/bin/crio-lxc-backup.sh +#CRIO_LXC_CREATE_HOOK_TIMEOUT= +#CRIO_LXC_START_TIMEOUT= +#CRIO_LXC_KILL_TIMEOUT= +#CRIO_LXC_DELETE_TIMEOUT= ``` ### Runtime (security) features @@ -99,6 +98,7 @@ Details see `crio-lxc --help` There is only a single log file for runtime and container process log output.
The log-level for the runtime and the container process can be set independently. +* containers are ephemeral, but the log file should not be * a single logfile is easy to rotate and monitor * a single logfile is easy to tail (watch for errors / events ...) * robust implementation is easy @@ -127,12 +127,11 @@ Fields that are always present: * `cmd` runtime command * `t` timestamp in UTC (format matches container process output) - Log message specific fields: * `pid` a process ID * `file` a path to a file -* `lxc.config` the key of a container process config item +* `lxc.config` the key of a container process config item * `env` the key of an environment variable @@ -140,21 +139,21 @@ Log message specific fields: Apart from the logfile following resources are useful: -* Systemd journal for cri-o and kubelet services -* `coredumpctl` if runtime or container process segfaults. +* Systemd journal for cri-o and kubelet services +* `coredumpctl` if runtime or container process segfaults. -#### Runtime Hook +#### Create Hook -If a runtime hook is defined, it is executed when the `create` command returns with an error.
-You can use the runtime hook to backup the runtime spec and container process config for further analysis.
+If a create hook is defined, it is executed before the `create` command returns.
+You can use it to backup the runtime spec and container process config for further analysis.
-The runtime hook executable must +The create hook executable must * not use the standard file descriptors (stdin/stdout/stderr) although they are nulled. -* not exceeds `CRIO_LXC_RUNTIME_HOOK_TIMEOUT` or it gets killed. +* not exceed `CRIO_LXC_CREATE_HOOK_TIMEOUT` or it is killed. * not modify/delete any resources created by the runtime or container process -The runtime hook process environment contains the following variables: +The process environment contains the following variables: * `CONTAINER_ID` the container ID * `LXC_CONFIG` the path to runtime process config @@ -162,18 +161,24 @@ The runtime hook process environment contains the following variables: * `RUNTIME_PATH` the path to the container runtime directory * `BUNDLE_PATH` the absolute path to the container bundle * `SPEC_PATH` the absolute path to the the JSON runtime spec +* `LOG_FILE` the path to the log file * `RUNTIME_ERROR` (optional) the error message if the runtime cmd return with error -Example environment of a shell script: +Example script `crio-lxc-backup.sh` that backs up any container runtime directory: ``` -SPEC_PATH=/var/run/containers/storage/overlay-containers/XXX/userdata/config.json -PWD=/ -RUNTIME_PATH=/run/crio-lxc/XXX -CONTAINER_ID=XXX -SHLVL=1 -RUNTIME_CMD=create -BUNDLE_PATH=/var/run/containers/storage/overlay-containers/XXX/userdata -LXC_CONFIG=/run/crio-lxc/XXX/config -_=/usr/bin/env +#!/bin/sh + +LOGDIR=$(dirname $LOG_FILE) +OUT=$LOGDIR/$CONTAINER_ID + +# backup container runtime directory to log directory +cp -r $RUNTIME_PATH $OUT +# copy OCI runtime spec to container runtime directory +cp $SPEC_PATH $OUT/spec.json + +# remove non `grep` friendly runtime files (symlinks, binaries, fifos) +rm $OUT/.crio-lxc/cwd +rm $OUT/.crio-lxc/init +rm $OUT/.crio-lxc/syncfifo ``` From 7e47f2ad8269fa5f818b938813186fde4485a5bf Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 01:16:19 +0100 Subject: [PATCH 138/373] cgroup: Handle disabled cgroup device controller correctly. Signed-off-by: Ruben Jenster --- lxcontainer/cgroup.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 6e74ae57..315c1ffe 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -66,13 +66,6 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { if !clxc.CgroupDevices { clxc.Log.Warn().Msg("cgroup device controller is disabled (access to all devices is granted)") - // allow read-write-mknod access to all char and block devices - if err := clxc.setConfigItem(devicesAllow, "b *:* rwm"); err != nil { - return err - } - if err := clxc.setConfigItem(devicesAllow, "c *:* rwm"); err != nil { - return err - } return nil } From 8f8dd313d28954686e530ab617b821668e2b9c0e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 01:18:57 +0100 Subject: [PATCH 139/373] create: Allow liblxc versions >= 3.1.0. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index c0ada642..e16e2140 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -32,9 +32,13 @@ func (clxc *Runtime) Create(ctx context.Context) error { if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) } - // TODO test this version + + if !lxc.VersionAtLeast(3, 1, 0) { + return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) + } + if !lxc.VersionAtLeast(4, 0, 5) { - return errorf("liblxc runtime version is %s, but >= 4.0.5 is required", lxc.Version()) + clxc.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } spec, err := clxc.ReadSpec() From 078812638d64cfb6f2bcfbb2a6e4de95d70e4c36 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 01:24:00 +0100 Subject: [PATCH 140/373] create: Rename Runtime instance variable. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 130 +++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index e16e2140..8e8e1e88 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -16,12 +16,12 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -func (clxc *Runtime) Create(ctx context.Context) error { - if clxc.runtimePathExists() { +func (c *Runtime) Create(ctx context.Context) error { + if c.runtimePathExists() { return ErrExist } - err := canExecute(clxc.StartCommand, clxc.ContainerHook, clxc.InitCommand) + err := canExecute(c.StartCommand, c.ContainerHook, c.InitCommand) if err != nil { return errorf("access check failed: %w", err) } @@ -38,39 +38,39 @@ func (clxc *Runtime) Create(ctx context.Context) error { } if !lxc.VersionAtLeast(4, 0, 5) { - clxc.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) + c.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } - spec, err := clxc.ReadSpec() + spec, err := c.ReadSpec() if err != nil { return errorf("failed to load container spec from bundle: %w", err) } - err = clxc.createContainer(spec) + err = c.createContainer(spec) if err != nil { return errorf("failed to create container: %w", err) } - if err := configureContainer(clxc, spec); err != nil { + if err := configureContainer(c, spec); err != nil { return errorf("failed to configure container: %w", err) } - if err := clxc.runStartCmd(ctx, spec); err != nil { + if err := c.runStartCmd(ctx, spec); err != nil { return errorf("failed to run container process: %w", err) } return nil } -func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { +func (c *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { // #nosec - cmd := exec.Command(clxc.StartCommand, clxc.Container.Name(), clxc.RuntimeRoot, clxc.ConfigFilePath()) + cmd := exec.Command(c.StartCommand, c.Container.Name(), c.RuntimeRoot, c.ConfigFilePath()) cmd.Env = []string{} - cmd.Dir = clxc.RuntimePath() + cmd.Dir = c.RuntimePath() - if clxc.ConsoleSocket == "" && !spec.Process.Terminal { + if c.ConsoleSocket == "" && !spec.Process.Terminal { // Inherit stdio from calling process (conmon). // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc - if err := clxc.setConfigItem("lxc.console.path", "none"); err != nil { + if err := c.setConfigItem("lxc.console.path", "none"); err != nil { return err } cmd.Stdin = os.Stdin @@ -78,13 +78,13 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err cmd.Stderr = os.Stderr } - if err := clxc.saveConfig(); err != nil { + if err := c.saveConfig(); err != nil { return err } - clxc.Log.Debug().Msg("starting lxc monitor process") - if clxc.ConsoleSocket != "" { - err = runStartCmdConsole(ctx, cmd, clxc.ConsoleSocket) + c.Log.Debug().Msg("starting lxc monitor process") + if c.ConsoleSocket != "" { + err = runStartCmdConsole(ctx, cmd, c.ConsoleSocket) } else { err = cmd.Start() } @@ -100,25 +100,25 @@ func (clxc *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err err // NOTE this goroutine may leak until crio-lxc is terminated ps, err := cmd.Process.Wait() if err != nil { - clxc.Log.Error().Err(err).Msg("failed to wait for start process") + c.Log.Error().Err(err).Msg("failed to wait for start process") } else { - clxc.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") + c.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") } cancel() }() - clxc.Log.Debug().Msg("waiting for init") - if err := clxc.waitCreated(ctx); err != nil { + c.Log.Debug().Msg("waiting for init") + if err := c.waitCreated(ctx); err != nil { return err } - clxc.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") - return CreatePidFile(clxc.PidFile, cmd.Process.Pid) + c.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") + return CreatePidFile(c.PidFile, cmd.Process.Pid) } -func configureContainer(clxc *Runtime, spec *specs.Spec) error { +func configureContainer(c *Runtime, spec *specs.Spec) error { if spec.Hostname != "" { - if err := clxc.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { + if err := c.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { return err } @@ -130,99 +130,99 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { } } - if err := configureRootfs(clxc, spec); err != nil { + if err := configureRootfs(c, spec); err != nil { return err } - if err := configureInit(clxc, spec); err != nil { + if err := configureInit(c, spec); err != nil { return err } - if err := configureMounts(clxc, spec); err != nil { + if err := configureMounts(c, spec); err != nil { return err } - if err := configureReadonlyPaths(clxc, spec); err != nil { + if err := configureReadonlyPaths(c, spec); err != nil { return err } - if err := configureNamespaces(clxc, spec.Linux.Namespaces); err != nil { + if err := configureNamespaces(c, spec.Linux.Namespaces); err != nil { return fmt.Errorf("failed to configure namespaces: %w", err) } if spec.Process.OOMScoreAdj != nil { - if err := clxc.setConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *spec.Process.OOMScoreAdj)); err != nil { + if err := c.setConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *spec.Process.OOMScoreAdj)); err != nil { return err } } if spec.Process.NoNewPrivileges { - if err := clxc.setConfigItem("lxc.no_new_privs", "1"); err != nil { + if err := c.setConfigItem("lxc.no_new_privs", "1"); err != nil { return err } } - if clxc.Apparmor { - if err := configureApparmor(clxc, spec); err != nil { + if c.Apparmor { + if err := configureApparmor(c, spec); err != nil { return fmt.Errorf("failed to configure apparmor: %w", err) } } else { - clxc.Log.Warn().Msg("apparmor is disabled (unconfined)") + c.Log.Warn().Msg("apparmor is disabled (unconfined)") } - if clxc.Seccomp { + if c.Seccomp { if spec.Linux.Seccomp == nil || len(spec.Linux.Seccomp.Syscalls) == 0 { } else { - profilePath := clxc.RuntimePath("seccomp.conf") + profilePath := c.RuntimePath("seccomp.conf") if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { return err } - if err := clxc.setConfigItem("lxc.seccomp.profile", profilePath); err != nil { + if err := c.setConfigItem("lxc.seccomp.profile", profilePath); err != nil { return err } } } else { - clxc.Log.Warn().Msg("seccomp is disabled") + c.Log.Warn().Msg("seccomp is disabled") } - if clxc.Capabilities { - if err := configureCapabilities(clxc, spec); err != nil { + if c.Capabilities { + if err := configureCapabilities(c, spec); err != nil { return fmt.Errorf("failed to configure capabilities: %w", err) } } else { - clxc.Log.Warn().Msg("capabilities are disabled") + c.Log.Warn().Msg("capabilities are disabled") } - if err := ensureDefaultDevices(clxc, spec); err != nil { + if err := ensureDefaultDevices(c, spec); err != nil { return fmt.Errorf("failed to add default devices: %w", err) } - if err := writeDevices(clxc.RuntimePath("devices.txt"), spec); err != nil { + if err := writeDevices(c.RuntimePath("devices.txt"), spec); err != nil { return fmt.Errorf("failed to create devices.txt: %w", err) } - if err := writeMasked(clxc.RuntimePath("masked.txt"), spec); err != nil { + if err := writeMasked(c.RuntimePath("masked.txt"), spec); err != nil { return fmt.Errorf("failed to create masked.txt: %w", err) } // pass context information as environment variables to hook scripts - if err := clxc.setConfigItem("lxc.hook.version", "1"); err != nil { + if err := c.setConfigItem("lxc.hook.version", "1"); err != nil { return err } - if err := clxc.setConfigItem("lxc.hook.mount", clxc.ContainerHook); err != nil { + if err := c.setConfigItem("lxc.hook.mount", c.ContainerHook); err != nil { return err } - if err := clxc.configureCgroupPath(); err != nil { + if err := c.configureCgroupPath(); err != nil { return fmt.Errorf("failed to configure cgroups path: %w", err) } - if err := configureCgroup(clxc, spec); err != nil { + if err := configureCgroup(c, spec); err != nil { return fmt.Errorf("failed to configure cgroups: %w", err) } for key, val := range spec.Linux.Sysctl { - if err := clxc.setConfigItem("lxc.sysctl."+key, val); err != nil { + if err := c.setConfigItem("lxc.sysctl."+key, val); err != nil { return err } } @@ -239,23 +239,23 @@ func configureContainer(clxc *Runtime, spec *specs.Spec) error { } seenLimits = append(seenLimits, name) val := fmt.Sprintf("%d:%d", limit.Soft, limit.Hard) - if err := clxc.setConfigItem("lxc.prlimit."+name, val); err != nil { + if err := c.setConfigItem("lxc.prlimit."+name, val); err != nil { return err } } return nil } -func configureRootfs(clxc *Runtime, spec *specs.Spec) error { - if err := clxc.setConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { +func configureRootfs(c *Runtime, spec *specs.Spec) error { + if err := c.setConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { return err } - if err := clxc.setConfigItem("lxc.rootfs.managed", "0"); err != nil { + if err := c.setConfigItem("lxc.rootfs.managed", "0"); err != nil { return err } // Resources not created by the container runtime MUST NOT be deleted by it. - if err := clxc.setConfigItem("lxc.ephemeral", "0"); err != nil { + if err := c.setConfigItem("lxc.ephemeral", "0"); err != nil { return err } @@ -266,40 +266,40 @@ func configureRootfs(clxc *Runtime, spec *specs.Spec) error { if spec.Root.Readonly { rootfsOptions = append(rootfsOptions, "ro") } - if err := clxc.setConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { + if err := c.setConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { return err } return nil } -func configureReadonlyPaths(clxc *Runtime, spec *specs.Spec) error { - rootmnt := clxc.getConfigItem("lxc.rootfs.mount") +func configureReadonlyPaths(c *Runtime, spec *specs.Spec) error { + rootmnt := c.getConfigItem("lxc.rootfs.mount") if rootmnt == "" { return fmt.Errorf("lxc.rootfs.mount unavailable") } for _, p := range spec.Linux.ReadonlyPaths { mnt := fmt.Sprintf("%s %s %s %s", filepath.Join(rootmnt, p), strings.TrimPrefix(p, "/"), "bind", "bind,ro,optional") - if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { + if err := c.setConfigItem("lxc.mount.entry", mnt); err != nil { return fmt.Errorf("failed to make path readonly: %w", err) } } return nil } -func configureApparmor(clxc *Runtime, spec *specs.Spec) error { +func configureApparmor(c *Runtime, spec *specs.Spec) error { // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. aaprofile := spec.Process.ApparmorProfile if aaprofile == "" { aaprofile = "unconfined" } - return clxc.setConfigItem("lxc.apparmor.profile", aaprofile) + return c.setConfigItem("lxc.apparmor.profile", aaprofile) } // configureCapabilities configures the linux capabilities / privileges granted to the container processes. // See `man lxc.container.conf` lxc.cap.drop and lxc.cap.keep for details. // https://blog.container-solutions.com/linux-capabilities-in-practice // https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work -func configureCapabilities(clxc *Runtime, spec *specs.Spec) error { +func configureCapabilities(c *Runtime, spec *specs.Spec) error { keepCaps := "none" if spec.Process.Capabilities != nil { var caps []string @@ -310,7 +310,7 @@ func configureCapabilities(clxc *Runtime, spec *specs.Spec) error { keepCaps = strings.Join(caps, " ") } - return clxc.setConfigItem("lxc.cap.keep", keepCaps) + return c.setConfigItem("lxc.cap.keep", keepCaps) } func isDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) bool { @@ -341,9 +341,9 @@ func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64 // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(clxc *Runtime, spec *specs.Spec) error { +func ensureDefaultDevices(c *Runtime, spec *specs.Spec) error { // make sure autodev is disabled - if err := clxc.setConfigItem("lxc.autodev", "0"); err != nil { + if err := c.setConfigItem("lxc.autodev", "0"); err != nil { return err } From d9673c906b267e5dbacc0ffbe25c41ccc94f6dea Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 01:35:48 +0100 Subject: [PATCH 141/373] readme: Add note about AdditionalGids until it's merged to master (remove this once merged to master). Signed-off-by: Ruben Jenster --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e2693ec3..3f9d66b9 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,15 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S * Only cgroupv2 unified cgroup hierarchy is supported. * A recent kernel > 5.8 is required for full cgroup support. * Cgroup resource limits are not implemented yet. This will change soon. -* runtime spec `additionalGroups` requires liblxc and go-lxc development version + +### AdditionalGids + +* https://github.com/lxc/lxc/pull/3575 + +Additional group ids for the container's process require the following development repositories: + +* https://github.com/Drachenfels-GmbH/lxc +* https://github.com/Drachenfels-GmbH/go-lxc ## Configuration From b54ab139d00768caf2050f6f4775501bfd18d657 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 09:20:05 +0100 Subject: [PATCH 142/373] k8s: Fix installation script. Upgrade to v1.19.6 Signed-off-by: Ruben Jenster --- K8S.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/K8S.md b/K8S.md index e819ca95..04621cc1 100644 --- a/K8S.md +++ b/K8S.md @@ -1,6 +1,6 @@ ## kubernetes -The following skript downloads kubernetes [v1.19.4](https://dl.k8s.io/v1.19.4) and installs it to `/usr/local/bin`.
+The following skript downloads kubernetes [v1.19.6](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.19.md#v1196) and installs it to `/usr/local/bin`.
You have to create the `kubelet.service` and `10-kubeadm.conf` before running the script. ```sh @@ -15,12 +15,12 @@ You have to create the `kubelet.service` and `10-kubeadm.conf` before running th # * run this script again ARCH="linux-amd64" -RELEASE="1.19.4" +RELEASE="1.19.6" ARCHIVE=kubernetes-server-$ARCH.tar.gz -CHECKSUM="fc9de14121af682af167ef99ce8a3803c25e92ef4739ed7eb592eadb30086b2cb9ede51d57816d1c3835f6202753d726eba804b839ae9cd516eff4e94c81c189" +CHECKSUM="126f6ab16d9e007ff75c58fab20fbaf4c6ff16212b8bbf5e71105f0f3611867ad1410ee05cd39b4e4e6cb3b6313fcff4b12ec91fa430b38f29d72221dda8c624" DESTDIR="/usr/local/bin" -[ -e "$ARCHIVE" ] || wget https://dl.k8s.io/v$RELEASE/$FILE +[ -e "$ARCHIVE" ] || wget https://dl.k8s.io/v$RELEASE/$ARCHIVE echo "$CHECKSUM $ARCHIVE" | sha512sum -c || exit 1 @@ -98,7 +98,7 @@ kind: KubeletConfiguration cgroupDriver: systemd --- kind: ClusterConfiguration -kubernetesVersion: v1.19.4 +kubernetesVersion: v1.19.6 apiVersion: kubeadm.k8s.io/v1beta2 apiServer: timeoutForControlPlane: 4m0s From 27fb17f5c5271fc2c0a27d99633fc47ba196e94e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 09:32:28 +0100 Subject: [PATCH 143/373] readme: Enable syntax highlighting for examples. Signed-off-by: Ruben Jenster --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f9d66b9..7371619c 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ In production it's recommended that you replace the environment file atomically. E.g the environment file `/etc/default/crio-lxc` could look like this: -``` +```sh CRIO_LXC_LOG_LEVEL=debug CRIO_LXC_CONTAINER_LOG_LEVEL=debug #CRIO_LXC_LOG_FILE= @@ -174,7 +174,7 @@ The process environment contains the following variables: Example script `crio-lxc-backup.sh` that backs up any container runtime directory: -``` +```sh #!/bin/sh LOGDIR=$(dirname $LOG_FILE) From 36a0ad2a4075d5008daa7037cd06c767532904f5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 22:44:29 +0100 Subject: [PATCH 144/373] runtime: Upgrade runtime-spec to v1.0.3-0.20200929063507-e6143ca7d51d Signed-off-by: Ruben Jenster --- go.mod | 2 +- go.sum | 4 ++-- lxcontainer/runtime.go | 53 ++++++++++++++---------------------------- 3 files changed, 20 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index aa549639..2ce9bd50 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/lxc/crio-lxc require ( github.com/creack/pty v1.1.11 - github.com/opencontainers/runtime-spec v1.0.2 + github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/rs/zerolog v1.20.0 github.com/stretchr/testify v1.3.0 github.com/urfave/cli/v2 v2.3.0 diff --git a/go.sum b/go.sum index 753e2c06..675c6be8 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 0338c7da..dd6f330e 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -17,24 +17,6 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -// ContainerState represents the state of a container. -type ContainerState string - -const ( - // StateCreating indicates that the container is being created - StateCreating ContainerState = "creating" - - // StateCreated indicates that the runtime has finished the create operation - StateCreated ContainerState = "created" - - // StateRunning indicates that the container process has executed the - // user-specified program but has not exited - StateRunning ContainerState = "running" - - // StateStopped indicates that the container process has exited - StateStopped ContainerState = "stopped" -) - var ErrNotExist = fmt.Errorf("container does not exist") var ErrExist = fmt.Errorf("container already exists") @@ -296,7 +278,7 @@ func (c *Runtime) waitCreated(ctx context.Context) error { if err != nil { return err } - if initState == StateCreated { + if initState == specs.StateCreated { return nil } return fmt.Errorf("unexpected init state %q", initState) @@ -304,7 +286,7 @@ func (c *Runtime) waitCreated(ctx context.Context) error { } } -func (c *Runtime) waitNot(ctx context.Context, state ContainerState) error { +func (c *Runtime) waitNot(ctx context.Context, state specs.ContainerState) error { for { select { case <-ctx.Done(): @@ -333,44 +315,44 @@ func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { } } -func (c *Runtime) getContainerState() (ContainerState, error) { +func (c *Runtime) getContainerState() (specs.ContainerState, error) { state := c.Container.State() switch state { case lxc.STOPPED: - return StateStopped, nil + return specs.StateStopped, nil case lxc.STARTING: - return StateCreating, nil + return specs.StateCreating, nil case lxc.RUNNING, lxc.STOPPING, lxc.ABORTING, lxc.FREEZING, lxc.FROZEN, lxc.THAWED: return c.getContainerInitState() default: - return StateStopped, fmt.Errorf("unsupported lxc container state %q", state) + return specs.StateStopped, fmt.Errorf("unsupported lxc container state %q", state) } } // getContainerInitState returns the detailed state of the container init process. // This should be called if the container is in state lxc.RUNNING. // On error the caller should call getContainerState() again -func (c *Runtime) getContainerInitState() (ContainerState, error) { +func (c *Runtime) getContainerInitState() (specs.ContainerState, error) { initPid := c.Container.InitPid() if initPid < 1 { - return StateStopped, nil + return specs.StateStopped, nil } cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := ioutil.ReadFile(cmdlinePath) if os.IsNotExist(err) { // init process died or returned - return StateStopped, nil + return specs.StateStopped, nil } if err != nil { // it's a serious error if cmdlinePath exists but can't be read - return StateStopped, err + return specs.StateStopped, err } initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) if string(cmdline) == initCmdline { - return StateCreated, nil + return specs.StateCreated, nil } - return StateRunning, nil + return specs.StateRunning, nil } func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { @@ -474,8 +456,8 @@ func (c *Runtime) Start(ctx context.Context) error { if err != nil { return errorf("failed to get container state: %w", err) } - if state != StateCreated { - return fmt.Errorf("invalid container state. expected %q, but was %q", StateCreated, state) + if state != specs.StateCreated { + return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state) } done := make(chan error) @@ -492,7 +474,7 @@ func (c *Runtime) Start(ctx context.Context) error { } } // wait for container state to change - return c.waitNot(ctx, StateCreated) + return c.waitNot(ctx, specs.StateCreated) } func (c *Runtime) syncFifoPath() string { @@ -560,13 +542,12 @@ func (c *Runtime) State() (*specs.State, error) { Annotations: c.Annotations, } - s, err := c.getContainerState() - state.Status = string(s) + state.Status, err = c.getContainerState() if err != nil { return nil, errorf("failed to get container state: %w", err) } - c.Log.Info().Int("pid", state.Pid).Str("status", state.Status).Msg("container state") + c.Log.Info().Int("pid", state.Pid).Str("status", string(state.Status)).Msg("container state") return state, nil } From 65d3cb074ecd649d823c8f68bb2f19bfd43e79f5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 21 Dec 2020 22:46:40 +0100 Subject: [PATCH 145/373] seccomp: Fix rule generation for action SCMP_ACT_ERRNO. Signed-off-by: Ruben Jenster --- lxcontainer/seccomp.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lxcontainer/seccomp.go b/lxcontainer/seccomp.go index 53e76edb..90b6a92b 100644 --- a/lxcontainer/seccomp.go +++ b/lxcontainer/seccomp.go @@ -107,6 +107,15 @@ func writeSeccompSyscall(w *bufio.Writer, sc specs.LinuxSyscall) error { if !ok { return fmt.Errorf("unsupported seccomp action: %s", sc.Action) } + + if sc.Action == specs.ActErrno { + var ret uint = 0 + if sc.ErrnoRet != nil { + ret = *sc.ErrnoRet + } + action = fmt.Sprintf("%s %d", action, ret) + } + if len(sc.Args) == 0 { fmt.Fprintf(w, "%s %s\n", name, action) } else { From 1d7692495ab821a72ff2559b22b07e33f53a3659 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 22 Dec 2020 10:18:07 +0100 Subject: [PATCH 146/373] docs: Upgrade kubernetes version to 1.20.1. Fix conmon version. Signed-off-by: Ruben Jenster --- INSTALL.md | 8 ++++---- K8S.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 0098b977..1552b62f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -39,8 +39,8 @@ pacman -Sy conntrack-tools ebtables jq ## runtime dependencies * [lxc](https://github.com/lxc/lxc.git) >= 4.0.5, master recommened -* [conmon/pinns](https://github.com/containers/conmon.git) v2.0.2 -* [cri-o](https://github.com/cri-o/cri-o.git) release-1.19 +* [conmon/pinns](https://github.com/containers/conmon.git) v2.0.22 +* [cri-o](https://github.com/cri-o/cri-o.git) release-1.20 By default everything is installed to `/usr/local` @@ -80,7 +80,7 @@ Keep in mind that you have to change the `INSTALL_PREFIX` in the crio install sc ```sh git clone https://github.com/containers/conmon.git cd conmon -git reset --hard v2.0.2 +git reset --hard v2.0.22 make clean make install ``` @@ -91,7 +91,7 @@ make install #!/bin/sh git clone https://github.com/cri-o/cri-o.git cd cri-o -git reset --hard origin/release-1.19 +git reset --hard origin/release-1.20 make install PREFIX=/usr/local diff --git a/K8S.md b/K8S.md index 04621cc1..ca680b13 100644 --- a/K8S.md +++ b/K8S.md @@ -1,6 +1,6 @@ ## kubernetes -The following skript downloads kubernetes [v1.19.6](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.19.md#v1196) and installs it to `/usr/local/bin`.
+The following skript downloads kubernetes [v1.20.1](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#v1201) and installs it to `/usr/local/bin`.
You have to create the `kubelet.service` and `10-kubeadm.conf` before running the script. ```sh @@ -15,9 +15,9 @@ You have to create the `kubelet.service` and `10-kubeadm.conf` before running th # * run this script again ARCH="linux-amd64" -RELEASE="1.19.6" +RELEASE="1.20.1" ARCHIVE=kubernetes-server-$ARCH.tar.gz -CHECKSUM="126f6ab16d9e007ff75c58fab20fbaf4c6ff16212b8bbf5e71105f0f3611867ad1410ee05cd39b4e4e6cb3b6313fcff4b12ec91fa430b38f29d72221dda8c624" +CHECKSUM="fb56486a55dbf7dbacb53b1aaa690bae18d33d244c72a1e2dc95fb0fcce45108c44ba79f8fa04f12383801c46813dc33d2d0eb2203035cdce1078871595e446e" DESTDIR="/usr/local/bin" [ -e "$ARCHIVE" ] || wget https://dl.k8s.io/v$RELEASE/$ARCHIVE From e388cc2d8bfcf408aa8ea2848dc035d1435a933a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 26 Dec 2020 19:01:54 +0100 Subject: [PATCH 147/373] exec: Show error message if exec failed. Signed-off-by: Ruben Jenster --- cmd/cli.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 9a9063c8..24dbc734 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -213,12 +213,13 @@ func main() { if err != nil { clxc.Log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") clxc.Release() + // write diagnostics message to stderr for crio/kubelet + println(err.Error()) + // exit with exit status of executed command if err, yes := err.(execError); yes { os.Exit(err.ExitStatus()) } - // write diagnostics message to stderr for crio/kubelet - println(err.Error()) os.Exit(1) } From 26b07882f9189abe48c2229c4bae73414548f34e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 26 Dec 2020 19:48:18 +0100 Subject: [PATCH 148/373] exec: Improve error message for exec failures. Signed-off-by: Ruben Jenster --- cmd/cli.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 24dbc734..9b318e47 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -217,8 +217,9 @@ func main() { println(err.Error()) // exit with exit status of executed command - if err, yes := err.(execError); yes { - os.Exit(err.ExitStatus()) + var errExec execError + if errors.As(err, &errExec) { + os.Exit(errExec.exitStatus()) } os.Exit(1) } @@ -452,12 +453,24 @@ var execCmd = cli.Command{ type execError int -func (e execError) ExitStatus() int { +func (e execError) exitStatus() int { return int(e) } func (e execError) Error() string { - return fmt.Sprintf("exec cmd exited with status %d", int(e)) + // liblxc remaps execvp exit codes to shell exit codes. + // FIXME This is undocumented behaviour lxc/src/lxc/attach.c:lxc_attach_run_command + // https://github.com/lxc/go-lxc/blob/d1943fb48dc73ef5cbc0ef43ed585420f7b2eb3a/container.go#L1370 + // RunCommandStatus returns with exitCode 126 or 127 but without error, so it is not possible to determine + // whether this is the exit code from the command itself (e.g a shell itself) or from liblxc exec. + switch int(e) { + case 126: + return "can not execute file: file header not recognized" + case 127: + return "executable file not found in $PATH" + default: + return fmt.Sprintf("cmd execution failed with exit status %d", e.exitStatus) + } } func doExec(ctx *cli.Context) error { From be4d80d18fe3dc874f4d187017fab8d4c3f099a3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 25 Jan 2021 15:15:14 +0100 Subject: [PATCH 149/373] k8s docs: Upgrade to k8s 1.20.2. Fixes version mismatch and invalid checksum. Fixes #8 Signed-off-by: Ruben Jenster --- K8S.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/K8S.md b/K8S.md index ca680b13..a66d27bf 100644 --- a/K8S.md +++ b/K8S.md @@ -1,6 +1,6 @@ ## kubernetes -The following skript downloads kubernetes [v1.20.1](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#v1201) and installs it to `/usr/local/bin`.
+The following skript downloads kubernetes [v1.20.2](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#v1202) and installs it to `/usr/local/bin`.
You have to create the `kubelet.service` and `10-kubeadm.conf` before running the script. ```sh @@ -15,9 +15,9 @@ You have to create the `kubelet.service` and `10-kubeadm.conf` before running th # * run this script again ARCH="linux-amd64" -RELEASE="1.20.1" +RELEASE="1.20.2" ARCHIVE=kubernetes-server-$ARCH.tar.gz -CHECKSUM="fb56486a55dbf7dbacb53b1aaa690bae18d33d244c72a1e2dc95fb0fcce45108c44ba79f8fa04f12383801c46813dc33d2d0eb2203035cdce1078871595e446e" +CHECKSUM="65abf178782e43bc21e8455ffbfdadf6064dbeae3ff704ccf9e13e8acee18235c280b06778e5de4bd702f5507e1870fe38c561366d125ef4f821ed7aa46e9f45" DESTDIR="/usr/local/bin" [ -e "$ARCHIVE" ] || wget https://dl.k8s.io/v$RELEASE/$ARCHIVE @@ -98,7 +98,7 @@ kind: KubeletConfiguration cgroupDriver: systemd --- kind: ClusterConfiguration -kubernetesVersion: v1.19.6 +kubernetesVersion: v1.20.2 apiVersion: kubeadm.k8s.io/v1beta2 apiServer: timeoutForControlPlane: 4m0s From 9711fb3248d07534fde2fe23b30bd6a09b58331d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 25 Jan 2021 16:07:11 +0100 Subject: [PATCH 150/373] k8s docs: Document how to fix kubeadm preflight check errors. Refs #8. Signed-off-by: Ruben Jenster --- K8S.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/K8S.md b/K8S.md index a66d27bf..717cacec 100644 --- a/K8S.md +++ b/K8S.md @@ -118,3 +118,40 @@ networking: scheduler: {} controlPlaneEndpoint: "${HOSTIP}:6443" ``` + +#### preflight issues + +There are some `preflight` checks that might fail once you start kubeadm. + +##### install cri-tools + +``` +[ERROR FileExisting-crictl]: crictl not found in system path +``` + +Please install the `cri-tools` from https://github.com/kubernetes-sigs/cri-tools/releases to your `PATH` e.g [cri-tools v1.20.0](https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.20.0/crictl-v1.20.0-linux-amd64.tar.gz) + + +##### load br-netfilter + +``` +[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables does not exist +``` + +You must load the `br-netfilter` kernel module. To do that automatically on startup add it to `/etc/modules-load.d` e.g : + +``` +echo 'br-netfilter' > /etc/modules-load.d/kubelet.conf +``` + +##### enable IP forwarding +``` +[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1 +```` + +IP forwarding must be enabled. E.g + +``` +echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-kubelet.conf +sysctl --system +``` From e3f5cce194c0eae61ffb85ace91a901204eccd2d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 3 Feb 2021 15:29:33 +0100 Subject: [PATCH 151/373] config: Don't fail if environment file does not exist. Refs #8 Signed-off-by: Ruben Jenster --- cmd/util.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/util.go b/cmd/util.go index d57ead1a..8239aadd 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -19,6 +19,15 @@ func setEnv(key, val string, overwrite bool) error { } func loadEnvFile(envFile string) (map[string]string, error) { + // don't fail if environment file does not exist + _, err := os.Stat(envFile) + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + // #nosec data, err := ioutil.ReadFile(envFile) if err != nil { From 87a7b3a36f6ecc5e8519d57f4dc5363d5a70f22a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 1 Feb 2021 15:03:25 +0100 Subject: [PATCH 152/373] build: Treat all compiler warnings as errors. Signed-off-by: Ruben Jenster --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index cfe35792..e723f57d 100644 --- a/Makefile +++ b/Makefile @@ -22,16 +22,16 @@ crio-lxc: $(GO_SRC) Makefile go.mod go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c - $(CC) -Wall -Wpedantic $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? + $(CC) -Werror -Wpedantic $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? crio-lxc-init: cmd/init/crio-lxc-init.c - /usr/local/musl/bin/musl-gcc -Wall -Wpedantic -static -g -o $@ $? - #musl-gcc -g3 -Wall -static $? -o $@ + /usr/local/musl/bin/musl-gcc -Werror -Wpedantic -static -g -o $@ $? + #musl-gcc -g3 -Werror -static $? -o $@ # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null crio-lxc-container-hook: cmd/container-hook/hook.c - musl-gcc -DDEBUG -Wall -Wpedantic $? -o $@ + musl-gcc -DDEBUG -Werror -Wpedantic $? -o $@ # make test TEST=basic will run only the basic test. .PHONY: check From eecd3668018d424e3ae257add18adfb86299028c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 3 Feb 2021 14:55:05 +0100 Subject: [PATCH 153/373] lxc: Use comma as separator for lxc.config.groups Signed-off-by: Ruben Jenster --- lxcontainer/init.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 21717d74..0b44cb07 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -158,7 +158,7 @@ func configureInitUser(clxc *Runtime, spec *specs.Spec) error { var b strings.Builder for i, gid := range spec.Process.User.AdditionalGids { if i > 0 { - b.WriteByte(' ') + b.WriteByte(',') } fmt.Fprintf(&b, "%d", gid) } From cbdc26f97e8419a0f676269411975e3bd1d4995e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 5 Feb 2021 21:40:14 +0100 Subject: [PATCH 154/373] Fix tests and compiler warnings. Signed-off-by: Ruben Jenster --- cmd/cli.go | 4 ++-- cmd/{util.go => utils.go} | 0 cmd/utils_test.go | 32 ++++++++++++++++++++++++++++++++ lxcontainer/cgroup_test.go | 32 -------------------------------- lxcontainer/namespaces.go | 2 +- 5 files changed, 35 insertions(+), 35 deletions(-) rename cmd/{util.go => utils.go} (100%) create mode 100644 cmd/utils_test.go diff --git a/cmd/cli.go b/cmd/cli.go index 9b318e47..d4d48dcf 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -168,7 +168,7 @@ func main() { if env != nil { for key, val := range env { if err := setEnv(key, val, false); err != nil { - err = fmt.Errorf("failed to set environment variable \"%s=%s\": %w", err) + err = fmt.Errorf("failed to set environment variable \"%s=%s\": %w", key, val, err) println(err.Error()) os.Exit(1) } @@ -469,7 +469,7 @@ func (e execError) Error() string { case 127: return "executable file not found in $PATH" default: - return fmt.Sprintf("cmd execution failed with exit status %d", e.exitStatus) + return fmt.Sprintf("cmd execution failed with exit status %d", e.exitStatus()) } } diff --git a/cmd/util.go b/cmd/utils.go similarity index 100% rename from cmd/util.go rename to cmd/utils.go diff --git a/cmd/utils_test.go b/cmd/utils_test.go new file mode 100644 index 00000000..447cb9e9 --- /dev/null +++ b/cmd/utils_test.go @@ -0,0 +1,32 @@ +package main + +import ( + "testing" + + "golang.org/x/sys/unix" + + "github.com/stretchr/testify/require" +) + +func TestParseSignal(t *testing.T) { + sig := parseSignal("9") + require.Equal(t, unix.SIGKILL, sig) + + sig = parseSignal("kill") + require.Equal(t, unix.SIGKILL, sig) + + sig = parseSignal("sigkill") + require.Equal(t, unix.SIGKILL, sig) + + sig = parseSignal("KILL") + require.Equal(t, unix.SIGKILL, sig) + + sig = parseSignal("SIGKILL") + require.Equal(t, unix.SIGKILL, sig) + + sig = parseSignal("SIGNOTEXIST") + require.Equal(t, unix.Signal(0), sig) + + sig = parseSignal("66") + require.Equal(t, unix.Signal(66), sig) +} diff --git a/lxcontainer/cgroup_test.go b/lxcontainer/cgroup_test.go index f10bbbf9..912598a8 100644 --- a/lxcontainer/cgroup_test.go +++ b/lxcontainer/cgroup_test.go @@ -3,8 +3,6 @@ package lxcontainer import ( "testing" - "golang.org/x/sys/unix" - "github.com/stretchr/testify/require" ) @@ -13,33 +11,3 @@ func TestParseSystemCgroupPath(t *testing.T) { cg := parseSystemdCgroupPath(s) require.Equal(t, "kubepods.slice/kubepods-burstable.slice/kubepods-burstable-123.slice/crio-ABC.scope", cg) } - -func TestParseSignal(t *testing.T) { - sig, err := parseSignal("9") - require.NoError(t, err) - require.Equal(t, unix.SIGKILL, sig) - - sig, err = parseSignal("kill") - require.NoError(t, err) - require.Equal(t, unix.SIGKILL, sig) - - sig, err = parseSignal("sigkill") - require.NoError(t, err) - require.Equal(t, unix.SIGKILL, sig) - - sig, err = parseSignal("KILL") - require.NoError(t, err) - require.Equal(t, unix.SIGKILL, sig) - - sig, err = parseSignal("SIGKILL") - require.NoError(t, err) - require.Equal(t, unix.SIGKILL, sig) - - sig, err = parseSignal("SIGNOTEXIST") - require.Error(t, err) - require.Equal(t, sigzero, sig) - - sig, err = parseSignal("66") - require.Error(t, err) - require.Equal(t, sigzero, sig) -} diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index afb35654..7d96e4f6 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -100,7 +100,7 @@ func setHostname(nsPath string, hostname string) error { f, err := os.Open(nsPath) if err != nil { - return fmt.Errorf("failed to open container uts namespace: %w", nsPath, err) + return fmt.Errorf("failed to open container uts namespace %q: %w", nsPath, err) } // #nosec defer f.Close() From 3ae024593fbfa405990902ac8643d58d5fa536c1 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 5 Feb 2021 21:42:22 +0100 Subject: [PATCH 155/373] Use upstream go-lxc after merge of support for additional groups ids. Remove unused test dependencies. Signed-off-by: Ruben Jenster --- go.mod | 10 ++-------- go.sum | 9 +++++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2ce9bd50..8da0b70c 100644 --- a/go.mod +++ b/go.mod @@ -6,14 +6,8 @@ require ( github.com/rs/zerolog v1.20.0 github.com/stretchr/testify v1.3.0 github.com/urfave/cli/v2 v2.3.0 - golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 - gopkg.in/lxc/go-lxc.v2 v2.0.0 + golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 + gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 ) -replace gopkg.in/lxc/go-lxc.v2 v2.0.0 => github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef - -replace github.com/vbatts/go-mtree v0.4.4 => github.com/vbatts/go-mtree v0.4.5-0.20190122034725-8b6de6073c1a - -replace github.com/openSUSE/umoci v0.4.4 => github.com/tych0/umoci v0.1.1-0.20190402232331-556620754fb1 - go 1.13 diff --git a/go.sum b/go.sum index 675c6be8..a976c6f9 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef h1:t2Xd3jCGWbSXE9HGhN7acei0a9Co9TiqlhaSD6Cec0I= -github.com/Drachenfels-GmbH/go-lxc v0.0.0-20201106192530-079aead12fef/go.mod h1:BpD4MbHBk1uaTubH9ItkAJxE84u7J+IohxyP40SJ9hg= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -29,10 +28,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM= -golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 h1:YcCjv1g/OoEJ93hK3p+5MhPyuIMD9FwOYF5f4D7rNKk= +gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From d9b76eb180c2157aed524ad262a30b0001f5ce62 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Feb 2021 13:13:12 +0100 Subject: [PATCH 156/373] doc: Update documentation. Remove AdditionalGids section since lxc.init.groups was merged into lxc master and go-lxc. Signed-off-by: Ruben Jenster --- INSTALL.md | 10 +++++----- README.md | 11 ++--------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 1552b62f..bb317fac 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -38,7 +38,7 @@ pacman -Sy conntrack-tools ebtables jq ## runtime dependencies -* [lxc](https://github.com/lxc/lxc.git) >= 4.0.5, master recommened +* [lxc](https://github.com/lxc/lxc.git) >= b5daeddc5afce1cad4915aef3e71fdfe0f428709 * [conmon/pinns](https://github.com/containers/conmon.git) v2.0.22 * [cri-o](https://github.com/cri-o/cri-o.git) release-1.20 @@ -50,11 +50,11 @@ By default everything is installed to `/usr/local` git clone https://github.com/lxc/lxc.git cd lxc ./autogen.sh -./configure --enable-bash=no --enable-tools=no \ - --enable-commands=no --enable-seccomp=yes \ +./configure --enable-bash=no --enable-seccomp=yes \ --enable-capabilities=yes --enable-apparmor=yes make install +git describe --tags > /usr/local/lib/liblxc.version.txt echo /usr/local/lib > /etc/ld.so.conf.d/local.conf ldconfig ``` @@ -79,13 +79,13 @@ Keep in mind that you have to change the `INSTALL_PREFIX` in the crio install sc ```sh git clone https://github.com/containers/conmon.git -cd conmon +cd conmon git reset --hard v2.0.22 make clean make install ``` -### cri-o +### cri-o ```sh #!/bin/sh diff --git a/README.md b/README.md index 7371619c..46a0cd68 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,9 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S * Only cgroupv2 unified cgroup hierarchy is supported. * A recent kernel > 5.8 is required for full cgroup support. -* Cgroup resource limits are not implemented yet. This will change soon. -### AdditionalGids - -* https://github.com/lxc/lxc/pull/3575 - -Additional group ids for the container's process require the following development repositories: - -* https://github.com/Drachenfels-GmbH/lxc -* https://github.com/Drachenfels-GmbH/go-lxc +* [runtime: Implement POSIX platform hooks](https://github.com/Drachenfels-GmbH/crio-lxc/issues/10) +* [runtime: Implement cgroup2 resource limits](https://github.com/Drachenfels-GmbH/crio-lxc/issues/11) ## Configuration From e7f22882cbd7894d419d66ed7b0d6dadd05c5e85 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Feb 2021 18:51:30 +0100 Subject: [PATCH 157/373] doc: small fixes Signed-off-by: Ruben Jenster --- README.md | 8 +++++--- lxcontainer/init.go | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 46a0cd68..7e554969 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,10 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S ## Requirements and restrictions -* Only cgroupv2 unified cgroup hierarchy is supported. -* A recent kernel > 5.8 is required for full cgroup support. +* Only cgroupv2 (unified cgroup hierarchy) is supported. +* A recent kernel >= 5.8 is required for full cgroup support. + +### Unimplemented features * [runtime: Implement POSIX platform hooks](https://github.com/Drachenfels-GmbH/crio-lxc/issues/10) * [runtime: Implement cgroup2 resource limits](https://github.com/Drachenfels-GmbH/crio-lxc/issues/11) @@ -86,7 +88,7 @@ CRIO_LXC_CONTAINER_LOG_LEVEL=debug ### Runtime (security) features All supported runtime security features are enabled by default.
-There following runtime (security) features can optionally be disabled.
+The following runtime (security) features can optionally be disabled.
Details see `crio-lxc --help` * apparmor diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 0b44cb07..7860821f 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -12,7 +12,8 @@ import ( ) const ( - // SyncFifoPath is the path to the fifo used to block container start in init until start cmd is called. + // initDir is the working directory for crio-lxc-init. + // It contains the init binary itself and all files required for it. initDir = "/.crio-lxc" ) From 2da257967049e0f819f0b931235e9988a692cc31 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Feb 2021 22:22:45 +0100 Subject: [PATCH 158/373] build: Remove hardcoded path to musl-gcc. Fixes #17 Signed-off-by: Ruben Jenster --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e723f57d..bacc7017 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH LDFLAGS=-X main.version=$(COMMIT) CC ?= cc +MUSL_CC ?= musl-gcc all: fmt $(BINS) @@ -25,7 +26,7 @@ crio-lxc-start: cmd/start/crio-lxc-start.c $(CC) -Werror -Wpedantic $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? crio-lxc-init: cmd/init/crio-lxc-init.c - /usr/local/musl/bin/musl-gcc -Werror -Wpedantic -static -g -o $@ $? + $(MUSL_CC) -Werror -Wpedantic -static -g -o $@ $? #musl-gcc -g3 -Werror -static $? -o $@ # ensure that crio-lxc-init is statically compiled ! ldd $@ 2>/dev/null From 980a89a3d1a161d1dc6a2bd2a028166b0ccafb7b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 12 Feb 2021 10:55:34 +0100 Subject: [PATCH 159/373] Remove commited binary. Signed-off-by: Ruben Jenster --- crio-lxc-container-hook | Bin 16816 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 crio-lxc-container-hook diff --git a/crio-lxc-container-hook b/crio-lxc-container-hook deleted file mode 100755 index ca0f3bec1791069f166d5ebe068c93ef24abcce9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16816 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 RO#fRejl>foXlb+le*@fN$20%{ From a47e41a6b69746c743068c7921d2abba346e3d1e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 12 Feb 2021 10:57:37 +0100 Subject: [PATCH 160/373] make: Add test target Signed-off-by: Ruben Jenster --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bacc7017..311f37c3 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,15 @@ LDFLAGS=-X main.version=$(COMMIT) CC ?= cc MUSL_CC ?= musl-gcc -all: fmt $(BINS) +all: fmt test $(BINS) install: all cp -v $(BINS) $(PREFIX)/bin +.PHONY: test +test: + go test -v ./... + lint: golangci-lint run -c ./lint.yaml ./... From 5fc5e2226e2b9b854f8b5ec91735f5655b90d0c5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 15 Feb 2021 16:42:14 +0100 Subject: [PATCH 161/373] Removed old (bats) tetssuite. The bats tests are currently unused and unmaintained so I remove them for now. Currently I run sonobuoy conformance tests on a semi-automated test cluster. Signed-off-by: Ruben Jenster --- .gitignore | 1 - Makefile | 7 - README.old.md | 105 ------------ test/.gitignore | 1 - test/basic-container-config.json | 14 -- test/basic-pod-config.json | 11 -- test/basic.bats | 20 --- test/crio.conf.in | 278 ------------------------------- test/helpers.bash | 63 ------- test/manual.bats | 34 ---- 10 files changed, 534 deletions(-) delete mode 100644 README.old.md delete mode 100644 test/.gitignore delete mode 100644 test/basic-container-config.json delete mode 100644 test/basic-pod-config.json delete mode 100644 test/basic.bats delete mode 100644 test/crio.conf.in delete mode 100644 test/helpers.bash delete mode 100644 test/manual.bats diff --git a/.gitignore b/.gitignore index b5431de5..547fd83e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ crio-lxc crio-lxc-start crio-lxc-init crio-lxc-container-hook -crio-lxc-test* oci/ roots/ .stacker/ diff --git a/Makefile b/Makefile index 311f37c3..d611390b 100644 --- a/Makefile +++ b/Makefile @@ -38,13 +38,6 @@ crio-lxc-init: cmd/init/crio-lxc-init.c crio-lxc-container-hook: cmd/container-hook/hook.c musl-gcc -DDEBUG -Werror -Wpedantic $? -o $@ -# make test TEST=basic will run only the basic test. -.PHONY: check -check: crio-lxc - go fmt ./... && ([ -z $(TRAVIS) ] || git diff --quiet) - go test ./... - PACKAGES_DIR=$(PACKAGES_DIR) sudo -E "PATH=$$PATH" bats -t $(patsubst %,test/%.bats,$(TEST)) - .PHONY: vendorup vendorup: go get -u diff --git a/README.old.md b/README.old.md deleted file mode 100644 index b167a8a2..00000000 --- a/README.old.md +++ /dev/null @@ -1,105 +0,0 @@ -# crio-lxc - -This is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as -a drop-in container runtime replacement for use by -[CRI-O](https://github.com/kubernetes-sigs/cri-o). - -To use this, simply build it: - -``` -make -``` - -Then specify the `crio-lxc` binary you just built as the value for -`default_runtime` in the `crio.runtime` section of `/etc/crio/crio.conf`. - -#### change liblxc source path - -The installation prefix environment variable is set to `PREFIX=/usr/local` by default. -The library source path for `pkg-config` is set to `$PREFIX/lib/pkg-config` by default. -You can change that by setting the `PKG_CONFIG_PATH` environment variable. - -E.g to install binaries in `/opt/bin` and use liblxc from `/usr/lib`: - - PREFIX=/opt PKG_CONFIG_PATH=/usr/lib/pkgconfig make install - -#### rebuild all libraries - -To rebuild all libraries set `GOFLAGS=-a`. -E.g after an liblxc upgrade the go-lxc library must be rebuild. - - make clean - GOFLAGS=-a make - -### cri-o - -crio-lxc-install - -## Notes - -Note that you must have a new enough liblxc, one which supports the -"lxc.rootfs.managed" key. 3.0.3 is not new enough, 3.1 is. On Ubuntu, -you can upgrade using the ubuntu-lxc/lxc-git-master PPA. Arch and -OpenSUSE tumbleweed should be uptodate. - -## Tests - -To run the 'basic' test, you'll need to build cri-o and CNI. - -``` -mkdir ~/packages -cd packages -git clone https://github.com/kubernetes-sigs/cri-o -cd cri-o -make -cd .. -git clone https://github.com/containernetworking/cni -git clone https://github.com/containernetworking/plugins cni-plugins -cd cni-plugins -./build_linux.sh -``` - -You'll also need crictl. Download the tarball, extract it, and -copy crictl to somewhere in your path: - -``` -wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.14.0/crictl-v1.14.0-linux-amd64.tar.gz -tar zxf crictl-v1.14.0-linux-amd64.tar.gz -sudo cp crictl /usr/local/bin # or ~/.local/bin, etc. -``` - -You'll also need conntrack installed: - -``` -apt install conntrack -``` - -You have to install [bats](https://github.com/bats-core/bats-core) to run the tests. -On debian you can install bats with: - - apt-get install bats - - -To keep the tempdir of of a test run, you have to create the lockfile `.keeptempdirs` -in the top-level of this repository. - - touch .keeptempdirs - -To debug `crictl` calls within a test run: - - CRICTLDEBUG="-D" make basic.bats - -`bats` does not show any output when the test was successful. -The logfile is created in /tmp and deleted when the test was successful. -To watch the test output while the test is running: - - tail -f /tmp/bats.*.log - -Expand multi-line output int cri-o log (e.g stacktrace) - -echo "output" | sed 's/\\n\\t/\n/g' - - -# TODO -## generate nice buttons for the project page -https://goreportcard.com diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index c272491c..00000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -oci-cache diff --git a/test/basic-container-config.json b/test/basic-container-config.json deleted file mode 100644 index 5a68f41f..00000000 --- a/test/basic-container-config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "metadata": { - "name": "busybox" - }, - "image":{ - "image": "busybox" - }, - "command": [ - "top" - ], - "log_path":"busybox/0.log", - "linux": { - } -} diff --git a/test/basic-pod-config.json b/test/basic-pod-config.json deleted file mode 100644 index e7ccc473..00000000 --- a/test/basic-pod-config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "metadata": { - "name": "nginx-sandbox", - "namespace": "default", - "attempt": 1, - "uid": "hdishd83djaidwnduwk28bcsb" - }, - "log_directory": "/tmp", - "linux": { - } -} diff --git a/test/basic.bats b/test/basic.bats deleted file mode 100644 index 70e93176..00000000 --- a/test/basic.bats +++ /dev/null @@ -1,20 +0,0 @@ -load helpers - -function setup() { - setup_crio -} - -function teardown() { - cleanup_crio -} - -@test "basic cri-o workings" { - crictl runp test/basic-pod-config.json - crictl pull busybox - crictl images - podid=$(crictl pods | grep nginx-sandbox | awk '{ print $1 }') - crictl create $podid test/basic-container-config.json test/basic-pod-config.json - crictl ps -a | grep busybox - crictl stopp $podid - crictl rmp $podid -} diff --git a/test/crio.conf.in b/test/crio.conf.in deleted file mode 100644 index 5331fe7e..00000000 --- a/test/crio.conf.in +++ /dev/null @@ -1,278 +0,0 @@ -# The CRI-O configuration file specifies all of the available configuration -# options and command-line flags for the crio(8) OCI Kubernetes Container Runtime -# daemon, but in a TOML format that can be more easily modified and versioned. -# -# Please refer to crio.conf(5) for details of all configuration options. - -# CRI-O reads its storage defaults from the containers-storage.conf(5) file -# located at /etc/containers/storage.conf. Modify this storage configuration if -# you want to change the system's defaults. If you want to modify storage just -# for CRI-O, you can change the storage configuration options here. -[crio] - -# Path to the "root directory". CRI-O stores all of its data, including -# containers images, in this directory. -root = "CRIOLXC_TEST_DIR/crio-root" - -# Path to the "run directory". CRI-O stores all of its state in this directory. -#runroot = "/tmp/1000" - -# Storage driver used to manage the storage of images and containers. Please -# refer to containers-storage.conf(5) to see all available storage drivers. -#storage_driver = "vfs" - -# List to pass options to the storage driver. Please refer to -# containers-storage.conf(5) to see all available storage options. -#storage_option = [ -#] - -# If set to false, in-memory locking will be used instead of file-based locking. -file_locking = true - -# Path to the lock file. -file_locking_path = "CRIOLXC_TEST_DIR/crio.lock" - - -# The crio.api table contains settings for the kubelet/gRPC interface. -[crio.api] - -# Path to AF_LOCAL socket on which CRI-O will listen. -listen = "CRIOLXC_TEST_DIR/crio.sock" - -# IP address on which the stream server will listen. -stream_address = "127.0.0.1" - -# The port on which the stream server will listen. -stream_port = "0" - -# Enable encrypted TLS transport of the stream server. -stream_enable_tls = false - -# Path to the x509 certificate file used to serve the encrypted stream. This -# file can change, and CRI-O will automatically pick up the changes within 5 -# minutes. -stream_tls_cert = "" - -# Path to the key file used to serve the encrypted stream. This file can -# change, and CRI-O will automatically pick up the changes within 5 minutes. -stream_tls_key = "" - -# Path to the x509 CA(s) file used to verify and authenticate client -# communication with the encrypted stream. This file can change, and CRI-O will -# automatically pick up the changes within 5 minutes. -stream_tls_ca = "" - -# Maximum grpc send message size in bytes. If not set or <=0, then CRI-O will default to 16 * 1024 * 1024. -grpc_max_send_msg_size = 16777216 - -# Maximum grpc receive message size. If not set or <= 0, then CRI-O will default to 16 * 1024 * 1024. -grpc_max_recv_msg_size = 16777216 - -# The crio.runtime table contains settings pertaining to the OCI runtime used -# and options for how to set up and manage the OCI runtime. -[crio.runtime] - -# A list of ulimits to be set in containers by default, specified as -# "=:", for example: -# "nofile=1024:2048" -# If nothing is set here, settings will be inherited from the CRI-O daemon -#default_ulimits = [ -#] - -# default_runtime is the _name_ of the OCI runtime to be used as the default. -# The name is matched against the runtimes map below. -default_runtime = "lxc" - -# If true, the runtime will not use pivot_root, but instead use MS_MOVE. -no_pivot = false - -# Path to the conmon binary, used for monitoring the OCI runtime. -conmon = "PACKAGES_DIR/conmon/bin/conmon" - -# Cgroup setting for conmon -#conmon_cgroup = "system.slice" - -# Path to pinns. -pinns_path = "PACKAGES_DIR/cri-o/bin/pinns" - -# Environment variable list for the conmon process, used for passing necessary -# environment variables to conmon or the runtime. -conmon_env = [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", -] - -# If true, SELinux will be used for pod separation on the host. -selinux = false - -# Path to the seccomp.json profile which is used as the default seccomp profile -# for the runtime. -seccomp_profile = "CRIOLXC_TEST_DIR/seccomp.json" - -# Used to change the name of the default AppArmor profile of CRI-O. The default -# profile name is "crio-default-" followed by the version string of CRI-O. -apparmor_profile = "unconfined" - -# Cgroup management implementation used for the runtime. -cgroup_manager = "systemd" - -# List of default capabilities for containers. If it is empty or commented out, -# only the capabilities defined in the containers json file by the user/kube -# will be added. -default_capabilities = [ - "CHOWN", - "DAC_OVERRIDE", - "FSETID", - "FOWNER", - "NET_RAW", - "SETGID", - "SETUID", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL", -] - -# List of default sysctls. If it is empty or commented out, only the sysctls -# defined in the container json file by the user/kube will be added. -default_sysctls = [ -] - -# List of additional devices. specified as -# "::", for example: "--device=/dev/sdc:/dev/xvdc:rwm". -#If it is empty or commented out, only the devices -# defined in the container json file by the user/kube will be added. -additional_devices = [ -] - -# Path to OCI hooks directories for automatically executed hooks. -hooks_dir = [ -] - -# List of default mounts for each container. **Deprecated:** this option will -# be removed in future versions in favor of default_mounts_file. -default_mounts = [ -] - -# Path to the file specifying the defaults mounts for each container. The -# format of the config is /SRC:/DST, one mount per line. Notice that CRI-O reads -# its default mounts from the following two files: -# -# 1) /etc/containers/mounts.conf (i.e., default_mounts_file): This is the -# override file, where users can either add in their own default mounts, or -# override the default mounts shipped with the package. -# -# 2) /usr/share/containers/mounts.conf: This is the default file read for -# mounts. If you want CRI-O to read from a different, specific mounts file, -# you can change the default_mounts_file. Note, if this is done, CRI-O will -# only add mounts it finds in this file. -# -#default_mounts_file = "" - -# Maximum number of processes allowed in a container. -pids_limit = 1024 - -# Maximum sized allowed for the container log file. Negative numbers indicate -# that no size limit is imposed. If it is positive, it must be >= 8192 to -# match/exceed conmon's read buffer. The file is truncated and re-opened so the -# limit is never exceeded. -log_size_max = -1 - -# Whether container output should be logged to journald in addition to the kuberentes log file -log_to_journald = false - -# Path to directory in which container exit files are written to by conmon. -container_exits_dir = "CRIOLXC_TEST_DIR/exits" - -# Path to directory for container attach sockets. -container_attach_socket_dir = "CRIOLXC_TEST_DIR/attach-sockets" - -# If set to true, all containers will run in read-only mode. -read_only = false - -# Changes the verbosity of the logs based on the level it is set to. Options -# are fatal, panic, error, warn, info, and debug. -log_level = "info" - -# The UID mappings for the user namespace of each container. A range is -# specified in the form containerUID:HostUID:Size. Multiple ranges must be -# separated by comma. -uid_mappings = "" - -# The GID mappings for the user namespace of each container. A range is -# specified in the form containerGID:HostGID:Size. Multiple ranges must be -# separated by comma. -gid_mappings = "" - -# The minimal amount of time in seconds to wait before issuing a timeout -# regarding the proper termination of the container. -ctr_stop_timeout = 0 - -# ManageNetworkNSLifecycle determines whether we pin and remove network namespace -# and manage its lifecycle. -manage_network_ns_lifecycle = false - -# The "crio.runtime.runtimes" table defines a list of OCI compatible runtimes. -# The runtime to use is picked based on the runtime_handler provided by the CRI. -# If no runtime_handler is provided, the runtime will be picked based on the level -# of trust of the workload. - -[crio.runtime.runtimes.lxc] -runtime_path = "CRIOLXC_BINARY" -runtime_type = "oci" -runtime_root = "CRIOLXC_TEST_DIR/runtime-root" - - -# The crio.image table contains settings pertaining to the management of OCI images. -# -# CRI-O reads its configured registries defaults from the system wide -# containers-registries.conf(5) located in /etc/containers/registries.conf. If -# you want to modify just CRI-O, you can change the registries configuration in -# this file. Otherwise, leave insecure_registries and registries commented out to -# use the system's defaults from /etc/containers/registries.conf. -[crio.image] - -# Default transport for pulling images from a remote container storage. -default_transport = "docker://" - -# The image used to instantiate infra containers. -pause_image = "k8s.gcr.io/pause:3.1" - -# If not empty, the path to a docker/config.json-like file containing credentials -# necessary for pulling the image specified by pause_image above. -pause_image_auth_file = "" - -# The command to run to have a container stay in the paused state. -pause_command = "/pause" - -# Path to the file which decides what sort of policy we use when deciding -# whether or not to trust an image that we've pulled. It is not recommended that -# this option be used, as the default behavior of using the system-wide default -# policy (i.e., /etc/containers/policy.json) is most often preferred. Please -# refer to containers-policy.json(5) for more details. -signature_policy = "CRIOLXC_TEST_DIR/policy.json" - -# Controls how image volumes are handled. The valid values are mkdir, bind and -# ignore; the latter will ignore volumes entirely. -image_volumes = "mkdir" - -# List of registries to be used when pulling an unqualified image (e.g., -# "alpine:latest"). By default, registries is set to "docker.io" for -# compatibility reasons. Depending on your workload and usecase you may add more -# registries (e.g., "quay.io", "registry.fedoraproject.org", -# "registry.opensuse.org", etc.). -registries = [ - "docker.io", -] - - -# The crio.network table containers settings pertaining to the management of -# CNI plugins. -[crio.network] - -# Path to the directory where CNI configuration files are located. -network_dir = "CRIOLXC_TEST_DIR/cni/net.d" - -# Paths to directories where CNI plugin binaries are located. -plugin_dirs = [ - "CRIOLXC_TEST_DIR/cni-plugins/bin", -] diff --git a/test/helpers.bash b/test/helpers.bash deleted file mode 100644 index d8800d1e..00000000 --- a/test/helpers.bash +++ /dev/null @@ -1,63 +0,0 @@ -ROOT_DIR=$(git rev-parse --show-toplevel) - -function make_tempdir { - declare -g TEMP_DIR=$(realpath $(mktemp -d crio-lxc-test.XXXXXXXX)) - # not strictly necessary, but nice if we end up debugging things by keeping - # the tempdir around - chmod 755 "$TEMP_DIR" -} - -function setup_crio { - make_tempdir - sed \ - -e "s,CRIOLXC_TEST_DIR,$TEMP_DIR,g" \ - -e "s,CRIOLXC_BINARY,$ROOT_DIR/crio-lxc,g" \ - -e "s,PACKAGES_DIR,$PACKAGES_DIR,g" \ - "$ROOT_DIR/test/crio.conf.in" > "$TEMP_DIR/crio.conf" - # it doesn't like seccomp_profile = "", so let's make a bogus one - echo "{}" > "$TEMP_DIR/seccomp.json" - # It doesn't like if these dirs don't exist, so always them - # You can't start a pod without them, so if you're going to test - # basic.bats, then - # cd ~/packages; git clone https://github.com/containernetworking/cni - # git clone https://github.com/containernetworking/plugins cni-plugins - # cd cni-plugins; ./build_linux.sh - mkdir -p "$TEMP_DIR/cni/net.d" - mkdir -p /tmp/busybox # for the logfile as per log_directory in test/basic-pod-config.json - if [ -d ~/packages/cni-plugins ]; then - rsync -a ~/packages/cni-plugins $TEMP_DIR/ - cat > $TEMP_DIR/cni/net.d/10-myptp.conf << EOF -{"cniVersion":"0.3.1","name":"myptp","type":"ptp","ipMasq":true,"ipam":{"type":"host-local","subnet":"172.16.29.0/24","routes":[{"dst":"0.0.0.0/0"}]}} -EOF - else - mkdir -p "$TEMP_DIR/cni-plugins" - fi - # set up an insecure policy - echo '{"default": [{"type": "insecureAcceptAnything"}]}' > "$TEMP_DIR/policy.json" - "$PACKAGES_DIR/cri-o/bin/crio" --config "$TEMP_DIR/crio.conf" & - declare -g CRIO_PID=$! -} - -function cleanup_crio { - kill -SIGTERM $CRIO_PID || true - # wait until it dies; it has a bunch of stuff mounted, and we'll get - # various EBUSY races if we don't - wait $CRIO_PID - cleanup_tempdir -} - -function cleanup_tempdir { - [ -f .keeptempdirs ] || rm -rf "$TEMP_DIR" || true -} - -function crictl { - # watch out for: https://github.com/kubernetes-sigs/cri-tools/issues/460 - # If you need more debug output, set CRICTLDEBUG to -D - $(which crictl) ${CRICTLDEBUG} --runtime-endpoint "unix://$TEMP_DIR/crio.sock" $@ - echo "$output" -} - -function crio-lxc { - $ROOT_DIR/crio-lxc --lxc-path "$TEMP_DIR/lxcpath" $@ - echo "$output" -} diff --git a/test/manual.bats b/test/manual.bats deleted file mode 100644 index c4f9ae0f..00000000 --- a/test/manual.bats +++ /dev/null @@ -1,34 +0,0 @@ -load helpers - -function setup() { - make_tempdir - skopeo --insecure-policy copy docker://alpine:latest oci:$ROOT_DIR/test/oci-cache:alpine - umoci unpack --image "$ROOT_DIR/test/oci-cache:alpine" "$TEMP_DIR/dest" - sed -i -e "s?rootfs?$TEMP_DIR/dest/rootfs?" "$TEMP_DIR/dest/config.json" - sed -i -e "s?\"/bin/sh\"?\"/bin/sleep\",\n\"10\"?" "$TEMP_DIR/dest/config.json" - sed -i -e "s?\"type\": \"ipc\"?\"type\": \"ipc\",\n\"path\": \"/proc/1/ns/ipc\"?" "$TEMP_DIR/dest/config.json" - -} - -function teardown() { - cleanup_tempdir -} - -@test "manual invocation" { - crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" create --bundle "$TEMP_DIR/dest" --pid-file "$TEMP_DIR/pid" alpine - - status=$(crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" state alpine | jq -r .status) - [ $status = "created" ] - - crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" start alpine - - status=$(crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" state alpine | jq -r .status) - [ $status = "running" ] - - pid1ipcnsinode=$(stat -L -c%i /proc/1/ns/ipc) - mypid=$(<"$TEMP_DIR/pid") - mypidipcnsinode=$(stat -L -c%i "/proc/$mypid/ns/ipc") - [ $pid1ipcnsinode = $mypidipcnsinode ] - crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" kill alpine - crio-lxc --debug --log-level trace --log-file "$TEMP_DIR/log" delete alpine -} From dcfd25265b4af47528559f8dc29bd8a29975d313 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 22:09:07 +0100 Subject: [PATCH 162/373] Fix crio-lxc-start compilation. Linker flags always go after the source files. Setting the linker flags before the source files works with recent GCC versions (e.g GCC 10.0.3 on archlinux), but it doesn't work with older versions (e.g GCC 9.3.0, ubuntu 20.04) Signed-off-by: Ruben Jenster --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index d611390b..24939278 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,10 @@ TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) PACKAGES_DIR?=~/packages BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-container-hook PREFIX ?= /usr/local -PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig +# Note: The default pkg-config directory is search after PKG_CONFIG_PATH +PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig export PKG_CONFIG_PATH +LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) LDFLAGS=-X main.version=$(COMMIT) CC ?= cc MUSL_CC ?= musl-gcc @@ -27,12 +29,11 @@ crio-lxc: $(GO_SRC) Makefile go.mod go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c - $(CC) -Werror -Wpedantic $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --cflags lxc) -o $@ $? + $(CC) -Werror -Wpedantic -o $@ $? $(LIBLXC_LDFLAGS) crio-lxc-init: cmd/init/crio-lxc-init.c $(MUSL_CC) -Werror -Wpedantic -static -g -o $@ $? - #musl-gcc -g3 -Werror -static $? -o $@ - # ensure that crio-lxc-init is statically compiled + # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null crio-lxc-container-hook: cmd/container-hook/hook.c From 8c4eea35436f388db637432fcc3e19aefb2770a2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 22:47:33 +0100 Subject: [PATCH 163/373] Build crio-lxc-container-hook statically linked. Cleanup Makefile. Signed-off-by: Ruben Jenster --- Makefile | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 24939278..1519c68f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,7 @@ -GO_SRC=$(shell find . -name \*.go) COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) -TEST?=$(patsubst test/%.bats,%,$(wildcard test/*.bats)) -PACKAGES_DIR?=~/packages -BINS := crio-lxc crio-lxc-start crio-lxc-init crio-lxc-container-hook +BINS := crio-lxc-start crio-lxc-init crio-lxc-container-hook crio-lxc +# Installation prefix for BINS PREFIX ?= /usr/local # Note: The default pkg-config directory is search after PKG_CONFIG_PATH PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig @@ -15,9 +13,13 @@ MUSL_CC ?= musl-gcc all: fmt test $(BINS) -install: all +install: $(BINS) cp -v $(BINS) $(PREFIX)/bin +.PHONY: clean +clean: + -rm -f $(BINS) + .PHONY: test test: go test -v ./... @@ -25,27 +27,19 @@ test: lint: golangci-lint run -c ./lint.yaml ./... -crio-lxc: $(GO_SRC) Makefile go.mod +crio-lxc: go.mod **/*.go go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd crio-lxc-start: cmd/start/crio-lxc-start.c $(CC) -Werror -Wpedantic -o $@ $? $(LIBLXC_LDFLAGS) crio-lxc-init: cmd/init/crio-lxc-init.c - $(MUSL_CC) -Werror -Wpedantic -static -g -o $@ $? + $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null crio-lxc-container-hook: cmd/container-hook/hook.c - musl-gcc -DDEBUG -Werror -Wpedantic $? -o $@ - -.PHONY: vendorup -vendorup: - go get -u - -.PHONY: clean -clean: - -rm -f $(BINS) + $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? fmt: go fmt ./... From 9436029e207cf6e4681e493caa5566d23fb7a04b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Feb 2021 11:33:58 +0100 Subject: [PATCH 164/373] runtime: Implement mount option filtering. Refs #14 Currently only the mount options 'rprivate' and 'tmpcopyup' are removed from tmpfs mounts (hardcoded). Signed-off-by: Ruben Jenster --- lxcontainer/mount.go | 30 ++++++++++++++++++++++++++++++ lxcontainer/mount_test.go | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index c2a1c878..93d288c8 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -9,6 +9,34 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) +func removeMountOptions(clxc *Runtime, fs string, opts []string, unsupported ...string) []string { + supported := make([]string, 0, len(opts)) + for _, opt := range opts { + addOption := true + for _, u := range unsupported { + if opt == u { + addOption = false + break + } + } + if addOption { + supported = append(supported, opt) + } else { + clxc.Log.Info().Str("fs", fs).Str("option", opt).Msg("removed mount option") + } + } + return supported +} + +func filterMountOptions(clxc *Runtime, fs string, opts []string) []string { + switch fs { + case "tmpfs": + // TODO make this configurable per filesystem + return removeMountOptions(clxc, fs, opts, "rprivate", "tmpcopyup") + } + return opts +} + func configureMounts(clxc *Runtime, spec *specs.Spec) error { // excplicitly disable auto-mounting if err := clxc.setConfigItem("lxc.mount.auto", ""); err != nil { @@ -46,6 +74,8 @@ func configureMounts(clxc *Runtime, spec *specs.Spec) error { return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) } + ms.Options = filterMountOptions(clxc, ms.Type, ms.Options) + mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, strings.Join(ms.Options, ",")) if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index 18577518..7e05c0d9 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "testing" + "strings" "github.com/stretchr/testify/require" ) @@ -71,3 +72,16 @@ func TestResolveMountDestination_relative(t *testing.T) { require.Equal(t, filepath.Join(tmpdir, "/folder3/hello.txt"), p) require.Error(t, err, os.ErrExist) } + +func TestFilterMountOptions(t *testing.T) { + rt := Runtime{LogFilePath: "/dev/stderr", LogLevel: "debug"} + rt.ConfigureLogging("test") + + opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") + + out := filterMountOptions(&rt, "tmpfs", opts) + require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) + + out = filterMountOptions(&rt, "nosuchfs", opts) + require.Equal(t, opts, out) +} From 2afe1e01abd3dba017946c215b61025f4f28db46 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Feb 2021 18:13:30 +0100 Subject: [PATCH 165/373] Disable 'private' mount option for cgroup2 fs. Refs #13 Signed-off-by: Ruben Jenster --- lxcontainer/mount.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index 93d288c8..8e5fd927 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -33,6 +33,9 @@ func filterMountOptions(clxc *Runtime, fs string, opts []string) []string { case "tmpfs": // TODO make this configurable per filesystem return removeMountOptions(clxc, fs, opts, "rprivate", "tmpcopyup") + case "cgroup2": + // TODO make this configurable per filesystem + return removeMountOptions(clxc, fs, opts, "private") } return opts } From ef6c1f6b518eb4c838a75b9e09f6b831547ea46c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 12 Feb 2021 10:48:09 +0100 Subject: [PATCH 166/373] Fix formatting. Signed-off-by: Ruben Jenster --- lxcontainer/mount_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index 7e05c0d9..432da059 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -4,8 +4,8 @@ import ( "io/ioutil" "os" "path/filepath" - "testing" "strings" + "testing" "github.com/stretchr/testify/require" ) @@ -74,14 +74,14 @@ func TestResolveMountDestination_relative(t *testing.T) { } func TestFilterMountOptions(t *testing.T) { - rt := Runtime{LogFilePath: "/dev/stderr", LogLevel: "debug"} - rt.ConfigureLogging("test") + rt := Runtime{LogFilePath: "/dev/stderr", LogLevel: "debug"} + rt.ConfigureLogging("test") - opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") + opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") - out := filterMountOptions(&rt, "tmpfs", opts) - require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) + out := filterMountOptions(&rt, "tmpfs", opts) + require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) - out = filterMountOptions(&rt, "nosuchfs", opts) - require.Equal(t, opts, out) + out = filterMountOptions(&rt, "nosuchfs", opts) + require.Equal(t, opts, out) } From 43b4414b84c3cdf65bcf431ed63a38aa9e50103e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 7 Mar 2021 03:22:00 +0100 Subject: [PATCH 167/373] Read container spec in cli. Signed-off-by: Ruben Jenster --- cmd/cli.go | 49 +++++++++++++++++++++++++++++++++++----- lxcontainer/container.go | 12 +--------- lxcontainer/create.go | 7 +----- lxcontainer/runtime.go | 14 ------------ lxcontainer/utils.go | 2 +- 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index d4d48dcf..66db985f 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -7,9 +7,11 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "time" "github.com/lxc/crio-lxc/lxcontainer" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) @@ -277,16 +279,25 @@ var createCmd = cli.Command{ } func doCreate(unused *cli.Context) error { - ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateTimeout) - defer cancel() - - err := clxc.Create(ctx) + err := doCreateInternal(unused) if clxc.CreateHook != "" { runCreateHook(err) } return err } +func doCreateInternal(unused *cli.Context) error { + ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateTimeout) + defer cancel() + + specPath := filepath.Join(clxc.BundlePath, "config.json") + spec, err := readSpec(specPath) + if err != nil { + return fmt.Errorf("failed to load container spec from bundle: %w", err) + } + return clxc.Create(ctx, spec) +} + func runCreateHook(err error) { env := []string{ "CONTAINER_ID=" + clxc.ContainerID, @@ -294,7 +305,7 @@ func runCreateHook(err error) { "RUNTIME_CMD=" + clxc.Command, "RUNTIME_PATH=" + clxc.RuntimePath(), "BUNDLE_PATH=" + clxc.BundlePath, - "SPEC_PATH=" + clxc.SpecPath(), + "SPEC_PATH=" + filepath.Join(clxc.BundlePath, "config.json"), "LOG_FILE=" + clxc.LogFilePath, } if err != nil { @@ -486,7 +497,7 @@ func doExec(ctx *cli.Context) error { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := lxcontainer.ReadSpecProcess(ctx.String("process")) + procSpec, err := readSpecProcess(ctx.String("process")) if err != nil { return err } @@ -513,3 +524,29 @@ func doExec(ctx *cli.Context) error { } return nil } + +func readSpec(src string) (spec *specs.Spec, err error) { + err = lxcontainer.DecodeFileJSON(spec, src) + return +} + +func readSpecProcess(src string) (*specs.Process, error) { + if src == "" { + return nil, nil + } + proc := new(specs.Process) + err := lxcontainer.DecodeFileJSON(proc, src) + return proc, err +} + +/* +func (c ContainerInfo) SpecPath() string { + return filepath.Join(c.BundlePath, "config.json") +} + +func (c *ContainerInfo) ReadSpec() (*specs.Spec, error) { + spec := new(specs.Spec) + err := DecodeFileJSON(spec, c.SpecPath()) + return spec, err +} +*/ diff --git a/lxcontainer/container.go b/lxcontainer/container.go index e5e1fa41..783bd56f 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -73,7 +73,7 @@ func (c ContainerInfo) CreatePidFile(pid int) error { // RuntimeRoot and ContainerID must be set func (c *ContainerInfo) Load() error { - return decodeFileJSON(c, c.RuntimePath("container.json")) + return DecodeFileJSON(c, c.RuntimePath("container.json")) } func (c *ContainerInfo) Create() error { @@ -81,13 +81,3 @@ func (c *ContainerInfo) Create() error { c.CreatedAt = time.Now() return encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) } - -func (c ContainerInfo) SpecPath() string { - return filepath.Join(c.BundlePath, "config.json") -} - -func (c *ContainerInfo) ReadSpec() (*specs.Spec, error) { - spec := new(specs.Spec) - err := decodeFileJSON(spec, c.SpecPath()) - return spec, err -} diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 8e8e1e88..5d37cbda 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -16,7 +16,7 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -func (c *Runtime) Create(ctx context.Context) error { +func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { if c.runtimePathExists() { return ErrExist } @@ -41,11 +41,6 @@ func (c *Runtime) Create(ctx context.Context) error { c.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } - spec, err := c.ReadSpec() - if err != nil { - return errorf("failed to load container spec from bundle: %w", err) - } - err = c.createContainer(spec) if err != nil { return errorf("failed to create container: %w", err) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index dd6f330e..65b37c20 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -671,17 +671,3 @@ func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.Atta } return opts, nil } - -func ReadSpec(src string) (spec *specs.Spec, err error) { - err = decodeFileJSON(spec, src) - return -} - -func ReadSpecProcess(src string) (*specs.Process, error) { - if src == "" { - return nil, nil - } - proc := new(specs.Process) - err := decodeFileJSON(proc, src) - return proc, err -} diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 7aff621d..f179e37c 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -70,7 +70,7 @@ func isFilesystem(dir string, fsName string) error { return nil } -func decodeFileJSON(obj interface{}, src string) error { +func DecodeFileJSON(obj interface{}, src string) error { // #nosec f, err := os.Open(src) if err != nil { From f67c2e8cee65edcef6188ae7f96a33917395bea0 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 00:44:35 +0100 Subject: [PATCH 168/373] Disable 'rslave' mount option for sysfs. Should fix sysfs mount in nested containers. Signed-off-by: Ruben Jenster --- lxcontainer/mount.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index 8e5fd927..8b565767 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -30,6 +30,8 @@ func removeMountOptions(clxc *Runtime, fs string, opts []string, unsupported ... func filterMountOptions(clxc *Runtime, fs string, opts []string) []string { switch fs { + case "sysfs": + return removeMountOptions(clxc, fs, opts, "rslave") case "tmpfs": // TODO make this configurable per filesystem return removeMountOptions(clxc, fs, opts, "rprivate", "tmpcopyup") From 691cee335d7bb25e8f7adf3fb6e4d38b96777325 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 18 Feb 2021 11:35:18 +0100 Subject: [PATCH 169/373] Upgrade vulnerable transitive dependencies reported by snyk. Signed-off-by: Ruben Jenster --- go.mod | 4 ++++ go.sum | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 8da0b70c..2b43336f 100644 --- a/go.mod +++ b/go.mod @@ -10,4 +10,8 @@ require ( gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 ) +replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + +replace golang.org/x/text => golang.org/x/text v0.3.3 + go 1.13 diff --git a/go.sum b/go.sum index a976c6f9..065df4e6 100644 --- a/go.sum +++ b/go.sum @@ -24,13 +24,17 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From c627c74c13969de483d9c5b696a1422c097e5041 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 18 Feb 2021 21:25:35 +0100 Subject: [PATCH 170/373] Implement ubuntu docker containers with lxc build from source/ppa Signed-off-by: Ruben Jenster --- deployment/README.md | 39 +++++++++++ deployment/debian.buster-slim.Dockerfile | 9 +++ deployment/ubuntu-install-lxc.sh | 87 ++++++++++++++++++++++++ deployment/ubuntu.20.04.Dockerfile | 9 +++ deployment/ubuntu.21.04.Dockerfile | 9 +++ 5 files changed, 153 insertions(+) create mode 100644 deployment/README.md create mode 100644 deployment/debian.buster-slim.Dockerfile create mode 100755 deployment/ubuntu-install-lxc.sh create mode 100644 deployment/ubuntu.20.04.Dockerfile create mode 100644 deployment/ubuntu.21.04.Dockerfile diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 00000000..e471aebe --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,39 @@ +# Packaging + + docker build . + + docker build --no-cache -t helloap:0.1 -f ./Dockerfile . + +Run with buildah as fast as docker + + buildah bud ubuntu.20.04.Dockerfile + + buildah bud --no-cache --pull-never Dockerfile + +## TODO + +* Build Images with Github ? +* Automate script formatting with [shfmt](https://github.com/mvdan/sh) + + ~/go/bin/shfmt -w ubuntu-install-lxc.sh ubuntu-install-lxc.sh + + +## Buildah Oneliners + +#### Remove all working containers + + buildah containers -q | xargs buildah delete + +#### Remove all images without a name + + buildah images | grep '' | tr -s ' ' | cut -d ' ' -f 3 | xargs buildah rmi + +#### Select images by name with jq + + buildah images --json | jq '[ .[] | select( .names[] | contains("localhost")) ]' + + +## Resources + +* [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) + diff --git a/deployment/debian.buster-slim.Dockerfile b/deployment/debian.buster-slim.Dockerfile new file mode 100644 index 00000000..2463e888 --- /dev/null +++ b/deployment/debian.buster-slim.Dockerfile @@ -0,0 +1,9 @@ +FROM debian:buster-slim + +LABEL distribution=debian lxc_from=git lxc_version=master + +ENV LXC_INSTALL_FROM=git + +COPY ubuntu-install-lxc.sh /tmp +RUN /tmp/ubuntu-install-lxc.sh +RUN rm /tmp/ubuntu-install-lxc.sh diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh new file mode 100755 index 00000000..1742ab42 --- /dev/null +++ b/deployment/ubuntu-install-lxc.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# enable debug logging +set -x +# abort if subshell command exits non-zero +set -e + +# Bash auto indentation `gg=G` +# see https://unix.stackexchange.com/questions/19945/auto-indent-format-code-for-vim + +# see `man 5 os-release` and http://0pointer.de/blog/projects/os-release +. /etc/os-release + +apt_cleanup() { + export DEBIAN_FRONTEND=noninteractive + apt-get purge --yes $@ + apt-get autoremove --yes + apt-get clean + rm -rf /var/lib/apt/lists/* +} + +apt_install() { + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install --no-install-recommends --yes $@ +} + +LXC_PPA=${LXC_PPA:-http://ppa.launchpad.net/ubuntu-lxc/lxc-git-master/ubuntu} +LXC_PPA_KEY=${LXC_PPA_KEY:-93763AC528C8C52568951BE0D5495F657635B973} +LXC_PPA_KEYURL="${LXC_PPA_KEYURL:-http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$LXC_PPA_KEY}" +LXC_PPA_DEPS="curl gnupg2 ca-certificates" + +install_lxc_ppa() { + curl -sSL "$LXC_PPA_KEYURL" | apt-key add - >/dev/null + echo "deb $LXC_PPA $UBUNTU_CODENAME main" >/etc/apt/sources.list.d/lxc-git-master.list + apt-get update + apt_install lxc +} + +LXC_GIT_REPO="${LXC_GIT_REPO:-https://github.com/lxc/lxc.git}" +LXC_GIT_VERSION="${LXC_GIT_VERSION:-master}" + +LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} +LXC_INSTALL_COMMANDS=${LXC_INSTALL_COMMANDS:-no} +LXC_INSTALL_DOC=${LXC_INSTALL_DOC:-no} +LXC_INSTALL_API_DOCS=${LXC_INSTALL_API_DOCS:-no} + +LXC_BUILD_TOOLS="build-essential libtool automake pkg-config git ca-certificates" +LXC_BUILD_LIBS="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev" +LXC_BUILD_DEPS="$LXC_BUILD_TOOLS $LXC_BUILD_LIBS" +LXC_RUNTIME_DEPS="libseccomp2 libapparmor1 libbtrfs0 libdevmapper1.02.1 libcap2" + +install_lxc_git() { + local tmpdir=/tmp/lxc + git clone $LXC_GIT_REPO $tmpdir + cd $tmpdir + git reset --hard $LXC_GIT_VERSION + ./autogen.sh + ./configure --enable-bash=no --enable-seccomp=yes \ + --enable-capabilities=yes --enable-apparmor=yes \ + --enable-tools=$LXC_INSTALL_TOOLS --enable-commands=$LXC_INSTALL_COMMANDS \ + --enable-static=no --enable-examples=no \ + --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS + make install + git describe --tags >/usr/local/lib/liblxc.version.txt + echo /usr/local/lib >>/etc/ld.so.conf.d/local.conf + ldconfig + cd + rm -rf $tmpdir +} + +case $LXC_INSTALL_FROM in +"git") + apt_install $LXC_BUILD_DEPS $LXC_RUNTIME_DEPS + install_lxc_git + apt_cleanup $LXC_BUILD_DEPS + ;; +"ppa") + apt_install $LXC_PPA_DEPS + install_lxc_ppa + apt_cleanup $LXC_PPA_DEPS + ;; + *) + echo "Installation method 'LXC_INSTALL_FROM=$LXC_INSTALL_FROM' is unsupported" >&2 + echo "Supported installation methods are: 'git' and 'ppa'" >&2 + exit 1 + ;; +esac diff --git a/deployment/ubuntu.20.04.Dockerfile b/deployment/ubuntu.20.04.Dockerfile new file mode 100644 index 00000000..9a2587cd --- /dev/null +++ b/deployment/ubuntu.20.04.Dockerfile @@ -0,0 +1,9 @@ +FROM ubuntu:20.04 + +LABEL distribution=ubuntu lxc_from=git lxc_version=master + +ENV LXC_INSTALL_FROM=git + +COPY ubuntu-install-lxc.sh /tmp +RUN /tmp/ubuntu-install-lxc.sh +RUN rm /tmp/ubuntu-install-lxc.sh diff --git a/deployment/ubuntu.21.04.Dockerfile b/deployment/ubuntu.21.04.Dockerfile new file mode 100644 index 00000000..01ec20a6 --- /dev/null +++ b/deployment/ubuntu.21.04.Dockerfile @@ -0,0 +1,9 @@ +FROM ubuntu:21.04 + +LABEL distribution=ubuntu lxc_from=git lxc_version=master + +ENV LXC_INSTALL_FROM=git + +COPY ubuntu-install-lxc.sh /tmp +RUN /tmp/ubuntu-install-lxc.sh +RUN rm /tmp/ubuntu-install-lxc.sh From 4bef0bc9f80bba099f1a9f3a49800ab8faef2c04 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 10:28:17 +0100 Subject: [PATCH 171/373] Fix go vet findings. Signed-off-by: Ruben Jenster --- lxcontainer/container.go | 2 +- lxcontainer/utils.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 783bd56f..de819d04 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -20,7 +20,7 @@ type ContainerInfo struct { RuntimeRoot string BundlePath string - ConsoleSocket string `json;",omitempty"` + ConsoleSocket string `json:",omitempty"` // PidFile is the absolute path to the PID file of the container monitor process (crio-lxc-start) PidFile string MonitorCgroupDir string diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index f179e37c..24be11d5 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -127,7 +127,7 @@ func mkdirAll(path string, perm os.FileMode, uid int, gid int) error { if dir.IsDir() { return nil } - return &os.PathError{"mkdir", path, unix.ENOTDIR} + return &os.PathError{Op: "mkdir", Path: path, Err: unix.ENOTDIR} } // Slow path: make sure parent exists and then call Mkdir for path. From 52dfae3ae85691fe0cba82ab7158475d6614b173 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 10:56:40 +0100 Subject: [PATCH 172/373] Small impovements to lxc installation script. Signed-off-by: Ruben Jenster --- deployment/ubuntu-install-lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh index 1742ab42..4eaf8281 100755 --- a/deployment/ubuntu-install-lxc.sh +++ b/deployment/ubuntu-install-lxc.sh @@ -10,8 +10,9 @@ set -e # see `man 5 os-release` and http://0pointer.de/blog/projects/os-release . /etc/os-release +export DEBIAN_FRONTEND=noninteractive + apt_cleanup() { - export DEBIAN_FRONTEND=noninteractive apt-get purge --yes $@ apt-get autoremove --yes apt-get clean @@ -19,7 +20,6 @@ apt_cleanup() { } apt_install() { - export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends --yes $@ } From e58a3274d631d4a11e58c9fe443406a03ec41986 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 10:59:11 +0100 Subject: [PATCH 173/373] deployment: Implement crio-lxc installation. Signed-off-by: Ruben Jenster --- deployment/install-crio-lxc.sh | 60 ++++++++++++++++++++++++++++ deployment/ubuntu.criolxc.Dockerfile | 5 +++ 2 files changed, 65 insertions(+) create mode 100755 deployment/install-crio-lxc.sh create mode 100644 deployment/ubuntu.criolxc.Dockerfile diff --git a/deployment/install-crio-lxc.sh b/deployment/install-crio-lxc.sh new file mode 100755 index 00000000..56ea2c8a --- /dev/null +++ b/deployment/install-crio-lxc.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# enable debug logging +set -x +# abort if subshell command exits non-zero +set -e + +export DEBIAN_FRONTEND=noninteractive + +apt_cleanup() { + apt-get purge --yes $@ + apt-get autoremove --yes + apt-get clean + rm -rf /var/lib/apt/lists/* +} + +apt_install() { + apt-get update + apt-get install --no-install-recommends --yes $@ +} + +CRIO_LXC_GIT_REPO="${CRIO_LXC_GIT_REPO:-https://github.com/Drachenfels-GmbH/crio-lxc.git}" +CRIO_LXC_GIT_VERSION="${CRIO_LXC_GIT_VERSION:-master}" +CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" + +GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.linux-amd64.tar.gz}" +GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-013a489ebb3e24ef3d915abe5b94c3286c070dfe0818d5bca8108f1d6e8440d2}" + +install_golang() { + local archive="$(basename $GOLANG_SRC)" + cd /tmp + wget --quiet $GOLANG_SRC + echo "$GOLANG_CHECKSUM $archive" | sha256sum -c + tar -C /usr/local -xzf $archive + export PATH=/usr/local/go/bin:$PATH + rm /tmp/$archive +} + +uninstall_golang() { + rm -rf $(go env GOPATH) + rm -rf $(go env GOCACHE) + rm -rf $(go env GOROOT) +} + +install_crio_lxc() { + local tmpdir=/tmp/lxc + git clone $CRIO_LXC_GIT_REPO $tmpdir + cd $tmpdir + git reset --hard $CIO_LXC_GIT_VERSION + # lxc installed from source with dafault installation prefix is prefered + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH + make install + cd + rm -rf $tmpdir +} + +apt_install $CRIO_LXC_BUILD_DEPS +install_golang +install_crio_lxc +uninstall_golang +apt_cleanup $CRIO_LXC_BUILD_DEPS diff --git a/deployment/ubuntu.criolxc.Dockerfile b/deployment/ubuntu.criolxc.Dockerfile new file mode 100644 index 00000000..b1bf7a16 --- /dev/null +++ b/deployment/ubuntu.criolxc.Dockerfile @@ -0,0 +1,5 @@ +FROM debian-buster-lxc:0.1 + +COPY install-crio-lxc.sh /tmp +RUN /tmp/install-crio-lxc.sh +RUN rm /tmp/install-crio-lxc.sh From 90bf4cb09a59e6ad9f976d87afb207fe32f1ed26 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 14:19:32 +0100 Subject: [PATCH 174/373] deployment: Move pkg manager helpers to utils.sh Signed-off-by: Ruben Jenster --- deployment/install-crio-lxc.sh | 37 +++------------------------- deployment/ubuntu-install-lxc.sh | 18 +++----------- deployment/ubuntu.20.04.Dockerfile | 5 ++-- deployment/ubuntu.criolxc.Dockerfile | 6 +++-- deployment/utils.sh | 35 ++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 53 deletions(-) create mode 100755 deployment/utils.sh diff --git a/deployment/install-crio-lxc.sh b/deployment/install-crio-lxc.sh index 56ea2c8a..4ba9eaf6 100755 --- a/deployment/install-crio-lxc.sh +++ b/deployment/install-crio-lxc.sh @@ -4,42 +4,11 @@ set -x # abort if subshell command exits non-zero set -e -export DEBIAN_FRONTEND=noninteractive - -apt_cleanup() { - apt-get purge --yes $@ - apt-get autoremove --yes - apt-get clean - rm -rf /var/lib/apt/lists/* -} - -apt_install() { - apt-get update - apt-get install --no-install-recommends --yes $@ -} +. $(dirname $(readlink -f $0))/utils.sh CRIO_LXC_GIT_REPO="${CRIO_LXC_GIT_REPO:-https://github.com/Drachenfels-GmbH/crio-lxc.git}" CRIO_LXC_GIT_VERSION="${CRIO_LXC_GIT_VERSION:-master}" -CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" - -GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.linux-amd64.tar.gz}" -GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-013a489ebb3e24ef3d915abe5b94c3286c070dfe0818d5bca8108f1d6e8440d2}" - -install_golang() { - local archive="$(basename $GOLANG_SRC)" - cd /tmp - wget --quiet $GOLANG_SRC - echo "$GOLANG_CHECKSUM $archive" | sha256sum -c - tar -C /usr/local -xzf $archive - export PATH=/usr/local/go/bin:$PATH - rm /tmp/$archive -} - -uninstall_golang() { - rm -rf $(go env GOPATH) - rm -rf $(go env GOCACHE) - rm -rf $(go env GOROOT) -} +CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" install_crio_lxc() { local tmpdir=/tmp/lxc @@ -57,4 +26,4 @@ apt_install $CRIO_LXC_BUILD_DEPS install_golang install_crio_lxc uninstall_golang -apt_cleanup $CRIO_LXC_BUILD_DEPS +apt_clean $CRIO_LXC_BUILD_DEPS diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh index 4eaf8281..f29beebf 100755 --- a/deployment/ubuntu-install-lxc.sh +++ b/deployment/ubuntu-install-lxc.sh @@ -10,19 +10,7 @@ set -e # see `man 5 os-release` and http://0pointer.de/blog/projects/os-release . /etc/os-release -export DEBIAN_FRONTEND=noninteractive - -apt_cleanup() { - apt-get purge --yes $@ - apt-get autoremove --yes - apt-get clean - rm -rf /var/lib/apt/lists/* -} - -apt_install() { - apt-get update - apt-get install --no-install-recommends --yes $@ -} +. $(dirname $(readlink -f $0))/utils.sh LXC_PPA=${LXC_PPA:-http://ppa.launchpad.net/ubuntu-lxc/lxc-git-master/ubuntu} LXC_PPA_KEY=${LXC_PPA_KEY:-93763AC528C8C52568951BE0D5495F657635B973} @@ -72,12 +60,12 @@ case $LXC_INSTALL_FROM in "git") apt_install $LXC_BUILD_DEPS $LXC_RUNTIME_DEPS install_lxc_git - apt_cleanup $LXC_BUILD_DEPS + apt_clean $LXC_BUILD_DEPS ;; "ppa") apt_install $LXC_PPA_DEPS install_lxc_ppa - apt_cleanup $LXC_PPA_DEPS + apt_clean $LXC_PPA_DEPS ;; *) echo "Installation method 'LXC_INSTALL_FROM=$LXC_INSTALL_FROM' is unsupported" >&2 diff --git a/deployment/ubuntu.20.04.Dockerfile b/deployment/ubuntu.20.04.Dockerfile index 9a2587cd..ab0663e5 100644 --- a/deployment/ubuntu.20.04.Dockerfile +++ b/deployment/ubuntu.20.04.Dockerfile @@ -3,7 +3,8 @@ FROM ubuntu:20.04 LABEL distribution=ubuntu lxc_from=git lxc_version=master ENV LXC_INSTALL_FROM=git +ENV LXC_GIT_VERSION=35a68d6df2c240b6604625bd34979ba64db25de7 -COPY ubuntu-install-lxc.sh /tmp +COPY ubuntu-install-lxc.sh utils.sh /tmp RUN /tmp/ubuntu-install-lxc.sh -RUN rm /tmp/ubuntu-install-lxc.sh +RUN rm /tmp/ubuntu-install-lxc.sh /tmp/utils.sh diff --git a/deployment/ubuntu.criolxc.Dockerfile b/deployment/ubuntu.criolxc.Dockerfile index b1bf7a16..9a8f64b2 100644 --- a/deployment/ubuntu.criolxc.Dockerfile +++ b/deployment/ubuntu.criolxc.Dockerfile @@ -1,5 +1,7 @@ FROM debian-buster-lxc:0.1 -COPY install-crio-lxc.sh /tmp +ENV CRIO_LXC_GIT_VERSION=master + +COPY install-crio-lxc.sh utils.sh /tmp RUN /tmp/install-crio-lxc.sh -RUN rm /tmp/install-crio-lxc.sh +RUN rm /tmp/install-crio-lxc.sh /tmp/utils.sh diff --git a/deployment/utils.sh b/deployment/utils.sh new file mode 100755 index 00000000..cd11fc5b --- /dev/null +++ b/deployment/utils.sh @@ -0,0 +1,35 @@ +#!/bin/sh +export DEBIAN_FRONTEND=noninteractive + +apt_install() { + apt-get update + apt-get install --no-install-recommends --yes $@ +} + +apt_clean() { + apt-get purge --yes $@ + apt-get autoremove --yes + apt-get clean + rm -rf /var/lib/apt/lists/* +} + +GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.linux-amd64.tar.gz}" +GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-013a489ebb3e24ef3d915abe5b94c3286c070dfe0818d5bca8108f1d6e8440d2}" + +install_golang() { + local archive="$(basename $GOLANG_SRC)" + local destdir"/tmp" + + cd $destdir + wget --quiet $GOLANG_SRC + echo "$GOLANG_CHECKSUM $archive" | sha256sum -c + tar -xzf $archive + export PATH=$destdir/go/bin:$PATH + rm $destdir/$archive +} + +uninstall_golang() { + rm -rf $(go env GOPATH) + rm -rf $(go env GOCACHE) + rm -rf $(go env GOROOT) +} From ee32b8949d26571d949f7c1d56add5df63669587 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 16:45:14 +0100 Subject: [PATCH 175/373] deployment: Format shell scripts with shfmt. Signed-off-by: Ruben Jenster --- deployment/ubuntu-install-lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh index f29beebf..0a4185e2 100755 --- a/deployment/ubuntu-install-lxc.sh +++ b/deployment/ubuntu-install-lxc.sh @@ -67,9 +67,9 @@ case $LXC_INSTALL_FROM in install_lxc_ppa apt_clean $LXC_PPA_DEPS ;; - *) +*) echo "Installation method 'LXC_INSTALL_FROM=$LXC_INSTALL_FROM' is unsupported" >&2 - echo "Supported installation methods are: 'git' and 'ppa'" >&2 + echo "Supported installation methods are: 'git' and 'ppa'" >&2 exit 1 ;; esac From f592ba35bcae4c9a6aae74eb50db2394987f1127 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 16:46:42 +0100 Subject: [PATCH 176/373] deployment: Update README. Signed-off-by: Ruben Jenster --- deployment/README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/deployment/README.md b/deployment/README.md index e471aebe..1daf392b 100644 --- a/deployment/README.md +++ b/deployment/README.md @@ -36,4 +36,32 @@ Run with buildah as fast as docker ## Resources * [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +* [Reducing the size of the Debian Installation Footprint](https://wiki.debian.org/ReduceDebian) + +## Container Changlog + +Provide some information about what has changed in an container upgrade. + +* Changelog for package upgrades +* List of Modified files (mode and size, maybe rsync like output ?) + +## apt Package Changelog for debian/ubuntu + +Create a list of installed packages and versions. + +https://man7.org/linux/man-pages/man1/dpkg-query.1.html + +dpkg-query -W -f='{Pkg:"${binary:Package}", Version:"${Version}",Category:"${Section}"}\n' + +## List changed files + +### Packages installed from source ? + +* Are handled by the image layer +* Before squashing the image changes in the image layer should be listed + +### Track file changes with overlay + +* mount overlay on rootfs, make install, unmount, tar overlay and create package from it. +* similar to archlinux `makepkg` ... From 7b9d94204bdec0f1bd09e9c0e8c7048727a406fe Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 17:21:21 +0100 Subject: [PATCH 177/373] Update go module dependencies. Signed-off-by: Ruben Jenster --- go.mod | 6 +++++- go.sum | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 2b43336f..ac915aa1 100644 --- a/go.mod +++ b/go.mod @@ -2,12 +2,16 @@ module github.com/lxc/crio-lxc require ( github.com/creack/pty v1.1.11 + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/kr/pretty v0.2.1 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/rs/zerolog v1.20.0 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 github.com/urfave/cli/v2 v2.3.0 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 + gopkg.in/yaml.v2 v2.4.0 // indirect ) replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad diff --git a/go.sum b/go.sum index 065df4e6..516b395b 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,17 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -20,8 +25,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -38,6 +43,11 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 h1:YcCjv1g/OoEJ93hK3p+5MhPyuIMD9FwOYF5f4D7rNKk= gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= From 9bacb9d9a3e331c3b52fd6c94406e45c587f80e5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 17:21:46 +0100 Subject: [PATCH 178/373] Format shell script. Signed-off-by: Ruben Jenster --- utils/cglist.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/cglist.sh b/utils/cglist.sh index 5d1afa29..7b65bdc7 100755 --- a/utils/cglist.sh +++ b/utils/cglist.sh @@ -3,5 +3,5 @@ cd /sys/fs/cgroup/kubepods.slice for cg in $(find . -name cgroup.controllers); do - echo "$(dirname $cg) [$(cat $cg)]" + echo "$(dirname $cg) [$(cat $cg)]" done From f112ea25a041dde71d964e0543581bd910423aa5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 7 Mar 2021 03:26:30 +0100 Subject: [PATCH 179/373] Change module import path. Signed-off-by: Ruben Jenster --- cmd/cli.go | 2 +- go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 66db985f..ed863f3c 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -10,7 +10,7 @@ import ( "path/filepath" "time" - "github.com/lxc/crio-lxc/lxcontainer" + "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer" "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) diff --git a/go.mod b/go.mod index ac915aa1..e6a6f471 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/lxc/crio-lxc +module github.com/Drachenfels-GmbH/crio-lxc require ( github.com/creack/pty v1.1.11 From 0d298eb1313597963575344daf1be69c72bdee36 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 7 Mar 2021 10:05:50 +0100 Subject: [PATCH 180/373] Allow spec without Linux.Resources set. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 5d37cbda..7cd1ce2f 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -364,6 +364,10 @@ func ensureDefaultDevices(c *Runtime, spec *specs.Spec) error { pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] + if spec.Linux.Resources == nil { + spec.Linux.Resources = &specs.LinuxResources{} + } + // add missing default devices for _, dev := range devices { if !isDeviceEnabled(spec, dev) { From 8adb723fb63cacec7a499522437ea47b6146ce07 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 15:41:22 +0100 Subject: [PATCH 181/373] deployment: Fix typo in helper script. Signed-off-by: Ruben Jenster --- deployment/utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/utils.sh b/deployment/utils.sh index cd11fc5b..3bcd62a4 100755 --- a/deployment/utils.sh +++ b/deployment/utils.sh @@ -18,7 +18,7 @@ GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-013a489ebb3e24ef3d915abe5b94c3286c070dfe0818 install_golang() { local archive="$(basename $GOLANG_SRC)" - local destdir"/tmp" + local destdir="/tmp" cd $destdir wget --quiet $GOLANG_SRC From 010a37ced47fa9a1bb9a2722da875e0f02b8761f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 15:48:31 +0100 Subject: [PATCH 182/373] Improve error messages for pidfile creation. Signed-off-by: Ruben Jenster --- lxcontainer/utils.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 24be11d5..2957907c 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -19,17 +19,21 @@ func CreatePidFile(path string, pid int) error { // #nosec f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0600) if err != nil { - return err + return fmt.Errorf("failed to create temporary PID file %q: %w", tmpName, err) } _, err = fmt.Fprintf(f, "%d", pid) if err != nil { - return err + return fmt.Errorf("failed to write to temporary PID file %q: %w", tmpName, err) } err = f.Close() if err != nil { - return err + return fmt.Errorf("failed to close temporary PID file %q: %w", tmpName, err) } - return os.Rename(tmpName, path) + err = os.Rename(tmpName, path) + if err != nil { + return fmt.Errorf("failed to rename temporary PID file %q to %q: %w", tmpName, path, err) + } + return nil } func canExecute(cmds ...string) error { From 5c70f9e4cdd6da286a9b50c3643729af762bd1db Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 15:50:34 +0100 Subject: [PATCH 183/373] Set Container and LogFile to nil on release. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 65b37c20..b39c28fb 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -164,9 +164,12 @@ func (c Runtime) Release() error { if err := c.Container.Release(); err != nil { c.Log.Error().Err(err).Msg("failed to release container") } + c.Container = nil } if c.LogFile != nil { - return c.LogFile.Close() + err := c.LogFile.Close() + c.LogFile = nil + return err } return nil } From 5baac15da365a0d38ea3198da81d1420c0bbfa14 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 15:55:51 +0100 Subject: [PATCH 184/373] Gracefully handle missing values in runtime spec. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 7cd1ce2f..b0a1f1fb 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -41,6 +41,27 @@ func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { c.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } + if spec.Linux.Resources == nil { + spec.Linux.Resources = &specs.LinuxResources{} + } + + if spec.Linux.Devices == nil { + spec.Linux.Devices = make([]specs.LinuxDevice, 0, 20) + } + + if spec.Process == nil { + return fmt.Errorf("spec.Process is nil") + } + + if len(spec.Process.Args) == 0 { + return fmt.Errorf("specs.Process.Args is empty") + } + + if spec.Process.Cwd == "" { + c.Log.Info().Msg("specs.Process.Cwd is unset defaulting to '/'") + spec.Process.Cwd = "/" + } + err = c.createContainer(spec) if err != nil { return errorf("failed to create container: %w", err) From 978bc4de65cfb1c045970c6e33c3a42a8ad79f0f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 21:01:54 +0100 Subject: [PATCH 185/373] Add hook that runs at the end of createContainer. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index b39c28fb..2b894386 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -38,6 +38,12 @@ type Runtime struct { ContainerHook string Log zerolog.Logger + + // runtime hooks (not OCI runtime hooks) + + // AfterCreateContainer is called right after creating the container runtime directory and descriptor, + // and before creating the lxc 'config' file for the container. + AfterCreateContainer func(c *Runtime) error } // createContainer creates a new container. @@ -89,7 +95,14 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { return err } c.Container = container - return c.setContainerLogLevel() + if err := c.setContainerLogLevel(); err != nil { + return err + } + + if c.AfterCreateContainer != nil { + return c.AfterCreateContainer(c) + } + return nil } // loadContainer checks for the existence of the lxc config file. From 7a4638dc95662ee5c7775752502e9886489a3fb5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 9 Mar 2021 21:11:09 +0100 Subject: [PATCH 186/373] Add kubernetes node build script. Signed-off-by: Ruben Jenster --- deployment/install-node.sh | 142 +++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 deployment/install-node.sh diff --git a/deployment/install-node.sh b/deployment/install-node.sh new file mode 100755 index 00000000..631e600c --- /dev/null +++ b/deployment/install-node.sh @@ -0,0 +1,142 @@ +#!/bin/sh +# enable debug logging +set -x +# abort if subshell command exits non-zero +set -e + +. $(dirname $(readlink -f $0))/utils.sh +CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" + +install_cni() { + local repo="${CNI_PLUGINS_GIT_REPO:-https://github.com/containernetworking/plugins.git}" + local version="${CNI_PLUGINS_GIT_VERSION:-v0.9.1}" + local tmpdir=/tmp/cni-plugins + + git clone $repo $tmpdir + cd $tmpdir + git reset --hard $version + + ./build_linux.sh + export CNI_PLUGIN_DIR=/usr/local/cni/bin + mkdir -p $CNI_PLUGIN_DIR + cp bin/* $CNI_PLUGIN_DIR + + cd / + rm -rf $tmpdir +} + +install_conmon() { + local repo="${CONMON_GIT_REPO:-https://github.com/containers/conmon.git}" + local version="${CONMON_GIT_VERSION:-v2.0.27}" + local tmpdir=/tmp/conmon + + git clone $repo $tmpdir + cd $tmpdir + git reset --hard $version + + make clean + make install + + cd / + rm -rf $tmpdir +} + +install_crio() { + local repo="${CRIO_GIT_REPO:-https://github.com/cri-o/cri-o.git}" + local version="${CRIO_GIT_VERSION:-v1.20.1}" + + local tmpdir=/tmp/cri-o + git clone $repo $tmpdir + cd $tmpdir + git reset --hard $version + + make install + + cd / + rm -rf $tmpdir + + # configure cri-o + PREFIX=/usr/local + CRIO_LXC_ROOT=/run/crio-lxc + # environment for `crio config` + export CONTAINER_CONMON=${PREFIX}/bin/conmon + export CONTAINER_PINNS_PATH=${PREFIX}/bin/pinns + export CONTAINER_DEFAULT_RUNTIME=crio-lxc + export CONTAINER_RUNTIMES=crio-lxc:${PREFIX}/bin/crio-lxc:$CRIO_LXC_ROOT + export CONTAINER_CNI_PLUGIN_DIR=$CNI_PLUGIN_DIR + + crio config >/etc/crio/crio.conf + + # Modify systemd service file to run with full privileges. + # This is required for the runtime to set cgroupv2 device controller eBPF. + sed -i 's/ExecStart=\//ExecStart=+\//' /usr/local/lib/systemd/system/crio.service +} + +install_kubernetes() { + local arch="linux-amd64" + # TODO maybe make arch a global variable ${GOHOSTOS}-${GOHOSTARCH} + local archive="kubernetes-server-$arch.tar.gz" + # see https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md + local sum="37738bc8430b0832f32c6d13cdd68c376417270568cd9b31a1ff37e96cfebcc1e2970c72bed588f626e35ed8273671c77200f0d164e67809b5626a2a99e3c5f5" + K8S_CHECKSUM="${KUBERNETES_CHECKSUM:-${sum}}" + K8S_RELEASE="${KUBERNETES_RELEASE:-1.20.4}" + local destdir="/usr/local/bin" + + cd /tmp + wget --quiet https://dl.k8s.io/v${K8S_RELEASE}/$archive + echo "$K8S_CHECKSUM $archive" | sha512sum -c + tar -x -z -f $archive -C $destdir --strip-components=3 \ + kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet + rm $archive + + cat >/etc/systemd/system/kubelet.service <<-EOF + [Unit] + Description=kubelet: The Kubernetes Node Agent + Documentation=http://kubernetes.io/docs/ + + [Service] + ExecStart=$destdir/kubelet + Restart=always + StartLimitInterval=0 + RestartSec=10 + + [Install] + WantedBy=multi-user.target + EOF + + mkdir -p /etc/systemd/system/kubelet.service.d + cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<-EOF + [Service] + Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" + Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" + # This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically + EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env + # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use + # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. + EnvironmentFile=-/etc/default/kubelet + ExecStart= + ExecStart=$destdir/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS + EOF + + #systemctl daemon-reload + systemctl enable kubelet.service +} + +# TODO let install functions append build dependencies and runtime dependencies +BUILD_LIBS="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev" +BUILD_TOOLCHAIN="wget ca-certificates git build-essential libtool make automake pkg-config" +BUILD_DEPS="$BUILD_LIBS $BUILD_TOOLCHAIN" + +K8S_RUNTIME_DEPS="ebtables iptables conntrack" +RUNTIME_DEPS="$K8S_RUNTIME_DEPS tzdata systemd" + +PKGS="$BUILD_DEPS $RUNTIME_DEPS" + +apt_install $PKGS +install_golang +install_cni +install_conmon +install_crio +install_kubernetes +uninstall_golang +apt_clean $BUILD_DEPS From 0c86a8a5bc3b7ac61440c483de3da1a29ef1fa25 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 10 Mar 2021 19:48:48 +0100 Subject: [PATCH 187/373] Create stdio symlinks in /dev Signed-off-by: Ruben Jenster --- cmd/container-hook/hook.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmd/container-hook/hook.c b/cmd/container-hook/hook.c index 9ce889ff..1157f73e 100644 --- a/cmd/container-hook/hook.c +++ b/cmd/container-hook/hook.c @@ -192,6 +192,24 @@ int create_devices_at(int rootfs, int runtime, const char *devices) goto out; } } + + int ret; + + ret = symlink("/proc/self/fd/0", "/dev/stdin"); + if (ret == -1) { + printf("failed to create symlink /dev/stdin -> /proc/self/fd/0 : %s\n", strerror(errno)); + goto out; + } + ret = symlink("/proc/self/fd/1", "/dev/stdout"); + if (ret == -1) { + printf("failed to create symlink /dev/stdout -> /proc/self/fd/1 : %s\n", strerror(errno)); + goto out; + } + ret = symlink("/proc/self/fd/2", "/dev/stderr"); + if (ret == -1) { + printf("failed to create symlink /dev/stderr -> /proc/self/fd/2 : %s\n", strerror(errno)); + goto out; + } out: fclose(f); return (errno == 0) ? 0 : -1; From 397d758779997590dc8ed70b5579551065a33b19 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 10 Mar 2021 19:48:53 +0100 Subject: [PATCH 188/373] Revert "Create stdio symlinks in /dev" This reverts commit 80deddb4364aec1483b2569f76a192d5565c4697. Signed-off-by: Ruben Jenster --- cmd/container-hook/hook.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/cmd/container-hook/hook.c b/cmd/container-hook/hook.c index 1157f73e..9ce889ff 100644 --- a/cmd/container-hook/hook.c +++ b/cmd/container-hook/hook.c @@ -192,24 +192,6 @@ int create_devices_at(int rootfs, int runtime, const char *devices) goto out; } } - - int ret; - - ret = symlink("/proc/self/fd/0", "/dev/stdin"); - if (ret == -1) { - printf("failed to create symlink /dev/stdin -> /proc/self/fd/0 : %s\n", strerror(errno)); - goto out; - } - ret = symlink("/proc/self/fd/1", "/dev/stdout"); - if (ret == -1) { - printf("failed to create symlink /dev/stdout -> /proc/self/fd/1 : %s\n", strerror(errno)); - goto out; - } - ret = symlink("/proc/self/fd/2", "/dev/stderr"); - if (ret == -1) { - printf("failed to create symlink /dev/stderr -> /proc/self/fd/2 : %s\n", strerror(errno)); - goto out; - } out: fclose(f); return (errno == 0) ? 0 : -1; From 2aff27c695e3a5d72f2bfa9c4e28f999f2f43915 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 00:41:02 +0100 Subject: [PATCH 189/373] deployment: Update node installation script. Signed-off-by: Ruben Jenster --- INSTALL.md | 3 +- deployment/install-node.sh | 44 ++++++++++++++++++++-------- deployment/ubuntu.criolxc.Dockerfile | 2 +- deployment/ubuntu.node.Dockerfile | 5 ++++ go.mod | 6 ++-- go.sum | 16 +++++----- 6 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 deployment/ubuntu.node.Dockerfile diff --git a/INSTALL.md b/INSTALL.md index bb317fac..cfd3451e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -139,7 +139,8 @@ mountopt = "nodev,redirect_dir=off,metacopy=off" #### HTTP proxy -If you're system is proxied you can add the proxy environment variables to `/etc/default/crio` +If you need a HTTP proxy for internet access you may have to set the proxy environment variables in `/etc/default/crio` +for crio-o to be able to fetch images from remote repositories. ``` http_proxy="http://myproxy:3128" diff --git a/deployment/install-node.sh b/deployment/install-node.sh index 631e600c..0bbf4a37 100755 --- a/deployment/install-node.sh +++ b/deployment/install-node.sh @@ -72,19 +72,34 @@ install_crio() { sed -i 's/ExecStart=\//ExecStart=+\//' /usr/local/lib/systemd/system/crio.service } +install_cri_tools() { + local release="${CRI_TOOLS_RELEASE:-v1.20.0}" + local checksum="${CRI_TOOLS_CHECKSUM:-44d5f550ef3f41f9b53155906e0229ffdbee4b19452b4df540265e29572b899c}" + local arch="linux-amd64" + local archive="crictl-${release}-${arch}.tar.gz" + local url="https://github.com/kubernetes-sigs/cri-tools/releases/download/$release/$archive" + local destdir="/usr/local/bin" + + cd /tmp + wget --quiet $url + echo "$checksum $archive" | sha256sum -c + tar -x -z -f $archive -C $destdir + rm $archive +} + install_kubernetes() { + # see https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md + local checksum="${K8S_CHECKSUM:-37738bc8430b0832f32c6d13cdd68c376417270568cd9b31a1ff37e96cfebcc1e2970c72bed588f626e35ed8273671c77200f0d164e67809b5626a2a99e3c5f5}" + local release="${K8S_RELEASE:-v1.20.4}" local arch="linux-amd64" # TODO maybe make arch a global variable ${GOHOSTOS}-${GOHOSTARCH} local archive="kubernetes-server-$arch.tar.gz" - # see https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md - local sum="37738bc8430b0832f32c6d13cdd68c376417270568cd9b31a1ff37e96cfebcc1e2970c72bed588f626e35ed8273671c77200f0d164e67809b5626a2a99e3c5f5" - K8S_CHECKSUM="${KUBERNETES_CHECKSUM:-${sum}}" - K8S_RELEASE="${KUBERNETES_RELEASE:-1.20.4}" + local url="https://dl.k8s.io/${release}/${archive}" local destdir="/usr/local/bin" cd /tmp - wget --quiet https://dl.k8s.io/v${K8S_RELEASE}/$archive - echo "$K8S_CHECKSUM $archive" | sha512sum -c + wget --quiet $url + echo "$checksum $archive" | sha512sum -c tar -x -z -f $archive -C $destdir --strip-components=3 \ kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet rm $archive @@ -123,19 +138,24 @@ install_kubernetes() { } # TODO let install functions append build dependencies and runtime dependencies -BUILD_LIBS="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev" -BUILD_TOOLCHAIN="wget ca-certificates git build-essential libtool make automake pkg-config" -BUILD_DEPS="$BUILD_LIBS $BUILD_TOOLCHAIN" +BUILD_DEPS_CONMON="libglib2.0-dev" +BUILD_DEPS_CRIO="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev" +BUILD_DEPS="wget ca-certificates git build-essential libtool make automake pkg-config" +BUILD_DEPS="${BUILD_DEPS} ${BUILD_DEPS_CONMON} ${BUILD_DEPS_CRIO}" -K8S_RUNTIME_DEPS="ebtables iptables conntrack" -RUNTIME_DEPS="$K8S_RUNTIME_DEPS tzdata systemd" +DEPS_CONMON="libglib2.0-0" +DEPS_CRIO="tzdata" +DEPS_K8S="ebtables ethtool socat conntrack iproute2 iptables" +DEPS="$DEPS_CONMON $DEPS_CRIO $DEPS_K8S" +DEPS="$DEPS systemd" -PKGS="$BUILD_DEPS $RUNTIME_DEPS" +PKGS="$DEPS $BUILD_DEPS" apt_install $PKGS install_golang install_cni install_conmon +install_cri_tools install_crio install_kubernetes uninstall_golang diff --git a/deployment/ubuntu.criolxc.Dockerfile b/deployment/ubuntu.criolxc.Dockerfile index 9a8f64b2..4fc4dc9a 100644 --- a/deployment/ubuntu.criolxc.Dockerfile +++ b/deployment/ubuntu.criolxc.Dockerfile @@ -1,4 +1,4 @@ -FROM debian-buster-lxc:0.1 +FROM myimage ENV CRIO_LXC_GIT_VERSION=master diff --git a/deployment/ubuntu.node.Dockerfile b/deployment/ubuntu.node.Dockerfile new file mode 100644 index 00000000..0410147b --- /dev/null +++ b/deployment/ubuntu.node.Dockerfile @@ -0,0 +1,5 @@ +FROM localhost/criolxc:0.1 + +COPY install-node.sh utils.sh /tmp +RUN /tmp/install-node.sh +RUN rm /tmp/install-node.sh /tmp/utils.sh diff --git a/go.mod b/go.mod index e6a6f471..e6846658 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,17 @@ module github.com/Drachenfels-GmbH/crio-lxc require ( + github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/creack/pty v1.1.11 github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.2.1 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/rs/zerolog v1.20.0 - github.com/stretchr/testify v1.4.0 + github.com/stretchr/testify v1.6.1 github.com/urfave/cli/v2 v2.3.0 - golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 + golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 - gopkg.in/yaml.v2 v2.4.0 // indirect ) replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad diff --git a/go.sum b/go.sum index 516b395b..117c0bf0 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -25,8 +26,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -35,8 +36,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIwSCiDQJxpBxmvqb1N1c= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -47,7 +48,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881 h1:YcCjv1g/OoEJ93hK3p+5MhPyuIMD9FwOYF5f4D7rNKk= gopkg.in/lxc/go-lxc.v2 v2.0.0-20210205143421-c4b883be4881/go.mod h1:4K0lbUXeslpmjwJZyW1lI6s5j97mrsj4+kpYwwvuLXo= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 304c808021a89cca5647e77b87df425ab40f7b95 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 07:16:03 +0100 Subject: [PATCH 190/373] Fix spec deserialization. Signed-off-by: Ruben Jenster --- cmd/cli.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index ed863f3c..0ea50154 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -525,9 +525,10 @@ func doExec(ctx *cli.Context) error { return nil } -func readSpec(src string) (spec *specs.Spec, err error) { - err = lxcontainer.DecodeFileJSON(spec, src) - return +func readSpec(src string) (*specs.Spec, error) { + spec := new(specs.Spec) + err := lxcontainer.DecodeFileJSON(spec, src) + return spec, err } func readSpecProcess(src string) (*specs.Process, error) { From a815e112529b5ff2a4963488261293f4abf75995 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 07:58:02 +0100 Subject: [PATCH 191/373] Fix nil pointer in device create Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index b0a1f1fb..de2c5d93 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -424,7 +424,7 @@ func writeDevices(dst string, spec *specs.Spec) error { uid = *d.UID } gid := spec.Process.User.GID - if d.GID == nil { + if d.GID != nil { gid = *d.GID } mode := os.FileMode(0600) From b76f58499a6a1728fa1ed65141c16512ebc84e4c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 07:58:44 +0100 Subject: [PATCH 192/373] Do not fail if CgroupsPath is empty. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 2b894386..420fcbbd 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -69,7 +69,8 @@ func (c *Runtime) createContainer(spec *specs.Spec) error { } if spec.Linux.CgroupsPath == "" { - return fmt.Errorf("empty cgroups path in spec") + //return fmt.Errorf("empty cgroups path in spec") + spec.Linux.CgroupsPath = "foo.slice" } if c.SystemdCgroup { c.CgroupDir = parseSystemdCgroupPath(spec.Linux.CgroupsPath) From b665b3cedc02d4edbcca7f1828e5dece36057d20 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 08:35:23 +0100 Subject: [PATCH 193/373] Upgrade deployment scripts. Signed-off-by: Ruben Jenster --- deployment/install-crio-lxc.sh | 2 +- deployment/install-node.sh | 4 ++-- deployment/ubuntu.criolxc.Dockerfile | 4 ++-- deployment/ubuntu.node.Dockerfile | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deployment/install-crio-lxc.sh b/deployment/install-crio-lxc.sh index 4ba9eaf6..176906b3 100755 --- a/deployment/install-crio-lxc.sh +++ b/deployment/install-crio-lxc.sh @@ -14,7 +14,7 @@ install_crio_lxc() { local tmpdir=/tmp/lxc git clone $CRIO_LXC_GIT_REPO $tmpdir cd $tmpdir - git reset --hard $CIO_LXC_GIT_VERSION + git reset --hard $CRIO_LXC_GIT_VERSION # lxc installed from source with dafault installation prefix is prefered export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH make install diff --git a/deployment/install-node.sh b/deployment/install-node.sh index 0bbf4a37..bd71368f 100755 --- a/deployment/install-node.sh +++ b/deployment/install-node.sh @@ -140,11 +140,11 @@ install_kubernetes() { # TODO let install functions append build dependencies and runtime dependencies BUILD_DEPS_CONMON="libglib2.0-dev" BUILD_DEPS_CRIO="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev" -BUILD_DEPS="wget ca-certificates git build-essential libtool make automake pkg-config" +BUILD_DEPS="wget git build-essential libtool make automake pkg-config" BUILD_DEPS="${BUILD_DEPS} ${BUILD_DEPS_CONMON} ${BUILD_DEPS_CRIO}" DEPS_CONMON="libglib2.0-0" -DEPS_CRIO="tzdata" +DEPS_CRIO="tzdata ca-certificates" DEPS_K8S="ebtables ethtool socat conntrack iproute2 iptables" DEPS="$DEPS_CONMON $DEPS_CRIO $DEPS_K8S" DEPS="$DEPS systemd" diff --git a/deployment/ubuntu.criolxc.Dockerfile b/deployment/ubuntu.criolxc.Dockerfile index 4fc4dc9a..d485a12a 100644 --- a/deployment/ubuntu.criolxc.Dockerfile +++ b/deployment/ubuntu.criolxc.Dockerfile @@ -1,6 +1,6 @@ -FROM myimage +FROM lxc:0.1 -ENV CRIO_LXC_GIT_VERSION=master +ENV CRIO_LXC_GIT_VERSION=origin/standalone COPY install-crio-lxc.sh utils.sh /tmp RUN /tmp/install-crio-lxc.sh diff --git a/deployment/ubuntu.node.Dockerfile b/deployment/ubuntu.node.Dockerfile index 0410147b..49cbb02f 100644 --- a/deployment/ubuntu.node.Dockerfile +++ b/deployment/ubuntu.node.Dockerfile @@ -1,4 +1,4 @@ -FROM localhost/criolxc:0.1 +FROM localhost/criolxc:0.4 COPY install-node.sh utils.sh /tmp RUN /tmp/install-node.sh From 1fddfcc0d5c534955a8faa8150a6453015c7acde Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 09:03:57 +0100 Subject: [PATCH 194/373] Disable rslave mount option for cgroup2. Signed-off-by: Ruben Jenster --- lxcontainer/mount.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index 8b565767..02db1427 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -37,7 +37,7 @@ func filterMountOptions(clxc *Runtime, fs string, opts []string) []string { return removeMountOptions(clxc, fs, opts, "rprivate", "tmpcopyup") case "cgroup2": // TODO make this configurable per filesystem - return removeMountOptions(clxc, fs, opts, "private") + return removeMountOptions(clxc, fs, opts, "private", "rslave") } return opts } From d26082b6f9e390b31cc90535fa258fd79b0ae5b1 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 11 Mar 2021 16:47:01 +0100 Subject: [PATCH 195/373] deployment: Upgrade golang version to 1.16.1 Signed-off-by: Ruben Jenster --- deployment/utils.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/utils.sh b/deployment/utils.sh index 3bcd62a4..6971dff9 100755 --- a/deployment/utils.sh +++ b/deployment/utils.sh @@ -13,8 +13,8 @@ apt_clean() { rm -rf /var/lib/apt/lists/* } -GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.linux-amd64.tar.gz}" -GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-013a489ebb3e24ef3d915abe5b94c3286c070dfe0818d5bca8108f1d6e8440d2}" +GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.1.linux-amd64.tar.gz}" +GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-3edc22f8332231c3ba8be246f184b736b8d28f06ce24f08168d8ecf052549769}" install_golang() { local archive="$(basename $GOLANG_SRC)" From fcf88f9d9242d6e67ca3420a4c6c30dcfaf2b305 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 16 Mar 2021 16:59:24 +0100 Subject: [PATCH 196/373] Export namespace definitions. Signed-off-by: Ruben Jenster --- lxcontainer/namespaces.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index 7d96e4f6..5e6a5c2d 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -11,20 +11,30 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -type namespace struct { +type Namespace struct { Name string CloneFlag int } +var CgroupNamespace = Namespace{"cgroup", unix.CLONE_NEWCGROUP} +var IPCNamespace = Namespace{"ipc", unix.CLONE_NEWIPC} +var MountNamespace = Namespace{"mnt", unix.CLONE_NEWNS} +var NetworkNamespace = Namespace{"net", unix.CLONE_NEWNET} +var PIDNamespace = Namespace{"pid", unix.CLONE_NEWPID} +var TimeNamespace = Namespace{"time", unix.CLONE_NEWTIME} +var UserNamespace = Namespace{"user", unix.CLONE_NEWUSER} +var UTSNamespace = Namespace{"uts", unix.CLONE_NEWUTS} + // maps from CRIO namespace names to LXC names and clone flags -var namespaceMap = map[specs.LinuxNamespaceType]namespace{ - specs.CgroupNamespace: namespace{"cgroup", unix.CLONE_NEWCGROUP}, - specs.IPCNamespace: namespace{"ipc", unix.CLONE_NEWIPC}, - specs.MountNamespace: namespace{"mnt", unix.CLONE_NEWNS}, - specs.NetworkNamespace: namespace{"net", unix.CLONE_NEWNET}, - specs.PIDNamespace: namespace{"pid", unix.CLONE_NEWPID}, - specs.UserNamespace: namespace{"user", unix.CLONE_NEWUSER}, - specs.UTSNamespace: namespace{"uts", unix.CLONE_NEWUTS}, +var namespaceMap = map[specs.LinuxNamespaceType]Namespace{ + specs.CgroupNamespace: CgroupNamespace, + specs.IPCNamespace: IPCNamespace, + specs.MountNamespace: MountNamespace, + specs.NetworkNamespace: NetworkNamespace, + specs.PIDNamespace: PIDNamespace, + // specs.TimeNamespace: TimeNamespace, + specs.UserNamespace: UserNamespace, + specs.UTSNamespace: UTSNamespace, } func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { From 641d65cacb27c5dade11110501c2b5f56c38cb16 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 16 Mar 2021 17:12:24 +0100 Subject: [PATCH 197/373] Use lxc.namespaces.clone instead of lxc.namespaces.keep. Signed-off-by: Ruben Jenster --- lxcontainer/namespaces.go | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index 5e6a5c2d..dad6326c 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -51,37 +51,31 @@ func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { func configureNamespaces(clxc *Runtime, namespaces []specs.LinuxNamespace) error { seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} + cloneNamespaces := make([]string, 0, len(namespaces)) + for _, ns := range namespaces { - if _, ok := seenNamespaceTypes[ns.Type]; ok { - return fmt.Errorf("duplicate namespace type %s", ns.Type) + if _, seen := seenNamespaceTypes[ns.Type]; seen { + return fmt.Errorf("duplicate namespace %s", ns.Type) } seenNamespaceTypes[ns.Type] = true - if ns.Path == "" { - continue - } n, supported := namespaceMap[ns.Type] if !supported { return fmt.Errorf("unsupported namespace %s", ns.Type) } + + if ns.Path == "" { + cloneNamespaces = append(cloneNamespaces, n.Name) + continue + } + configKey := fmt.Sprintf("lxc.namespace.share.%s", n.Name) if err := clxc.setConfigItem(configKey, ns.Path); err != nil { return err } } - // from `man lxc.container.conf` - user and network namespace must be inherited together - if !seenNamespaceTypes[specs.NetworkNamespace] && seenNamespaceTypes[specs.UserNamespace] { - return fmt.Errorf("to inherit the network namespace the user namespace must be inherited as well") - } - - nsToKeep := make([]string, 0, len(namespaceMap)) - for key, n := range namespaceMap { - if !seenNamespaceTypes[key] { - nsToKeep = append(nsToKeep, n.Name) - } - } - return clxc.setConfigItem("lxc.namespace.keep", strings.Join(nsToKeep, " ")) + return clxc.setConfigItem("lxc.namespace.clone", strings.Join(cloneNamespaces, " ")) } func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool { From 9a86ac1857b658ce84ca4df04772b9d202c3dafa Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 22 Mar 2021 09:50:10 +0100 Subject: [PATCH 198/373] lxcontainer: Fix serialization of Runtime. Signed-off-by: Ruben Jenster --- lxcontainer/runtime.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 420fcbbd..d8b95bfc 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -21,11 +21,11 @@ var ErrNotExist = fmt.Errorf("container does not exist") var ErrExist = fmt.Errorf("container already exists") type Runtime struct { - Container *lxc.Container + Container *lxc.Container `json:"-"` ContainerInfo // [ global settings ] - LogFile *os.File + LogFile *os.File `json:"-"` LogFilePath string LogLevel string LogTimestamp string @@ -37,13 +37,13 @@ type Runtime struct { InitCommand string ContainerHook string - Log zerolog.Logger + Log zerolog.Logger `json:"-"` // runtime hooks (not OCI runtime hooks) // AfterCreateContainer is called right after creating the container runtime directory and descriptor, // and before creating the lxc 'config' file for the container. - AfterCreateContainer func(c *Runtime) error + AfterCreateContainer func(c *Runtime) error `json:"-"` } // createContainer creates a new container. From ca8454521b4f7b3030590a7181ef288d4ca8f0fa Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 22 Mar 2021 09:55:59 +0100 Subject: [PATCH 199/373] lxcontainer: Check if spec capabilities are empty. Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index de2c5d93..1b0c20a7 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -187,8 +187,7 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { } if c.Seccomp { - if spec.Linux.Seccomp == nil || len(spec.Linux.Seccomp.Syscalls) == 0 { - } else { + if spec.Linux.Seccomp != nil && len(spec.Linux.Seccomp.Syscalls) > 0 { profilePath := c.RuntimePath("seccomp.conf") if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { return err @@ -323,7 +322,9 @@ func configureCapabilities(c *Runtime, spec *specs.Spec) error { lcCapName := strings.TrimPrefix(strings.ToLower(c), "cap_") caps = append(caps, lcCapName) } - keepCaps = strings.Join(caps, " ") + if len(caps) > 0 { + keepCaps = strings.Join(caps, " ") + } } return c.setConfigItem("lxc.cap.keep", keepCaps) From a1c160c3989456df31edd31cdd21ff3f7263e853 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 22 Mar 2021 10:15:09 +0100 Subject: [PATCH 200/373] Move API command timeouts to runtime. Signed-off-by: Ruben Jenster --- cmd/cli.go | 22 ++++------------------ lxcontainer/create.go | 3 +++ lxcontainer/runtime.go | 19 ++++++++++++++++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 0ea50154..5d86c27a 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -26,11 +26,6 @@ var clxc struct { Command string CreateHook string CreateHookTimeout time.Duration - - CreateTimeout time.Duration - StartTimeout time.Duration - KillTimeout time.Duration - DeleteTimeout time.Duration } var version string @@ -287,15 +282,12 @@ func doCreate(unused *cli.Context) error { } func doCreateInternal(unused *cli.Context) error { - ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateTimeout) - defer cancel() - specPath := filepath.Join(clxc.BundlePath, "config.json") spec, err := readSpec(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } - return clxc.Create(ctx, spec) + return clxc.Create(context.Background(), spec) } func runCreateHook(err error) { @@ -342,9 +334,7 @@ starts } func doStart(unused *cli.Context) error { - ctx, cancel := context.WithTimeout(context.Background(), clxc.StartTimeout) - defer cancel() - return clxc.Start(ctx) + return clxc.Start(context.Background()) } var stateCmd = cli.Command{ @@ -398,9 +388,7 @@ func doKill(ctx *cli.Context) error { if signum == 0 { return fmt.Errorf("invalid signal param %q", sig) } - c, cancel := context.WithTimeout(context.Background(), clxc.KillTimeout) - defer cancel() - return clxc.Kill(c, signum) + return clxc.Kill(context.Background(), signum) } var deleteCmd = cli.Command{ @@ -427,9 +415,7 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { - c, cancel := context.WithTimeout(context.Background(), clxc.DeleteTimeout) - defer cancel() - err := clxc.Delete(c, ctx.Bool("force")) + err := clxc.Delete(context.Background(), ctx.Bool("force")) if errors.Is(err, lxcontainer.ErrNotExist) { clxc.Log.Warn().Msg("container does not exist") return nil diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 1b0c20a7..0d143afd 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -17,6 +17,9 @@ import ( ) func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { + ctx, cancel := context.WithTimeout(ctx, c.CreateTimeout) + defer cancel() + if c.runtimePathExists() { return ErrExist } diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index d8b95bfc..aa854f49 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -22,10 +22,11 @@ var ErrExist = fmt.Errorf("container already exists") type Runtime struct { Container *lxc.Container `json:"-"` + Log zerolog.Logger `json:"-"` + LogFile *os.File `json:"-"` + ContainerInfo - // [ global settings ] - LogFile *os.File `json:"-"` LogFilePath string LogLevel string LogTimestamp string @@ -37,7 +38,10 @@ type Runtime struct { InitCommand string ContainerHook string - Log zerolog.Logger `json:"-"` + CreateTimeout time.Duration + StartTimeout time.Duration + KillTimeout time.Duration + DeleteTimeout time.Duration // runtime hooks (not OCI runtime hooks) @@ -462,6 +466,9 @@ func (c *Runtime) saveConfig() error { } func (c *Runtime) Start(ctx context.Context) error { + ctx, cancel := context.WithTimeout(ctx, c.StartTimeout) + defer cancel() + c.Log.Info().Msg("notify init to start container process") err := c.loadContainer() @@ -520,6 +527,9 @@ func (c *Runtime) readFifo() error { } func (c *Runtime) Delete(ctx context.Context, force bool) error { + ctx, cancel := context.WithTimeout(ctx, c.DeleteTimeout) + defer cancel() + err := c.loadContainer() if err == ErrNotExist { c.Log.Info().Msg("container does not exist") @@ -569,6 +579,9 @@ func (c *Runtime) State() (*specs.State, error) { } func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { + ctx, cancel := context.WithTimeout(ctx, c.KillTimeout) + defer cancel() + err := c.loadContainer() if err != nil { return errorf("failed to load container: %w", err) From 1f00c0453b45010e5e7c10b8c36bbcb8cd3ef4db Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 22 Mar 2021 10:45:36 +0100 Subject: [PATCH 201/373] Move container features from ContainerInfo to Runtime Signed-off-by: Ruben Jenster --- cmd/cli.go | 8 ++++---- lxcontainer/cgroup.go | 4 ++-- lxcontainer/container.go | 6 ------ lxcontainer/create.go | 12 ++++++------ lxcontainer/runtime.go | 15 ++++++++++++--- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 5d86c27a..9a1ca530 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -123,28 +123,28 @@ func main() { &cli.BoolFlag{ Name: "apparmor", Usage: "set apparmor profile defined in container spec", - Destination: &clxc.Apparmor, + Destination: &clxc.Features.Apparmor, EnvVars: []string{"CRIO_LXC_APPARMOR"}, Value: true, }, &cli.BoolFlag{ Name: "capabilities", Usage: "keep capabilities defined in container spec", - Destination: &clxc.Capabilities, + Destination: &clxc.Features.Capabilities, EnvVars: []string{"CRIO_LXC_CAPABILITIES"}, Value: true, }, &cli.BoolFlag{ Name: "cgroup-devices", Usage: "allow only devices permitted by container spec", - Destination: &clxc.CgroupDevices, + Destination: &clxc.Features.CgroupDevices, EnvVars: []string{"CRIO_LXC_CGROUP_DEVICES"}, Value: true, }, &cli.BoolFlag{ Name: "seccomp", Usage: "Generate and apply seccomp profile for lxc from container spec", - Destination: &clxc.Seccomp, + Destination: &clxc.Features.Seccomp, EnvVars: []string{"CRIO_LXC_SECCOMP"}, Value: true, }, diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 315c1ffe..3b04182b 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -64,8 +64,8 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { devicesAllow := "lxc.cgroup2.devices.allow" devicesDeny := "lxc.cgroup2.devices.deny" - if !clxc.CgroupDevices { - clxc.Log.Warn().Msg("cgroup device controller is disabled (access to all devices is granted)") + if !clxc.Features.CgroupDevices { + clxc.Log.Warn().Msg("cgroup device controller feature is disabled - access to all devices is granted") return nil } diff --git a/lxcontainer/container.go b/lxcontainer/container.go index de819d04..148c02a6 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -28,12 +28,6 @@ type ContainerInfo struct { // values derived from spec CgroupDir string - // feature gates - Seccomp bool - Capabilities bool - Apparmor bool - CgroupDevices bool - // values duplicated from bundle.json // annotations are required for 'state' Annotations map[string]string `json:",omitempty"` diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 0d143afd..7e3e64fb 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -181,15 +181,15 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { } } - if c.Apparmor { + if c.Features.Apparmor { if err := configureApparmor(c, spec); err != nil { return fmt.Errorf("failed to configure apparmor: %w", err) } } else { - c.Log.Warn().Msg("apparmor is disabled (unconfined)") + c.Log.Warn().Msg("apparmor feature is disabled - profile is set to unconfined") } - if c.Seccomp { + if c.Features.Seccomp { if spec.Linux.Seccomp != nil && len(spec.Linux.Seccomp.Syscalls) > 0 { profilePath := c.RuntimePath("seccomp.conf") if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { @@ -200,15 +200,15 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { } } } else { - c.Log.Warn().Msg("seccomp is disabled") + c.Log.Warn().Msg("seccomp feature is disabled - all system calls are allowed") } - if c.Capabilities { + if c.Features.Capabilities { if err := configureCapabilities(c, spec); err != nil { return fmt.Errorf("failed to configure capabilities: %w", err) } } else { - c.Log.Warn().Msg("capabilities are disabled") + c.Log.Warn().Msg("capabilities feature is disabled - running with full privileges") } if err := ensureDefaultDevices(c, spec); err != nil { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index aa854f49..5866816c 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -25,14 +25,15 @@ type Runtime struct { Log zerolog.Logger `json:"-"` LogFile *os.File `json:"-"` - ContainerInfo + ContainerInfo `json:"-"` LogFilePath string LogLevel string LogTimestamp string ContainerLogLevel string - SystemdCgroup bool - MonitorCgroup string + + SystemdCgroup bool + MonitorCgroup string StartCommand string InitCommand string @@ -43,6 +44,14 @@ type Runtime struct { KillTimeout time.Duration DeleteTimeout time.Duration + // feature gates + Features struct { + Seccomp bool + Capabilities bool + Apparmor bool + CgroupDevices bool + } + // runtime hooks (not OCI runtime hooks) // AfterCreateContainer is called right after creating the container runtime directory and descriptor, From 8e1433efbae5d811d469196bd083be72b3974b24 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 22 Mar 2021 13:35:36 +0100 Subject: [PATCH 202/373] lxcontainer: Group timeouts and executables in nested struct Signed-off-by: Ruben Jenster --- lxcontainer/create.go | 8 ++++---- lxcontainer/init.go | 2 +- lxcontainer/runtime.go | 28 ++++++++++++++++++---------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 7e3e64fb..8417cb6c 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -17,14 +17,14 @@ import ( ) func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { - ctx, cancel := context.WithTimeout(ctx, c.CreateTimeout) + ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Create) defer cancel() if c.runtimePathExists() { return ErrExist } - err := canExecute(c.StartCommand, c.ContainerHook, c.InitCommand) + err := canExecute(c.Executables.Start, c.Executables.Hook, c.Executables.Init) if err != nil { return errorf("access check failed: %w", err) } @@ -82,7 +82,7 @@ func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { func (c *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { // #nosec - cmd := exec.Command(c.StartCommand, c.Container.Name(), c.RuntimeRoot, c.ConfigFilePath()) + cmd := exec.Command(c.Executables.Start, c.Container.Name(), c.RuntimeRoot, c.ConfigFilePath()) cmd.Env = []string{} cmd.Dir = c.RuntimePath() @@ -227,7 +227,7 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { if err := c.setConfigItem("lxc.hook.version", "1"); err != nil { return err } - if err := c.setConfigItem("lxc.hook.mount", c.ContainerHook); err != nil { + if err := c.setConfigItem("lxc.hook.mount", c.Executables.Hook); err != nil { return err } diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 7860821f..0dc0aff2 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -88,7 +88,7 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { } initCmd := filepath.Join(initDir, "init") spec.Mounts = append(spec.Mounts, specs.Mount{ - Source: clxc.InitCommand, + Source: clxc.Executables.Init, Destination: strings.TrimLeft(initCmd, "/"), Type: "bind", Options: []string{"bind", "ro", "nosuid"}, diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 5866816c..8a8425dc 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -35,14 +35,22 @@ type Runtime struct { SystemdCgroup bool MonitorCgroup string - StartCommand string - InitCommand string - ContainerHook string + // Executables contains names for all (external) executed commands. + // The excutable name is used as path if it contains a slash, otherwise + // the PATH environment variable is consulted to resolve the executable path. + Executables struct { + Start string + Init string + Hook string + } - CreateTimeout time.Duration - StartTimeout time.Duration - KillTimeout time.Duration - DeleteTimeout time.Duration + // Timeouts for API commands + Timeouts struct { + Create time.Duration + Start time.Duration + Kill time.Duration + Delete time.Duration + } // feature gates Features struct { @@ -475,7 +483,7 @@ func (c *Runtime) saveConfig() error { } func (c *Runtime) Start(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, c.StartTimeout) + ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Start) defer cancel() c.Log.Info().Msg("notify init to start container process") @@ -536,7 +544,7 @@ func (c *Runtime) readFifo() error { } func (c *Runtime) Delete(ctx context.Context, force bool) error { - ctx, cancel := context.WithTimeout(ctx, c.DeleteTimeout) + ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Delete) defer cancel() err := c.loadContainer() @@ -588,7 +596,7 @@ func (c *Runtime) State() (*specs.State, error) { } func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { - ctx, cancel := context.WithTimeout(ctx, c.KillTimeout) + ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Kill) defer cancel() err := c.loadContainer() From 0bd755e8c78f66eea8ed7dbf850b25f611874470 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 14:23:59 +0100 Subject: [PATCH 203/373] refactor: Decouple Container from Runtime. Signed-off-by: Ruben Jenster --- lxcontainer/cgroup.go | 125 +++++-- lxcontainer/container.go | 500 +++++++++++++++++++++++++-- lxcontainer/create.go | 354 ++++++------------- lxcontainer/devices.go | 102 ++++++ lxcontainer/init.go | 54 +-- lxcontainer/log.go | 78 +++++ lxcontainer/mount.go | 36 +- lxcontainer/mount_test.go | 7 +- lxcontainer/namespaces.go | 10 +- lxcontainer/runtime.go | 698 +++++--------------------------------- lxcontainer/utils.go | 15 +- 11 files changed, 998 insertions(+), 981 deletions(-) create mode 100644 lxcontainer/devices.go create mode 100644 lxcontainer/log.go diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 3b04182b..9a619382 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -24,51 +24,112 @@ const ( // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md // TODO New spec will contain a property Unified for cgroupv2 properties // https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#unified -func configureCgroup(clxc *Runtime, spec *specs.Spec) error { - if devices := spec.Linux.Resources.Devices; devices != nil { - if err := configureDeviceController(clxc, spec); err != nil { - return err +func configureCgroup(rt *Runtime, c *Container) error { + if err := configureCgroupPath(rt, c); err != nil { + return err + } + + if devices := c.Linux.Resources.Devices; devices != nil { + if rt.Features.CgroupDevices { + if err := configureDeviceController(c); err != nil { + return err + } + } else { + c.Log.Warn().Msg("cgroup device controller feature is disabled - access to all devices is granted") } + } - if mem := spec.Linux.Resources.Memory; mem != nil { - clxc.Log.Debug().Msg("TODO cgroup memory controller not implemented") + if mem := c.Linux.Resources.Memory; mem != nil { + rt.Log.Debug().Msg("TODO cgroup memory controller not implemented") } - if cpu := spec.Linux.Resources.CPU; cpu != nil { - if err := configureCPUController(clxc, cpu); err != nil { + if cpu := c.Linux.Resources.CPU; cpu != nil { + if err := configureCPUController(rt, cpu); err != nil { return err } } - if pids := spec.Linux.Resources.Pids; pids != nil { - if err := clxc.setConfigItem("lxc.cgroup2.pids.max", fmt.Sprintf("%d", pids.Limit)); err != nil { + if pids := c.Linux.Resources.Pids; pids != nil { + if err := c.SetConfigItem("lxc.cgroup2.pids.max", fmt.Sprintf("%d", pids.Limit)); err != nil { return err } } - if blockio := spec.Linux.Resources.BlockIO; blockio != nil { - clxc.Log.Debug().Msg("TODO cgroup blockio controller not implemented") + if blockio := c.Linux.Resources.BlockIO; blockio != nil { + rt.Log.Debug().Msg("TODO cgroup blockio controller not implemented") } - if hugetlb := spec.Linux.Resources.HugepageLimits; hugetlb != nil { + if hugetlb := c.Linux.Resources.HugepageLimits; hugetlb != nil { // set Hugetlb limit (in bytes) - clxc.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") + rt.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") } - if net := spec.Linux.Resources.Network; net != nil { - clxc.Log.Debug().Msg("TODO cgroup network controller not implemented") + if net := c.Linux.Resources.Network; net != nil { + rt.Log.Debug().Msg("TODO cgroup network controller not implemented") } return nil } -func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { - devicesAllow := "lxc.cgroup2.devices.allow" - devicesDeny := "lxc.cgroup2.devices.deny" +func configureCgroupPath(rt *Runtime, c *Container) error { + if c.Linux.CgroupsPath == "" { + //return fmt.Errorf("empty cgroups path in spec") + c.Linux.CgroupsPath = "foo.slice" + } + if rt.SystemdCgroup { + c.CgroupDir = parseSystemdCgroupPath(c.Linux.CgroupsPath) + } else { + c.CgroupDir = c.Linux.CgroupsPath + } - if !clxc.Features.CgroupDevices { - clxc.Log.Warn().Msg("cgroup device controller feature is disabled - access to all devices is granted") - return nil + c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") + + if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { + return err + } + + if err := c.SetConfigItem("lxc.cgroup.relative", "0"); err != nil { + return err } + if err := c.SetConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { + return err + } + + /* + if c.supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { + return err + } + } + */ + + /* + // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb + // checking for on of the config items shuld be enough, because they were introduced together ... + if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { + if err := c.SetConfigItem("lxc.cgroup.dir.container", c.CgroupDir); err != nil { + return err + } + if err := c.SetConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroupDir); err != nil { + return err + } + } else { + if err := c.SetConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { + return err + } + } + if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { + return err + } + } + */ + return nil +} + +func configureDeviceController(c *Container) error { + devicesAllow := "lxc.cgroup2.devices.allow" + devicesDeny := "lxc.cgroup2.devices.deny" + // Set cgroup device permissions from spec. // Device rule parsing in LXC is not well documented in lxc.container.conf // see https://github.com/lxc/lxc/blob/79c66a2af36ee8e967c5260428f8cdb5c82efa94/src/lxc/cgroups/cgfsng.c#L2545 @@ -79,7 +140,7 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { blockDevice := "b" charDevice := "c" - for _, dev := range spec.Linux.Resources.Devices { + for _, dev := range c.Linux.Resources.Devices { key := devicesDeny if dev.Allow { key = devicesAllow @@ -103,16 +164,16 @@ func configureDeviceController(clxc *Runtime, spec *specs.Spec) error { } // decompose val := fmt.Sprintf("%s %s:%s %s", blockDevice, maj, min, dev.Access) - if err := clxc.setConfigItem(key, val); err != nil { + if err := c.SetConfigItem(key, val); err != nil { return err } val = fmt.Sprintf("%s %s:%s %s", charDevice, maj, min, dev.Access) - if err := clxc.setConfigItem(key, val); err != nil { + if err := c.SetConfigItem(key, val); err != nil { return err } case blockDevice, charDevice: val := fmt.Sprintf("%s %s:%s %s", dev.Type, maj, min, dev.Access) - if err := clxc.setConfigItem(key, val); err != nil { + if err := c.SetConfigItem(key, val); err != nil { return err } default: @@ -128,32 +189,32 @@ func configureCPUController(clxc *Runtime, slinux *specs.LinuxCPU) error { clxc.Log.Debug().Msg("TODO configure cgroup cpu controller") /* if cpu.Shares != nil && *cpu.Shares > 0 { - if err := clxc.setConfigItem("lxc.cgroup2.cpu.shares", fmt.Sprintf("%d", *cpu.Shares)); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpu.shares", fmt.Sprintf("%d", *cpu.Shares)); err != nil { return err } } if cpu.Quota != nil && *cpu.Quota > 0 { - if err := clxc.setConfigItem("lxc.cgroup2.cpu.cfs_quota_us", fmt.Sprintf("%d", *cpu.Quota)); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpu.cfs_quota_us", fmt.Sprintf("%d", *cpu.Quota)); err != nil { return err } } if cpu.Period != nil && *cpu.Period != 0 { - if err := clxc.setConfigItem("lxc.cgroup2.cpu.cfs_period_us", fmt.Sprintf("%d", *cpu.Period)); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpu.cfs_period_us", fmt.Sprintf("%d", *cpu.Period)); err != nil { return err } } if cpu.Cpus != "" { - if err := clxc.setConfigItem("lxc.cgroup2.cpuset.cpus", cpu.Cpus); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpuset.cpus", cpu.Cpus); err != nil { return err } } if cpu.RealtimePeriod != nil && *cpu.RealtimePeriod > 0 { - if err := clxc.setConfigItem("lxc.cgroup2.cpu.rt_period_us", fmt.Sprintf("%d", *cpu.RealtimePeriod)); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpu.rt_period_us", fmt.Sprintf("%d", *cpu.RealtimePeriod)); err != nil { return err } } if cpu.RealtimeRuntime != nil && *cpu.RealtimeRuntime > 0 { - if err := clxc.setConfigItem("lxc.cgroup2.cpu.rt_runtime_us", fmt.Sprintf("%d", *cpu.RealtimeRuntime)); err != nil { + if err := clxc.SetConfigItem("lxc.cgroup2.cpu.rt_runtime_us", fmt.Sprintf("%d", *cpu.RealtimeRuntime)); err != nil { return err } } diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 148c02a6..7ddc041d 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -1,6 +1,8 @@ package lxcontainer import ( + "context" + "fmt" "io/ioutil" "os" "path/filepath" @@ -9,15 +11,19 @@ import ( "time" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/rs/zerolog" + "golang.org/x/sys/unix" + "gopkg.in/lxc/go-lxc.v2" ) -// ContainerInfo holds the information about a single container. -// It is created at 'create' within the container runtime dir and not changed afterwards. -// It is removed when the container is deleted. -type ContainerInfo struct { +type ContainerConfig struct { + *specs.Spec + SpecPath string + + RuntimeDir string + ContainerID string CreatedAt time.Time - RuntimeRoot string BundlePath string ConsoleSocket string `json:",omitempty"` @@ -25,35 +31,32 @@ type ContainerInfo struct { PidFile string MonitorCgroupDir string - // values derived from spec CgroupDir string +} + +func (cfg ContainerConfig) ConfigFilePath() string { + return cfg.RuntimePath("config") +} - // values duplicated from bundle.json - // annotations are required for 'state' - Annotations map[string]string `json:",omitempty"` - // namespaces are required for 'exec' - Namespaces []specs.LinuxNamespace `json:",omitempty"` +func (cfg ContainerConfig) syncFifoPath() string { + return cfg.RuntimePath(initDir, "syncfifo") } // RuntimePath returns the absolute path witin the container root -func (c ContainerInfo) RuntimePath(subPath ...string) string { - return filepath.Join(c.RuntimeRoot, c.ContainerID, filepath.Join(subPath...)) +func (cfg ContainerConfig) RuntimePath(subPath ...string) string { + return filepath.Join(cfg.RuntimeDir, filepath.Join(subPath...)) } -func (c ContainerInfo) runtimePathExists() bool { - if _, err := os.Stat(c.RuntimePath()); err == nil { +func (cfg ContainerConfig) runtimeDirExists() bool { + if _, err := os.Stat(cfg.RuntimeDir); err == nil { return true } return false } -func (c ContainerInfo) ConfigFilePath() string { - return c.RuntimePath("config") -} - -func (c ContainerInfo) Pid() (int, error) { +func (cfg ContainerConfig) Pid() (int, error) { // #nosec - data, err := ioutil.ReadFile(c.PidFile) + data, err := ioutil.ReadFile(cfg.PidFile) if err != nil { return 0, err } @@ -61,17 +64,460 @@ func (c ContainerInfo) Pid() (int, error) { return strconv.Atoi(s) } -func (c ContainerInfo) CreatePidFile(pid int) error { - return CreatePidFile(c.PidFile, pid) +func (c *ContainerConfig) LoadSpecJson(p string) error { + c.SpecPath = p + return decodeFileJSON(c.Spec, p) +} + +// ContainerInfo holds the information about a single container. +// It is created at 'create' within the container runtime dir and not changed afterwards. +// It is removed when the container is deleted. +type Container struct { + linuxcontainer *lxc.Container `json:"-"` + *ContainerConfig + Log zerolog.Logger `json:"-"` +} + +func NewContainer(config *ContainerConfig) (*Container, error) { + c := &Container{ContainerConfig: config} + + if c.runtimeDirExists() { + return nil, ErrExist + } + + if err := os.MkdirAll(c.RuntimeDir, 0700); err != nil { + return nil, fmt.Errorf("failed to create container dir: %w", err) + } + + // An empty tmpfile is created to ensure that createContainer can only succeed once. + // The config file is atomically activated in SaveConfig. + // #nosec + f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + if err != nil { + return nil, err + } + if err := f.Close(); err != nil { + return nil, fmt.Errorf("failed to close empty config tmpfile: %w", err) + } + + c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + if err != nil { + return nil, err + } + return c, nil +} + +func LoadContainer(cfg *ContainerConfig) (*Container, error) { + c := &Container{ContainerConfig: cfg} + + if !c.runtimeDirExists() { + return nil, ErrNotExist + } + + err := decodeFileJSON(&c.ContainerConfig, c.RuntimePath("container.json")) + if err != nil { + return nil, fmt.Errorf("failed to load container config: %w", err) + } + + _, err = os.Stat(c.ConfigFilePath()) + if err != nil { + return nil, fmt.Errorf("failed to load lxc config file: %w", err) + } + c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + if err != nil { + return nil, fmt.Errorf("failed to create lxc container: %w", err) + } + + err = c.linuxcontainer.LoadConfigFile(c.ConfigFilePath()) + if err != nil { + return nil, fmt.Errorf("failed to load config file: %w", err) + } + return c, nil +} + +func (c *Container) SetLog(logFile string, level string) error { + // Never let lxc write to stdout, stdout belongs to the container init process. + // Explicitly disable it - allthough it is currently the default. + c.linuxcontainer.SetVerbosity(lxc.Quiet) + // The log level for a running container is set, and may change, per runtime call. + err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(level)) + if err != nil { + return fmt.Errorf("failed to set container loglevel: %w", err) + } + if err := c.linuxcontainer.SetLogFile(logFile); err != nil { + return fmt.Errorf("failed to set container log file: %w", err) + } + return nil +} + +func parseContainerLogLevel(level string) lxc.LogLevel { + switch strings.ToLower(level) { + case "trace": + return lxc.TRACE + case "debug": + return lxc.DEBUG + case "info": + return lxc.INFO + case "notice": + return lxc.NOTICE + case "warn": + return lxc.WARN + case "error": + return lxc.ERROR + case "crit": + return lxc.CRIT + case "alert": + return lxc.ALERT + case "fatal": + return lxc.FATAL + default: + return lxc.WARN + } } -// RuntimeRoot and ContainerID must be set -func (c *ContainerInfo) Load() error { - return DecodeFileJSON(c, c.RuntimePath("container.json")) +func (c *Container) waitCreated(ctx context.Context) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + state := c.linuxcontainer.State() + if !(state == lxc.RUNNING) { + c.Log.Debug().Stringer("state", state).Msg("wait for state lxc.RUNNING") + time.Sleep(time.Millisecond * 100) + continue + } + initState, err := c.getContainerInitState() + if err != nil { + return err + } + if initState == specs.StateCreated { + return nil + } + return fmt.Errorf("unexpected init state %q", initState) + } + } +} + +func (c *Container) waitNot(ctx context.Context, state specs.ContainerState) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + initState, _ := c.getContainerInitState() + if initState != state { + return nil + } + time.Sleep(time.Millisecond * 10) + } + } } -func (c *ContainerInfo) Create() error { +func (c *Container) wait(ctx context.Context, state lxc.State) bool { + for { + select { + case <-ctx.Done(): + return false + default: + if c.linuxcontainer.State() == state { + return true + } + time.Sleep(time.Millisecond * 100) + } + } +} + +func (c *Container) State() (*specs.State, error) { + pid, err := c.Pid() + if err != nil { + return nil, errorf("failed to load pidfile: %w", err) + } + + status, err := c.ContainerState() + if err != nil { + return nil, errorf("failed go get container status: %w", err) + } + + state := &specs.State{ + Version: specs.Version, + ID: c.ContainerID, + Bundle: c.BundlePath, + Pid: pid, + Annotations: c.Annotations, + Status: status, + } + return state, nil +} + +func (c *Container) ContainerState() (specs.ContainerState, error) { + state := c.linuxcontainer.State() + switch state { + case lxc.STOPPED: + return specs.StateStopped, nil + case lxc.STARTING: + return specs.StateCreating, nil + case lxc.RUNNING, lxc.STOPPING, lxc.ABORTING, lxc.FREEZING, lxc.FROZEN, lxc.THAWED: + return c.getContainerInitState() + default: + return specs.StateStopped, fmt.Errorf("unsupported lxc container state %q", state) + } +} + +// getContainerInitState returns the detailed state of the container init process. +// This should be called if the container is in state lxc.RUNNING. +// On error the caller should call getContainerState() again +func (c *Container) getContainerInitState() (specs.ContainerState, error) { + initPid := c.linuxcontainer.InitPid() + if initPid < 1 { + return specs.StateStopped, nil + } + cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) + cmdline, err := ioutil.ReadFile(cmdlinePath) + if os.IsNotExist(err) { + // init process died or returned + return specs.StateStopped, nil + } + if err != nil { + // it's a serious error if cmdlinePath exists but can't be read + return specs.StateStopped, err + } + + initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) + if string(cmdline) == initCmdline { + return specs.StateCreated, nil + } + return specs.StateRunning, nil +} + +func (c *Container) Kill(ctx context.Context, signum unix.Signal) error { + c.Log.Info().Int("signum", int(signum)).Msg("killing container process") + if signum == unix.SIGKILL || signum == unix.SIGTERM { + if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { + return err + } + if err := c.linuxcontainer.Stop(); err != nil { + return err + } + + if !c.wait(ctx, lxc.STOPPED) { + c.Log.Warn().Msg("failed to stop lxc container") + } + + // draining the cgroup is required to catch processes that escaped from + // 'kill' e.g a bash for loop that spawns a new child immediately. + start := time.Now() + err := drainCgroup(ctx, c.CgroupDir, signum) + if err != nil && !os.IsNotExist(err) { + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + } else { + c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") + } + return err + } + + // send non-terminating signals to monitor process + pid, err := c.Pid() + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to load pidfile: %w", err) + } + if pid > 1 { + c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") + if err := unix.Kill(pid, 0); err == nil { + err := unix.Kill(pid, signum) + if err != unix.ESRCH { + return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) + } + } + } + return nil +} + +// SaveConfig creates and atomically enables the lxc config file. +// It must be called after #createContainer and only once. +// Any config changes via clxc.setConfigItem must be done +// before calling SaveConfig. +// FIXME revise the config file mechanism +func (c *Container) SaveConfig() error { + // createContainer creates the tmpfile + tmpFile := c.RuntimePath(".config") + if _, err := os.Stat(tmpFile); err != nil { + return fmt.Errorf("failed to stat config tmpfile: %w", err) + } + // Don't overwrite an existing config. + cfgFile := c.ConfigFilePath() + if _, err := os.Stat(cfgFile); err == nil { + return fmt.Errorf("config file %s already exists", cfgFile) + } + err := c.linuxcontainer.SaveConfigFile(tmpFile) + if err != nil { + return fmt.Errorf("failed to save config file to %q: %w", tmpFile, err) + } + if err := os.Rename(tmpFile, cfgFile); err != nil { + return fmt.Errorf("failed to rename config file: %w", err) + } + p := c.RuntimePath("container.json") c.CreatedAt = time.Now() return encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) } + +func (c *Container) GetConfigItem(key string) string { + vals := c.linuxcontainer.ConfigItem(key) + if len(vals) > 0 { + first := vals[0] + // some lxc config values are set to '(null)' if unset + // eg. lxc.cgroup.dir + if first != "(null)" { + return first + } + } + return "" +} + +func (c *Container) SetConfigItem(key, value string) error { + err := c.linuxcontainer.SetConfigItem(key, value) + if err != nil { + return fmt.Errorf("failed to set config item '%s=%s': %w", key, value, err) + } + c.Log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") + return nil +} + +func (c *Container) SupportsConfigItem(keys ...string) bool { + canCheck := lxc.VersionAtLeast(4, 0, 6) + if !canCheck { + c.Log.Warn().Msg("lxc.IsSupportedConfigItem is broken in liblxc < 4.0.6") + } + for _, key := range keys { + if canCheck && lxc.IsSupportedConfigItem(key) { + continue + } + c.Log.Info().Str("lxc.config", key).Msg("unsupported config item") + return false + } + return true +} + +func (c *Container) Release() error { + return c.linuxcontainer.Release() +} + +// "Note that resources associated with the container, +// but not created by this container, MUST NOT be deleted." +// TODO - because we set rootfs.managed=0, Destroy() doesn't +// delete the /var/lib/lxc/$containerID/config file: +func (c *Container) Destroy() error { + if err := c.linuxcontainer.Destroy(); err != nil { + return fmt.Errorf("failed to destroy container: %w", err) + } + if c.CgroupDir != "" { + err := deleteCgroup(c.CgroupDir) + if err != nil && !os.IsNotExist(err) { + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + } + } + return os.RemoveAll(c.RuntimePath()) +} + +func (c *Container) Start(ctx context.Context) error { + done := make(chan error) + go func() { + // FIXME fifo must be unblocked otherwise + // this may be a goroutine leak + done <- c.readFifo() + }() + + select { + case <-ctx.Done(): + return errorf("syncfifo timeout: %w", ctx.Err()) + // TODO write to fifo here and fallthrough ? + case err := <-done: + if err != nil { + return errorf("failed to read from syncfifo: %w", err) + } + } + // wait for container state to change + return c.waitNot(ctx, specs.StateCreated) +} + +func (c *Container) readFifo() error { + // #nosec + f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) + if err != nil { + return err + } + // NOTE it's not possible to set an IO deadline on a fifo + // #nosec + defer f.Close() + + data := make([]byte, len(c.ContainerID)) + _, err = f.Read(data) + if err != nil { + return fmt.Errorf("problem reading from fifo: %w", err) + } + if c.ContainerID != string(data) { + return fmt.Errorf("bad fifo content: %s", string(data)) + } + return nil +} + +func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { + opts, err := attachOptions(proc, c.Linux.Namespaces) + if err != nil { + return 0, errorf("failed to create attach options: %w", err) + } + + c.Log.Info().Strs("args", args). + Int("uid", opts.UID).Int("gid", opts.GID). + Ints("groups", opts.Groups).Msg("execute cmd") + + pid, err = c.linuxcontainer.RunCommandNoWait(args, opts) + if err != nil { + return pid, errorf("failed to run exec cmd detached: %w", err) + } + return pid, nil +} + +func (c *Container) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { + opts, err := attachOptions(proc, c.Linux.Namespaces) + if err != nil { + return 0, errorf("failed to create attach options: %w", err) + } + exitStatus, err = c.linuxcontainer.RunCommandStatus(args, opts) + if err != nil { + return exitStatus, errorf("failed to run exec cmd: %w", err) + } + return exitStatus, nil +} + +func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.AttachOptions, error) { + opts := lxc.AttachOptions{ + StdinFd: 0, + StdoutFd: 1, + StderrFd: 2, + } + + clone, err := cloneFlags(ns) + if err != nil { + return opts, err + } + opts.Namespaces = clone + + if procSpec != nil { + opts.Cwd = procSpec.Cwd + // Use the environment defined by the process spec. + opts.ClearEnv = true + opts.Env = procSpec.Env + + opts.UID = int(procSpec.User.UID) + opts.GID = int(procSpec.User.GID) + if n := len(procSpec.User.AdditionalGids); n > 0 { + opts.Groups = make([]int, n) + for i, g := range procSpec.User.AdditionalGids { + opts.Groups[i] = int(g) + } + } + } + return opts, nil +} diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 8417cb6c..29856b18 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -16,186 +16,151 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -func (c *Runtime) Create(ctx context.Context, spec *specs.Spec) error { - ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Create) +func (rt *Runtime) Create(ctx context.Context, config *ContainerConfig) (*Container, error) { + ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Create) defer cancel() - if c.runtimePathExists() { - return ErrExist + if err := rt.checkSystem(); err != nil { + return nil, err } - err := canExecute(c.Executables.Start, c.Executables.Hook, c.Executables.Init) - if err != nil { - return errorf("access check failed: %w", err) + if err := rt.checkConfig(config); err != nil { + return nil, err } - if err := isFilesystem("/proc", "proc"); err != nil { - return errorf("procfs not mounted on /proc: %w", err) - } - if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { - return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) + config.RuntimeDir = filepath.Join(rt.Root, config.ContainerID) + c, err := NewContainer(config) + if err != nil { + return nil, errorf("failed to create container: %w", err) } - if !lxc.VersionAtLeast(3, 1, 0) { - return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) + if err := configureContainer(rt, c); err != nil { + return nil, errorf("failed to configure container: %w", err) } - if !lxc.VersionAtLeast(4, 0, 5) { - c.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) + if err := c.SaveConfig(); err != nil { + return nil, errorf("failed to save container descriptor: %w", err) } - if spec.Linux.Resources == nil { - spec.Linux.Resources = &specs.LinuxResources{} + if err := rt.runStartCmd(ctx, c); err != nil { + return nil, errorf("failed to run container process: %w", err) } - if spec.Linux.Devices == nil { - spec.Linux.Devices = make([]specs.LinuxDevice, 0, 20) + if rt.Hooks.AfterCreate != nil { + defer rt.Hooks.AfterCreate(ctx, c) } + return c, nil +} - if spec.Process == nil { - return fmt.Errorf("spec.Process is nil") +func (rt *Runtime) checkSystem() error { + err := canExecute(rt.Executables.Start, rt.Executables.Hook, rt.Executables.Init) + if err != nil { + return errorf("access check failed: %w", err) } - if len(spec.Process.Args) == 0 { - return fmt.Errorf("specs.Process.Args is empty") + if err := isFilesystem("/proc", "proc"); err != nil { + return errorf("procfs not mounted on /proc: %w", err) } - - if spec.Process.Cwd == "" { - c.Log.Info().Msg("specs.Process.Cwd is unset defaulting to '/'") - spec.Process.Cwd = "/" + if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { + return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) } - err = c.createContainer(spec) - if err != nil { - return errorf("failed to create container: %w", err) + if !lxc.VersionAtLeast(3, 1, 0) { + return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) } - if err := configureContainer(c, spec); err != nil { - return errorf("failed to configure container: %w", err) + if !lxc.VersionAtLeast(4, 0, 5) { + rt.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } - if err := c.runStartCmd(ctx, spec); err != nil { - return errorf("failed to run container process: %w", err) - } return nil } -func (c *Runtime) runStartCmd(ctx context.Context, spec *specs.Spec) (err error) { - // #nosec - cmd := exec.Command(c.Executables.Start, c.Container.Name(), c.RuntimeRoot, c.ConfigFilePath()) - cmd.Env = []string{} - cmd.Dir = c.RuntimePath() - - if c.ConsoleSocket == "" && !spec.Process.Terminal { - // Inherit stdio from calling process (conmon). - // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc - if err := c.setConfigItem("lxc.console.path", "none"); err != nil { - return err - } - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr +func (rt *Runtime) checkConfig(config *ContainerConfig) error { + if config.Linux.Resources == nil { + config.Linux.Resources = &specs.LinuxResources{} } - if err := c.saveConfig(); err != nil { - return err + if config.Linux.Devices == nil { + config.Linux.Devices = make([]specs.LinuxDevice, 0, 20) } - c.Log.Debug().Msg("starting lxc monitor process") - if c.ConsoleSocket != "" { - err = runStartCmdConsole(ctx, cmd, c.ConsoleSocket) - } else { - err = cmd.Start() + if config.Process == nil { + return fmt.Errorf("config.Process is nil") } - if err != nil { - return err + if len(config.Process.Args) == 0 { + return fmt.Errorf("configs.Process.Args is empty") } - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - go func() { - // NOTE this goroutine may leak until crio-lxc is terminated - ps, err := cmd.Process.Wait() - if err != nil { - c.Log.Error().Err(err).Msg("failed to wait for start process") - } else { - c.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") - } - cancel() - }() - - c.Log.Debug().Msg("waiting for init") - if err := c.waitCreated(ctx); err != nil { - return err + if config.Process.Cwd == "" { + rt.Log.Info().Msg("configs.Process.Cwd is unset defaulting to '/'") + config.Process.Cwd = "/" } - - c.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") - return CreatePidFile(c.PidFile, cmd.Process.Pid) + return nil } -func configureContainer(c *Runtime, spec *specs.Spec) error { - if spec.Hostname != "" { - if err := c.setConfigItem("lxc.uts.name", spec.Hostname); err != nil { +func configureContainer(rt *Runtime, c *Container) error { + if c.Hostname != "" { + if err := c.SetConfigItem("lxc.uts.name", c.Hostname); err != nil { return err } - uts := getNamespace(specs.UTSNamespace, spec.Linux.Namespaces) + uts := getNamespace(specs.UTSNamespace, c.Linux.Namespaces) if uts != nil && uts.Path != "" { - if err := setHostname(uts.Path, spec.Hostname); err != nil { + if err := setHostname(uts.Path, c.Hostname); err != nil { return fmt.Errorf("failed to set hostname: %w", err) } } } - if err := configureRootfs(c, spec); err != nil { + if err := configureRootfs(c); err != nil { return err } - if err := configureInit(c, spec); err != nil { + if err := configureInit(rt, c); err != nil { return err } - if err := configureMounts(c, spec); err != nil { + if err := configureMounts(c); err != nil { return err } - if err := configureReadonlyPaths(c, spec); err != nil { + if err := configureReadonlyPaths(c); err != nil { return err } - if err := configureNamespaces(c, spec.Linux.Namespaces); err != nil { + if err := configureNamespaces(c); err != nil { return fmt.Errorf("failed to configure namespaces: %w", err) } - if spec.Process.OOMScoreAdj != nil { - if err := c.setConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *spec.Process.OOMScoreAdj)); err != nil { + if c.Process.OOMScoreAdj != nil { + if err := c.SetConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *c.Process.OOMScoreAdj)); err != nil { return err } } - if spec.Process.NoNewPrivileges { - if err := c.setConfigItem("lxc.no_new_privs", "1"); err != nil { + if c.Process.NoNewPrivileges { + if err := c.SetConfigItem("lxc.no_new_privs", "1"); err != nil { return err } } - if c.Features.Apparmor { - if err := configureApparmor(c, spec); err != nil { + if rt.Features.Apparmor { + if err := configureApparmor(c); err != nil { return fmt.Errorf("failed to configure apparmor: %w", err) } } else { - c.Log.Warn().Msg("apparmor feature is disabled - profile is set to unconfined") + rt.Log.Warn().Msg("apparmor feature is disabled - profile is set to unconfined") } - if c.Features.Seccomp { - if spec.Linux.Seccomp != nil && len(spec.Linux.Seccomp.Syscalls) > 0 { + if rt.Features.Seccomp { + if c.Linux.Seccomp != nil && len(c.Linux.Seccomp.Syscalls) > 0 { profilePath := c.RuntimePath("seccomp.conf") - if err := writeSeccompProfile(profilePath, spec.Linux.Seccomp); err != nil { + if err := writeSeccompProfile(profilePath, c.Linux.Seccomp); err != nil { return err } - if err := c.setConfigItem("lxc.seccomp.profile", profilePath); err != nil { + if err := c.SetConfigItem("lxc.seccomp.profile", profilePath); err != nil { return err } } @@ -203,52 +168,52 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { c.Log.Warn().Msg("seccomp feature is disabled - all system calls are allowed") } - if c.Features.Capabilities { - if err := configureCapabilities(c, spec); err != nil { + if rt.Features.Capabilities { + if err := configureCapabilities(c); err != nil { return fmt.Errorf("failed to configure capabilities: %w", err) } } else { - c.Log.Warn().Msg("capabilities feature is disabled - running with full privileges") + rt.Log.Warn().Msg("capabilities feature is disabled - running with full privileges") } - if err := ensureDefaultDevices(c, spec); err != nil { + // make sure autodev is disabled + if err := c.SetConfigItem("lxc.autodev", "0"); err != nil { + return err + } + if err := ensureDefaultDevices(rt, c); err != nil { return fmt.Errorf("failed to add default devices: %w", err) } - if err := writeDevices(c.RuntimePath("devices.txt"), spec); err != nil { + if err := writeDevices(c.RuntimePath("devices.txt"), c); err != nil { return fmt.Errorf("failed to create devices.txt: %w", err) } - if err := writeMasked(c.RuntimePath("masked.txt"), spec); err != nil { + if err := writeMasked(c.RuntimePath("masked.txt"), c); err != nil { return fmt.Errorf("failed to create masked.txt: %w", err) } // pass context information as environment variables to hook scripts - if err := c.setConfigItem("lxc.hook.version", "1"); err != nil { + if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { return err } - if err := c.setConfigItem("lxc.hook.mount", c.Executables.Hook); err != nil { + if err := c.SetConfigItem("lxc.hook.mount", rt.Executables.Hook); err != nil { return err } - if err := c.configureCgroupPath(); err != nil { - return fmt.Errorf("failed to configure cgroups path: %w", err) - } - - if err := configureCgroup(c, spec); err != nil { + if err := configureCgroup(rt, c); err != nil { return fmt.Errorf("failed to configure cgroups: %w", err) } - for key, val := range spec.Linux.Sysctl { - if err := c.setConfigItem("lxc.sysctl."+key, val); err != nil { + for key, val := range c.Linux.Sysctl { + if err := c.SetConfigItem("lxc.sysctl."+key, val); err != nil { return err } } // `man lxc.container.conf`: "A resource with no explicitly configured limitation will be inherited // from the process starting up the container" - seenLimits := make([]string, 0, len(spec.Process.Rlimits)) - for _, limit := range spec.Process.Rlimits { + seenLimits := make([]string, 0, len(c.Process.Rlimits)) + for _, limit := range c.Process.Rlimits { name := strings.TrimPrefix(strings.ToLower(limit.Type), "rlimit_") for _, seen := range seenLimits { if seen == name { @@ -257,71 +222,71 @@ func configureContainer(c *Runtime, spec *specs.Spec) error { } seenLimits = append(seenLimits, name) val := fmt.Sprintf("%d:%d", limit.Soft, limit.Hard) - if err := c.setConfigItem("lxc.prlimit."+name, val); err != nil { + if err := c.SetConfigItem("lxc.prlimit."+name, val); err != nil { return err } } return nil } -func configureRootfs(c *Runtime, spec *specs.Spec) error { - if err := c.setConfigItem("lxc.rootfs.path", spec.Root.Path); err != nil { +func configureRootfs(c *Container) error { + if err := c.SetConfigItem("lxc.rootfs.path", c.Root.Path); err != nil { return err } - if err := c.setConfigItem("lxc.rootfs.managed", "0"); err != nil { + if err := c.SetConfigItem("lxc.rootfs.managed", "0"); err != nil { return err } // Resources not created by the container runtime MUST NOT be deleted by it. - if err := c.setConfigItem("lxc.ephemeral", "0"); err != nil { + if err := c.SetConfigItem("lxc.ephemeral", "0"); err != nil { return err } rootfsOptions := []string{} - if spec.Linux.RootfsPropagation != "" { - rootfsOptions = append(rootfsOptions, spec.Linux.RootfsPropagation) + if c.Linux.RootfsPropagation != "" { + rootfsOptions = append(rootfsOptions, c.Linux.RootfsPropagation) } - if spec.Root.Readonly { + if c.Root.Readonly { rootfsOptions = append(rootfsOptions, "ro") } - if err := c.setConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { + if err := c.SetConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { return err } return nil } -func configureReadonlyPaths(c *Runtime, spec *specs.Spec) error { - rootmnt := c.getConfigItem("lxc.rootfs.mount") +func configureReadonlyPaths(c *Container) error { + rootmnt := c.GetConfigItem("lxc.rootfs.mount") if rootmnt == "" { return fmt.Errorf("lxc.rootfs.mount unavailable") } - for _, p := range spec.Linux.ReadonlyPaths { + for _, p := range c.Linux.ReadonlyPaths { mnt := fmt.Sprintf("%s %s %s %s", filepath.Join(rootmnt, p), strings.TrimPrefix(p, "/"), "bind", "bind,ro,optional") - if err := c.setConfigItem("lxc.mount.entry", mnt); err != nil { + if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { return fmt.Errorf("failed to make path readonly: %w", err) } } return nil } -func configureApparmor(c *Runtime, spec *specs.Spec) error { +func configureApparmor(c *Container) error { // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. - aaprofile := spec.Process.ApparmorProfile + aaprofile := c.Process.ApparmorProfile if aaprofile == "" { aaprofile = "unconfined" } - return c.setConfigItem("lxc.apparmor.profile", aaprofile) + return c.SetConfigItem("lxc.apparmor.profile", aaprofile) } // configureCapabilities configures the linux capabilities / privileges granted to the container processes. // See `man lxc.container.conf` lxc.cap.drop and lxc.cap.keep for details. // https://blog.container-solutions.com/linux-capabilities-in-practice // https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work -func configureCapabilities(c *Runtime, spec *specs.Spec) error { +func configureCapabilities(c *Container) error { keepCaps := "none" - if spec.Process.Capabilities != nil { + if c.Process.Capabilities != nil { var caps []string - for _, c := range spec.Process.Capabilities.Permitted { + for _, c := range c.Process.Capabilities.Permitted { lcCapName := strings.TrimPrefix(strings.ToLower(c), "cap_") caps = append(caps, lcCapName) } @@ -330,121 +295,10 @@ func configureCapabilities(c *Runtime, spec *specs.Spec) error { } } - return c.setConfigItem("lxc.cap.keep", keepCaps) -} - -func isDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) bool { - for _, specDev := range spec.Linux.Devices { - if specDev.Path == dev.Path { - return true - } - } - return false -} - -func addDevice(spec *specs.Spec, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { - dev.FileMode = &mode - dev.UID = &uid - dev.GID = &gid - spec.Linux.Devices = append(spec.Linux.Devices, dev) - - addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) -} - -func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64, access string) { - devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} - spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) -} - -// ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) -// to the given container spec if required. -// crio can add devices to containers, but this does not work for privileged containers. -// See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 -// TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(c *Runtime, spec *specs.Spec) error { - // make sure autodev is disabled - if err := c.setConfigItem("lxc.autodev", "0"); err != nil { - return err - } - - mode := os.FileMode(0666) - var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID - - devices := []specs.LinuxDevice{ - specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, - specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, - specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, - specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, - specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, - specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, - // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? - // `man 2 mount` | devpts - // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. - // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` - } - - ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} - addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx - - pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} - addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] - - if spec.Linux.Resources == nil { - spec.Linux.Resources = &specs.LinuxResources{} - } - - // add missing default devices - for _, dev := range devices { - if !isDeviceEnabled(spec, dev) { - addDevice(spec, dev, mode, uid, gid, "rwm") - } - } - return nil -} - -func setenv(env []string, key, val string, overwrite bool) []string { - for i, kv := range env { - if strings.HasPrefix(kv, key+"=") { - if overwrite { - env[i] = key + "=" + val - } - return env - } - } - return append(env, key+"="+val) -} - -func writeDevices(dst string, spec *specs.Spec) error { - if spec.Linux.Devices == nil { - return nil - } - f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) - if err != nil { - return err - } - for _, d := range spec.Linux.Devices { - uid := spec.Process.User.UID - if d.UID != nil { - uid = *d.UID - } - gid := spec.Process.User.GID - if d.GID != nil { - gid = *d.GID - } - mode := os.FileMode(0600) - if d.FileMode != nil { - mode = *d.FileMode - } - _, err = fmt.Fprintf(f, "%s %s %d %d %o %d:%d\n", d.Path, d.Type, d.Major, d.Minor, mode, uid, gid) - if err != nil { - f.Close() - return err - } - } - return f.Close() + return c.SetConfigItem("lxc.cap.keep", keepCaps) } -func writeMasked(dst string, spec *specs.Spec) error { +func writeMasked(dst string, spec *Container) error { // #nosec if spec.Linux.MaskedPaths == nil { return nil diff --git a/lxcontainer/devices.go b/lxcontainer/devices.go new file mode 100644 index 00000000..6a5d009d --- /dev/null +++ b/lxcontainer/devices.go @@ -0,0 +1,102 @@ +package lxcontainer + +import ( + "fmt" + "os" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +func isDeviceEnabled(spec *Container, dev specs.LinuxDevice) bool { + for _, specDev := range spec.Linux.Devices { + if specDev.Path == dev.Path { + return true + } + } + return false +} + +func addDevice(spec *Container, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { + dev.FileMode = &mode + dev.UID = &uid + dev.GID = &gid + spec.Linux.Devices = append(spec.Linux.Devices, dev) + + addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) +} + +func addDevicePerms(spec *Container, devType string, major *int64, minor *int64, access string) { + devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) +} + +// ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) +// to the given container spec if required. +// crio can add devices to containers, but this does not work for privileged containers. +// See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 +// TODO file an issue on cri-o (at least for support) +func ensureDefaultDevices(c *Runtime, spec *Container) error { + mode := os.FileMode(0666) + var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID + + devices := []specs.LinuxDevice{ + specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, + specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, + specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, + specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, + specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, + specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, + // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? + // `man 2 mount` | devpts + // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. + // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` + } + + ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} + addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx + + pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} + addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] + + if spec.Linux.Resources == nil { + spec.Linux.Resources = &specs.LinuxResources{} + } + + // add missing default devices + for _, dev := range devices { + if !isDeviceEnabled(spec, dev) { + addDevice(spec, dev, mode, uid, gid, "rwm") + } + } + return nil +} + +func writeDevices(dst string, spec *Container) error { + if spec.Linux.Devices == nil { + return nil + } + f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) + if err != nil { + return err + } + for _, d := range spec.Linux.Devices { + uid := spec.Process.User.UID + if d.UID != nil { + uid = *d.UID + } + gid := spec.Process.User.GID + if d.GID != nil { + gid = *d.GID + } + mode := os.FileMode(0600) + if d.FileMode != nil { + mode = *d.FileMode + } + _, err = fmt.Fprintf(f, "%s %s %d %d %o %d:%d\n", d.Path, d.Type, d.Major, d.Minor, mode, uid, gid) + if err != nil { + f.Close() + return err + } + } + return f.Close() +} diff --git a/lxcontainer/init.go b/lxcontainer/init.go index 0dc0aff2..ecb860df 100644 --- a/lxcontainer/init.go +++ b/lxcontainer/init.go @@ -24,9 +24,9 @@ func createFifo(dst string, uid int, gid int, mode uint32) error { return unix.Chown(dst, uid, gid) } -func configureInit(clxc *Runtime, spec *specs.Spec) error { - runtimeInitDir := clxc.RuntimePath(initDir) - rootfsInitDir := filepath.Join(spec.Root.Path, initDir) +func configureInit(rt *Runtime, c *Container) error { + runtimeInitDir := c.RuntimePath(initDir) + rootfsInitDir := filepath.Join(c.Root.Path, initDir) err := os.MkdirAll(rootfsInitDir, 0) if err != nil { @@ -38,37 +38,37 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { return fmt.Errorf("failed to create runtime init dir %q: %w", runtimeInitDir, err) } - spec.Mounts = append(spec.Mounts, specs.Mount{ + c.Mounts = append(c.Mounts, specs.Mount{ Source: runtimeInitDir, Destination: strings.TrimLeft(initDir, "/"), Type: "bind", Options: []string{"bind", "ro", "nodev", "nosuid"}, }) - if err := clxc.setConfigItem("lxc.init.cwd", initDir); err != nil { + if err := c.SetConfigItem("lxc.init.cwd", initDir); err != nil { return err } - uid := int(spec.Process.User.UID) - gid := int(spec.Process.User.GID) + uid := int(c.Process.User.UID) + gid := int(c.Process.User.GID) // create files required for crio-lxc-init - if err := createFifo(clxc.syncFifoPath(), uid, gid, 0600); err != nil { + if err := createFifo(c.syncFifoPath(), uid, gid, 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), spec.Process.Args, uid, gid, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, uid, gid, 0400); err != nil { return err } - if err := createList(filepath.Join(runtimeInitDir, "environ"), spec.Process.Env, uid, gid, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, uid, gid, 0400); err != nil { return err } - if err := os.Symlink(spec.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { + if err := os.Symlink(c.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { return err } - if spec.Annotations != nil { - msgPath := spec.Annotations["io.kubernetes.container.terminationMessagePath"] + if c.Annotations != nil { + msgPath := c.Annotations["io.kubernetes.container.terminationMessagePath"] if msgPath != "" { if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "error.log")); err != nil { return err @@ -76,7 +76,7 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { } } - if err := configureInitUser(clxc, spec); err != nil { + if err := configureInitUser(c); err != nil { return err } @@ -87,13 +87,13 @@ func configureInit(clxc *Runtime, spec *specs.Spec) error { return fmt.Errorf("failed to create %s: %w", initCmdPath, err) } initCmd := filepath.Join(initDir, "init") - spec.Mounts = append(spec.Mounts, specs.Mount{ - Source: clxc.Executables.Init, + c.Mounts = append(c.Mounts, specs.Mount{ + Source: rt.Executables.Init, Destination: strings.TrimLeft(initCmd, "/"), Type: "bind", Options: []string{"bind", "ro", "nosuid"}, }) - return clxc.setConfigItem("lxc.init.cmd", initCmd+" "+clxc.ContainerID) + return c.SetConfigItem("lxc.init.cmd", initCmd+" "+c.ContainerID) } func touchFile(filePath string, perm os.FileMode) error { @@ -133,37 +133,37 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err return unix.Chmod(dst, mode) } -func configureInitUser(clxc *Runtime, spec *specs.Spec) error { +func configureInitUser(c *Container) error { // TODO ensure that the user namespace is enabled // See `man lxc.container.conf` lxc.idmap. - for _, m := range spec.Linux.UIDMappings { - if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + for _, m := range c.Linux.UIDMappings { + if err := c.SetConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { return err } } - for _, m := range spec.Linux.GIDMappings { - if err := clxc.setConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { + for _, m := range c.Linux.GIDMappings { + if err := c.SetConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { return err } } - if err := clxc.setConfigItem("lxc.init.uid", fmt.Sprintf("%d", spec.Process.User.UID)); err != nil { + if err := c.SetConfigItem("lxc.init.uid", fmt.Sprintf("%d", c.Process.User.UID)); err != nil { return err } - if err := clxc.setConfigItem("lxc.init.gid", fmt.Sprintf("%d", spec.Process.User.GID)); err != nil { + if err := c.SetConfigItem("lxc.init.gid", fmt.Sprintf("%d", c.Process.User.GID)); err != nil { return err } - if len(spec.Process.User.AdditionalGids) > 0 && clxc.supportsConfigItem("lxc.init.groups") { + if len(c.Process.User.AdditionalGids) > 0 && c.SupportsConfigItem("lxc.init.groups") { var b strings.Builder - for i, gid := range spec.Process.User.AdditionalGids { + for i, gid := range c.Process.User.AdditionalGids { if i > 0 { b.WriteByte(',') } fmt.Fprintf(&b, "%d", gid) } - if err := clxc.setConfigItem("lxc.init.groups", b.String()); err != nil { + if err := c.SetConfigItem("lxc.init.groups", b.String()); err != nil { return err } } diff --git a/lxcontainer/log.go b/lxcontainer/log.go new file mode 100644 index 00000000..842fa7a4 --- /dev/null +++ b/lxcontainer/log.go @@ -0,0 +1,78 @@ +package lxcontainer + +import ( + "fmt" + "github.com/rs/zerolog" + "os" + "path/filepath" + "strconv" + "strings" + "time" +) + +type Log struct { + zerolog.Logger `json:"-"` + File *os.File `json:"-"` + FilePath string + Level string + Timestamp string + LevelContainer string +} + +func (log Log) Open(cmdName string) error { + logDir := filepath.Dir(log.FilePath) + err := os.MkdirAll(logDir, 0750) + if err != nil { + return fmt.Errorf("failed to create log file directory %s: %w", logDir, err) + } + + log.File, err = os.OpenFile(log.FilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) + if err != nil { + return err + } + + zerolog.LevelFieldName = "l" + zerolog.MessageFieldName = "m" + + // match liblxc timestamp format + zerolog.TimestampFieldName = "t" + zerolog.TimeFieldFormat = log.Timestamp + zerolog.TimestampFunc = func() time.Time { + return time.Now().UTC() + } + + // TODO only log caller information in debug and trace level + zerolog.CallerFieldName = "c" + zerolog.CallerMarshalFunc = func(file string, line int) string { + return filepath.Base(file) + ":" + strconv.Itoa(line) + } + + // NOTE Unfortunately it's not possible change the possition of the timestamp. + // The ttimestamp is appended to the to the log output because it is dynamically rendered + // see https://github.com/rs/zerolog/issues/109 + // FIXME ContainerID is not part of the runtime anymore + // rt.Log = zerolog.New(rt.LogFile).With().Timestamp().Caller(). + // Str("cmd", cmdName).Str("cid", c.ContainerID).Logger() + log.Logger = zerolog.New(log.File).With().Timestamp().Caller(). + Str("cmd", cmdName).Logger() + + level, err := zerolog.ParseLevel(strings.ToLower(log.Level)) + if err != nil { + level = zerolog.InfoLevel + log.Warn().Err(err).Str("val", log.Level).Stringer("default", level). + Msg("failed to parse log-level - fallback to default") + } + zerolog.SetGlobalLevel(level) + return nil +} + +func (log Log) Close() error { + return log.File.Close() +} + +// FIXME move to test utils ? +func testLogger() zerolog.Logger { + z := zerolog.New(os.Stderr) + zerolog.SetGlobalLevel(zerolog.DebugLevel) + return z +} diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index 02db1427..ee1b7a86 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -9,7 +9,7 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -func removeMountOptions(clxc *Runtime, fs string, opts []string, unsupported ...string) []string { +func removeMountOptions(c *Container, fs string, opts []string, unsupported ...string) []string { supported := make([]string, 0, len(opts)) for _, opt := range opts { addOption := true @@ -22,34 +22,34 @@ func removeMountOptions(clxc *Runtime, fs string, opts []string, unsupported ... if addOption { supported = append(supported, opt) } else { - clxc.Log.Info().Str("fs", fs).Str("option", opt).Msg("removed mount option") + c.Log.Info().Str("fs", fs).Str("option", opt).Msg("removed mount option") } } return supported } -func filterMountOptions(clxc *Runtime, fs string, opts []string) []string { +func filterMountOptions(c *Container, fs string, opts []string) []string { switch fs { case "sysfs": - return removeMountOptions(clxc, fs, opts, "rslave") + return removeMountOptions(c, fs, opts, "rslave") case "tmpfs": // TODO make this configurable per filesystem - return removeMountOptions(clxc, fs, opts, "rprivate", "tmpcopyup") + return removeMountOptions(c, fs, opts, "rprivate", "tmpcopyup") case "cgroup2": // TODO make this configurable per filesystem - return removeMountOptions(clxc, fs, opts, "private", "rslave") + return removeMountOptions(c, fs, opts, "private", "rslave") } return opts } -func configureMounts(clxc *Runtime, spec *specs.Spec) error { +func configureMounts(c *Container) error { // excplicitly disable auto-mounting - if err := clxc.setConfigItem("lxc.mount.auto", ""); err != nil { + if err := c.SetConfigItem("lxc.mount.auto", ""); err != nil { return err } - for i := range spec.Mounts { - ms := spec.Mounts[i] + for i := range c.Mounts { + ms := c.Mounts[i] if ms.Type == "cgroup" { // TODO check if hieararchy is cgroup v2 only (unified mode) ms.Type = "cgroup2" @@ -62,28 +62,28 @@ func configureMounts(clxc *Runtime, spec *specs.Spec) error { // TODO replace with symlink.FollowSymlinkInScope(filepath.Join(rootfs, "/etc/passwd"), rootfs) ? // "github.com/docker/docker/pkg/symlink" - mountDest, err := resolveMountDestination(spec.Root.Path, ms.Destination) + mountDest, err := resolveMountDestination(c.Root.Path, ms.Destination) // Intermediate path resolution failed. This is not an error, since // the remaining directories / files are automatically created (create=dir|file) - clxc.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") + c.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. - if !filepath.HasPrefix(mountDest, spec.Root.Path) { + if !filepath.HasPrefix(mountDest, c.Root.Path) { // refuses mount destinations that escape from rootfs - return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, spec.Root.Path) + return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, c.Root.Path) } ms.Destination = mountDest - err = createMountDestination(spec, &ms) + err = createMountDestination(c, &ms) if err != nil { return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) } - ms.Options = filterMountOptions(clxc, ms.Type, ms.Options) + ms.Options = filterMountOptions(c, ms.Type, ms.Options) mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, strings.Join(ms.Options, ",")) - if err := clxc.setConfigItem("lxc.mount.entry", mnt); err != nil { + if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { return err } } @@ -99,7 +99,7 @@ func configureMounts(clxc *Runtime, spec *specs.Spec) error { // TODO check whether this is desired behaviour in lxc ? // Shouldn't the rootfs should be mounted readonly after all mounts destination directories have been created ? // https://github.com/lxc/lxc/issues/1702 -func createMountDestination(spec *specs.Spec, ms *specs.Mount) error { +func createMountDestination(spec *Container, ms *specs.Mount) error { info, err := os.Stat(ms.Source) if err != nil && ms.Type == "bind" { // check if mountpoint is optional ? diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index 432da059..989c585e 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -74,14 +74,13 @@ func TestResolveMountDestination_relative(t *testing.T) { } func TestFilterMountOptions(t *testing.T) { - rt := Runtime{LogFilePath: "/dev/stderr", LogLevel: "debug"} - rt.ConfigureLogging("test") + c := &Container{Log: testLogger()} opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") - out := filterMountOptions(&rt, "tmpfs", opts) + out := filterMountOptions(c, "tmpfs", opts) require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) - out = filterMountOptions(&rt, "nosuchfs", opts) + out = filterMountOptions(c, "nosuchfs", opts) require.Equal(t, opts, out) } diff --git a/lxcontainer/namespaces.go b/lxcontainer/namespaces.go index dad6326c..4ac1cd92 100644 --- a/lxcontainer/namespaces.go +++ b/lxcontainer/namespaces.go @@ -49,11 +49,11 @@ func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { return flags, nil } -func configureNamespaces(clxc *Runtime, namespaces []specs.LinuxNamespace) error { +func configureNamespaces(c *Container) error { seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} - cloneNamespaces := make([]string, 0, len(namespaces)) + cloneNamespaces := make([]string, 0, len(c.Linux.Namespaces)) - for _, ns := range namespaces { + for _, ns := range c.Linux.Namespaces { if _, seen := seenNamespaceTypes[ns.Type]; seen { return fmt.Errorf("duplicate namespace %s", ns.Type) } @@ -70,12 +70,12 @@ func configureNamespaces(clxc *Runtime, namespaces []specs.LinuxNamespace) error } configKey := fmt.Sprintf("lxc.namespace.share.%s", n.Name) - if err := clxc.setConfigItem(configKey, ns.Path); err != nil { + if err := c.SetConfigItem(configKey, ns.Path); err != nil { return err } } - return clxc.setConfigItem("lxc.namespace.clone", strings.Join(cloneNamespaces, " ")) + return c.SetConfigItem("lxc.namespace.clone", strings.Join(cloneNamespaces, " ")) } func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool { diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index 8a8425dc..f272ba4a 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -3,36 +3,26 @@ package lxcontainer import ( "context" "fmt" - "io/ioutil" "os" - "path/filepath" - "strconv" - "strings" + "os/exec" "time" - "golang.org/x/sys/unix" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/rs/zerolog" - "gopkg.in/lxc/go-lxc.v2" + "golang.org/x/sys/unix" ) var ErrNotExist = fmt.Errorf("container does not exist") var ErrExist = fmt.Errorf("container already exists") type Runtime struct { - Container *lxc.Container `json:"-"` - Log zerolog.Logger `json:"-"` - LogFile *os.File `json:"-"` - - ContainerInfo `json:"-"` - - LogFilePath string - LogLevel string - LogTimestamp string - ContainerLogLevel string + Log + Root string + // Use systemd encoded cgroup path (from crio-o/conmon) + // is true if /etc/crio/crio.conf#cgroup_manager = "systemd" SystemdCgroup bool + // Path for lxc monitor cgroup (lxc specific feature) + // similar to /etc/crio/crio.conf#conmon_cgroup MonitorCgroup string // Executables contains names for all (external) executed commands. @@ -62,659 +52,133 @@ type Runtime struct { // runtime hooks (not OCI runtime hooks) - // AfterCreateContainer is called right after creating the container runtime directory and descriptor, - // and before creating the lxc 'config' file for the container. - AfterCreateContainer func(c *Runtime) error `json:"-"` -} - -// createContainer creates a new container. -// It must only be called once during the lifecycle of a container. -func (c *Runtime) createContainer(spec *specs.Spec) error { - if c.runtimePathExists() { - return ErrExist - } - - if err := os.MkdirAll(c.RuntimePath(), 0700); err != nil { - return fmt.Errorf("failed to create container dir: %w", err) - } - - // An empty tmpfile is created to ensure that createContainer can only succeed once. - // The config file is atomically activated in saveConfig. - // #nosec - f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) - if err != nil { - return err - } - if err := f.Close(); err != nil { - return fmt.Errorf("failed to close empty config tmpfile: %w", err) - } - - if spec.Linux.CgroupsPath == "" { - //return fmt.Errorf("empty cgroups path in spec") - spec.Linux.CgroupsPath = "foo.slice" - } - if c.SystemdCgroup { - c.CgroupDir = parseSystemdCgroupPath(spec.Linux.CgroupsPath) - } else { - c.CgroupDir = spec.Linux.CgroupsPath - } - - c.MonitorCgroupDir = filepath.Join(c.MonitorCgroup, c.ContainerID+".scope") - - if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { - return err - } - - c.Annotations = spec.Annotations - c.Namespaces = spec.Linux.Namespaces - - if err := c.ContainerInfo.Create(); err != nil { - return err - } - - container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) - if err != nil { - return err - } - c.Container = container - if err := c.setContainerLogLevel(); err != nil { - return err + Hooks struct { + // AfterCreateContainer is called right after creating the container runtime directory and descriptor, + // and before creating the lxc 'config' file for the container. + AfterCreate func(ctx context.Context, c *Container) error `json:"-"` } +} - if c.AfterCreateContainer != nil { - return c.AfterCreateContainer(c) - } - return nil +// Release releases/closes allocated resources (lxc.Container, LogFile) +func (rt *Runtime) Close() error { + return rt.Log.File.Close() } -// loadContainer checks for the existence of the lxc config file. -// It returns an error if the config file does not exist. -func (c *Runtime) loadContainer() error { - if !c.runtimePathExists() { - return ErrNotExist - } +func (rt *Runtime) Start(ctx context.Context, c *Container) error { + ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Start) + defer cancel() - if err := c.ContainerInfo.Load(); err != nil { - return fmt.Errorf("failed to load container config: %w", err) - } + c.Log.Info().Msg("notify init to start container process") - if _, err := os.Stat(c.ConfigFilePath()); err != nil { - return fmt.Errorf("failed to load lxc config file: %w", err) - } - container, err := lxc.NewContainer(c.ContainerID, c.RuntimeRoot) + state, err := c.State() if err != nil { - return fmt.Errorf("failed to create new lxc container: %w", err) + return errorf("failed to get container state: %w", err) } - c.Container = container - err = container.LoadConfigFile(c.ConfigFilePath()) - if err != nil { - return fmt.Errorf("failed to load config file: %w", err) + if state.Status != specs.StateCreated { + return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state.Status) } - return c.setContainerLogLevel() + return c.Start(ctx) } -func (c *Runtime) configureCgroupPath() error { - if err := c.setConfigItem("lxc.cgroup.relative", "0"); err != nil { - return err - } - - if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { - return err - } - - if c.supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { +func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { + // #nosec + cmd := exec.Command(rt.Executables.Start, c.linuxcontainer.Name(), rt.Root, c.ConfigFilePath()) + cmd.Env = []string{} + cmd.Dir = c.RuntimePath() + + if c.ConsoleSocket == "" && !c.Process.Terminal { + // Inherit stdio from calling process (conmon). + // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc + if err := c.SetConfigItem("lxc.console.path", "none"); err != nil { return err } + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr } - /* - // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb - // checking for on of the config items shuld be enough, because they were introduced together ... - if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { - if err := c.setConfigItem("lxc.cgroup.dir.container", c.CgroupDir); err != nil { - return err - } - if err := c.setConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroupDir); err != nil { - return err - } - } else { - if err := c.setConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { - return err - } - } - if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := c.setConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { - return err - } - } - */ - return nil -} - -// Release releases/closes allocated resources (lxc.Container, LogFile) -func (c Runtime) Release() error { - if c.Container != nil { - if err := c.Container.Release(); err != nil { - c.Log.Error().Err(err).Msg("failed to release container") - } - c.Container = nil - } - if c.LogFile != nil { - err := c.LogFile.Close() - c.LogFile = nil + if err := c.SaveConfig(); err != nil { return err } - return nil -} -func (c *Runtime) ConfigureLogging(cmdName string) error { - logDir := filepath.Dir(c.LogFilePath) - err := os.MkdirAll(logDir, 0750) - if err != nil { - return fmt.Errorf("failed to create log file directory %s: %w", logDir, err) + c.Log.Debug().Msg("starting lxc monitor process") + if c.ConsoleSocket != "" { + err = runStartCmdConsole(ctx, cmd, c.ConsoleSocket) + } else { + err = cmd.Start() } - c.LogFile, err = os.OpenFile(c.LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { return err } - zerolog.LevelFieldName = "l" - zerolog.MessageFieldName = "m" - - // match liblxc timestamp format - zerolog.TimestampFieldName = "t" - zerolog.TimeFieldFormat = c.LogTimestamp - zerolog.TimestampFunc = func() time.Time { - return time.Now().UTC() - } - - // TODO only log caller information in debug and trace level - zerolog.CallerFieldName = "c" - zerolog.CallerMarshalFunc = func(file string, line int) string { - return filepath.Base(file) + ":" + strconv.Itoa(line) - } - - // NOTE Unfortunately it's not possible change the possition of the timestamp. - // The ttimestamp is appended to the to the log output because it is dynamically rendered - // see https://github.com/rs/zerolog/issues/109 - c.Log = zerolog.New(c.LogFile).With().Timestamp().Caller(). - Str("cmd", cmdName).Str("cid", c.ContainerID).Logger() - - level, err := zerolog.ParseLevel(strings.ToLower(c.LogLevel)) - if err != nil { - level = zerolog.InfoLevel - c.Log.Warn().Err(err).Str("val", c.LogLevel).Stringer("default", level). - Msg("failed to parse log-level - fallback to default") - } - zerolog.SetGlobalLevel(level) - return nil -} - -func (c *Runtime) setContainerLogLevel() error { - // Never let lxc write to stdout, stdout belongs to the container init process. - // Explicitly disable it - allthough it is currently the default. - c.Container.SetVerbosity(lxc.Quiet) - // The log level for a running container is set, and may change, per runtime call. - err := c.Container.SetLogLevel(c.parseContainerLogLevel()) - if err != nil { - return fmt.Errorf("failed to set container loglevel: %w", err) - } - if err := c.Container.SetLogFile(c.LogFilePath); err != nil { - return fmt.Errorf("failed to set container log file: %w", err) - } - return nil -} - -func (c *Runtime) parseContainerLogLevel() lxc.LogLevel { - switch strings.ToLower(c.ContainerLogLevel) { - case "trace": - return lxc.TRACE - case "debug": - return lxc.DEBUG - case "info": - return lxc.INFO - case "notice": - return lxc.NOTICE - case "warn": - return lxc.WARN - case "error": - return lxc.ERROR - case "crit": - return lxc.CRIT - case "alert": - return lxc.ALERT - case "fatal": - return lxc.FATAL - default: - c.Log.Warn().Str("val", c.ContainerLogLevel). - Stringer("default", lxc.WARN). - Msg("failed to parse container-log-level - fallback to default") - return lxc.WARN - } -} - -func (c *Runtime) isContainerStopped() bool { - return c.Container.State() == lxc.STOPPED -} - -func (c *Runtime) waitCreated(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - state := c.Container.State() - if !(state == lxc.RUNNING) { - c.Log.Debug().Stringer("state", state).Msg("wait for state lxc.RUNNING") - time.Sleep(time.Millisecond * 100) - continue - } - initState, err := c.getContainerInitState() - if err != nil { - return err - } - if initState == specs.StateCreated { - return nil - } - return fmt.Errorf("unexpected init state %q", initState) - } - } -} - -func (c *Runtime) waitNot(ctx context.Context, state specs.ContainerState) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - initState, _ := c.getContainerInitState() - if initState != state { - return nil - } - time.Sleep(time.Millisecond * 10) - } - } -} - -func (c *Runtime) wait(ctx context.Context, state lxc.State) bool { - for { - select { - case <-ctx.Done(): - return false - default: - if c.Container.State() == state { - return true - } - time.Sleep(time.Millisecond * 100) - } - } -} - -func (c *Runtime) getContainerState() (specs.ContainerState, error) { - state := c.Container.State() - switch state { - case lxc.STOPPED: - return specs.StateStopped, nil - case lxc.STARTING: - return specs.StateCreating, nil - case lxc.RUNNING, lxc.STOPPING, lxc.ABORTING, lxc.FREEZING, lxc.FROZEN, lxc.THAWED: - return c.getContainerInitState() - default: - return specs.StateStopped, fmt.Errorf("unsupported lxc container state %q", state) - } -} - -// getContainerInitState returns the detailed state of the container init process. -// This should be called if the container is in state lxc.RUNNING. -// On error the caller should call getContainerState() again -func (c *Runtime) getContainerInitState() (specs.ContainerState, error) { - initPid := c.Container.InitPid() - if initPid < 1 { - return specs.StateStopped, nil - } - cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) - cmdline, err := ioutil.ReadFile(cmdlinePath) - if os.IsNotExist(err) { - // init process died or returned - return specs.StateStopped, nil - } - if err != nil { - // it's a serious error if cmdlinePath exists but can't be read - return specs.StateStopped, err - } - - initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) - if string(cmdline) == initCmdline { - return specs.StateCreated, nil - } - return specs.StateRunning, nil -} - -func (c *Runtime) killContainer(ctx context.Context, signum unix.Signal) error { - c.Log.Info().Int("signum", int(signum)).Msg("killing container process") - if signum == unix.SIGKILL || signum == unix.SIGTERM { - if err := c.setConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { - return err - } - if err := c.Container.Stop(); err != nil { - return err - } - - if !c.wait(ctx, lxc.STOPPED) { - c.Log.Warn().Msg("failed to stop lxc container") - } + ctx, cancel := context.WithCancel(ctx) + defer cancel() - // draining the cgroup is required to catch processes that escaped from - // 'kill' e.g a bash for loop that spawns a new child immediately. - start := time.Now() - err := drainCgroup(ctx, c.CgroupDir, signum) - if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + go func() { + // NOTE this goroutine may leak until crio-lxc is terminated + ps, err := cmd.Process.Wait() + if err != nil { + c.Log.Error().Err(err).Msg("failed to wait for start process") } else { - c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") - } - return err - } - - // send non-terminating signals to monitor process - pid, err := c.Pid() - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load pidfile: %w", err) - } - if pid > 1 { - c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - if err := unix.Kill(pid, 0); err == nil { - err := unix.Kill(pid, signum) - if err != unix.ESRCH { - return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) - } + c.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") } - } - return nil -} - -// "Note that resources associated with the container, -// but not created by this container, MUST NOT be deleted." -// TODO - because we set rootfs.managed=0, Destroy() doesn't -// delete the /var/lib/lxc/$containerID/config file: -func (c *Runtime) destroy() error { - if c.Container != nil { - if err := c.Container.Destroy(); err != nil { - return fmt.Errorf("failed to destroy container: %w", err) - } - } + cancel() + }() - if c.ContainerInfo.CgroupDir != "" { - err := deleteCgroup(c.CgroupDir) - if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") - } + c.Log.Debug().Msg("waiting for init") + if err := c.waitCreated(ctx); err != nil { + return err } - return os.RemoveAll(c.RuntimePath()) -} - -// saveConfig creates and atomically enables the lxc config file. -// It must be called after #createContainer and only once. -// Any config changes via clxc.setConfigItem must be done -// before calling saveConfig. -func (c *Runtime) saveConfig() error { - // createContainer creates the tmpfile - tmpFile := c.RuntimePath(".config") - if _, err := os.Stat(tmpFile); err != nil { - return fmt.Errorf("failed to stat config tmpfile: %w", err) - } - // Don't overwrite an existing config. - cfgFile := c.ConfigFilePath() - if _, err := os.Stat(cfgFile); err == nil { - return fmt.Errorf("config file %s already exists", cfgFile) - } - err := c.Container.SaveConfigFile(tmpFile) - if err != nil { - return fmt.Errorf("failed to save config file to %q: %w", tmpFile, err) - } - if err := os.Rename(tmpFile, cfgFile); err != nil { - return fmt.Errorf("failed to rename config file: %w", err) - } - return nil + c.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") + return CreatePidFile(c.PidFile, cmd.Process.Pid) } -func (c *Runtime) Start(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Start) +func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) error { + ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Kill) defer cancel() - c.Log.Info().Msg("notify init to start container process") - - err := c.loadContainer() - if err != nil { - return errorf("failed to load container: %w", err) - } - - state, err := c.getContainerState() - if err != nil { - return errorf("failed to get container state: %w", err) - } - if state != specs.StateCreated { - return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state) - } - - done := make(chan error) - go func() { - done <- c.readFifo() - }() - - select { - case <-ctx.Done(): - return errorf("syncfifo timeout: %w", ctx.Err()) - case err := <-done: - if err != nil { - return errorf("failed to read from syncfifo: %w", err) - } - } - // wait for container state to change - return c.waitNot(ctx, specs.StateCreated) -} - -func (c *Runtime) syncFifoPath() string { - return c.RuntimePath(initDir, "syncfifo") -} - -func (c *Runtime) readFifo() error { - // #nosec - f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) + state, err := c.ContainerState() if err != nil { return err } - // can not set deadline on fifo - // #nosec - defer f.Close() - - data := make([]byte, len(c.ContainerID)) - _, err = f.Read(data) - if err != nil { - return fmt.Errorf("problem reading from fifo: %w", err) - } - if c.ContainerID != string(data) { - return fmt.Errorf("bad fifo content: %s", string(data)) + if state == specs.StateStopped { + return errorf("container already stopped") } - return nil + return c.Kill(ctx, signum) } -func (c *Runtime) Delete(ctx context.Context, force bool) error { - ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Delete) +func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { + ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Delete) defer cancel() - err := c.loadContainer() - if err == ErrNotExist { - c.Log.Info().Msg("container does not exist") - return nil + rt.Log.Info().Bool("force", force).Msg("delete container") + state, err := c.ContainerState() + if err != nil { + return err } - c.Log.Info().Bool("force", force).Msg("delete container") - if err == nil && !c.isContainerStopped() { + if state != specs.StateStopped { if !force { - return errorf("container is not not stopped (current state %s)", c.Container.State()) + return errorf("container is not not stopped (current state %s)", state) } - if err := c.killContainer(ctx, unix.SIGKILL); err != nil { + if err := c.Kill(ctx, unix.SIGKILL); err != nil { return errorf("failed to kill container: %w", err) } } - if err := c.destroy(); err != nil { + if err := c.Destroy(); err != nil { return errorf("failed to destroy container: %w", err) } return nil } -func (c *Runtime) State() (*specs.State, error) { - err := c.loadContainer() - if err != nil { - return nil, errorf("failed to load container: %w", err) - } - - pid, err := c.Pid() - if err != nil { - return nil, errorf("failed to load pidfile: %w", err) - } - - state := &specs.State{ - Version: specs.Version, - ID: c.Container.Name(), - Bundle: c.BundlePath, - Pid: pid, - Annotations: c.Annotations, - } - - state.Status, err = c.getContainerState() - if err != nil { - return nil, errorf("failed to get container state: %w", err) - } - - c.Log.Info().Int("pid", state.Pid).Str("status", string(state.Status)).Msg("container state") - return state, nil -} - -func (c *Runtime) Kill(ctx context.Context, signum unix.Signal) error { - ctx, cancel := context.WithTimeout(ctx, c.Timeouts.Kill) - defer cancel() - - err := c.loadContainer() - if err != nil { - return errorf("failed to load container: %w", err) - } - state := c.Container.State() - if state != lxc.RUNNING { - return errorf("can only kill container in state lxc.RUNNING but was %q", state) - } - if err := c.killContainer(ctx, signum); err != nil { - return errorf("failed to kill container: %w", err) - } - return nil -} - -func (c *Runtime) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { - err = c.loadContainer() - if err != nil { - return 0, errorf("failed to load container: %w", err) - } - - opts, err := attachOptions(proc, c.Namespaces) - if err != nil { - return 0, errorf("failed to create attach options: %w", err) - } - - c.Log.Info().Strs("args", args). - Int("uid", opts.UID).Int("gid", opts.GID). - Ints("groups", opts.Groups).Msg("execute cmd") - - pid, err = c.Container.RunCommandNoWait(args, opts) - if err != nil { - return pid, errorf("failed to run exec cmd detached: %w", err) - } - return pid, nil +func (rt *Runtime) Release() error { + return rt.Log.Close() } -func (c *Runtime) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { - err = c.loadContainer() - if err != nil { - return 0, errorf("failed to load container: %w", err) - } - opts, err := attachOptions(proc, c.Namespaces) - if err != nil { - return 0, errorf("failed to create attach options: %w", err) - } - exitStatus, err = c.Container.RunCommandStatus(args, opts) - if err != nil { - return exitStatus, errorf("failed to run exec cmd: %w", err) - } - return exitStatus, nil -} - -func (c *Runtime) getConfigItem(key string) string { - vals := c.Container.ConfigItem(key) - if len(vals) > 0 { - first := vals[0] - // some lxc config values are set to '(null)' if unset - // eg. lxc.cgroup.dir - if first != "(null)" { - return first - } - } - return "" -} - -func (c *Runtime) setConfigItem(key, value string) error { - err := c.Container.SetConfigItem(key, value) - if err != nil { - return fmt.Errorf("failed to set config item '%s=%s': %w", key, value, err) - } - c.Log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") - return nil -} - -func (c *Runtime) supportsConfigItem(keys ...string) bool { - canCheck := lxc.VersionAtLeast(4, 0, 6) - if !canCheck { - c.Log.Warn().Msg("lxc.IsSupportedConfigItem is broken in liblxc < 4.0.6") - } - for _, key := range keys { - if canCheck && lxc.IsSupportedConfigItem(key) { - continue - } - c.Log.Info().Str("lxc.config", key).Msg("unsupported config item") - return false - } - return true -} - -func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.AttachOptions, error) { - opts := lxc.AttachOptions{ - StdinFd: 0, - StdoutFd: 1, - StderrFd: 2, - } - - clone, err := cloneFlags(ns) - if err != nil { - return opts, err - } - opts.Namespaces = clone - - if procSpec != nil { - opts.Cwd = procSpec.Cwd - // Use the environment defined by the process spec. - opts.ClearEnv = true - opts.Env = procSpec.Env - - opts.UID = int(procSpec.User.UID) - opts.GID = int(procSpec.User.GID) - if n := len(procSpec.User.AdditionalGids); n > 0 { - opts.Groups = make([]int, n) - for i, g := range procSpec.User.AdditionalGids { - opts.Groups[i] = int(g) - } - } - } - return opts, nil +func ReadSpecProcessJSON(src string) (*specs.Process, error) { + proc := new(specs.Process) + err := decodeFileJSON(proc, src) + return proc, err } diff --git a/lxcontainer/utils.go b/lxcontainer/utils.go index 2957907c..d2f748ea 100644 --- a/lxcontainer/utils.go +++ b/lxcontainer/utils.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "runtime" + "strings" "golang.org/x/sys/unix" ) @@ -74,7 +75,7 @@ func isFilesystem(dir string, fsName string) error { return nil } -func DecodeFileJSON(obj interface{}, src string) error { +func decodeFileJSON(obj interface{}, src string) error { // #nosec f, err := os.Open(src) if err != nil { @@ -166,3 +167,15 @@ func mkdirAll(path string, perm os.FileMode, uid int, gid int) error { } return unix.Chown(path, uid, gid) } + +func setenv(env []string, key, val string, overwrite bool) []string { + for i, kv := range env { + if strings.HasPrefix(kv, key+"=") { + if overwrite { + env[i] = key + "=" + val + } + return env + } + } + return append(env, key+"="+val) +} From 7fca8fb4582c43cfd9bec5506ff61b5464dbe9bf Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 14:24:59 +0100 Subject: [PATCH 204/373] cli: Update CLI for lxcontainer changes. Signed-off-by: Ruben Jenster --- cmd/cli.go | 133 ++++++++++++++++++++++++----------------------------- 1 file changed, 61 insertions(+), 72 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 9a1ca530..cb827e2d 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -11,7 +11,6 @@ import ( "time" "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer" - "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) @@ -22,6 +21,7 @@ var envFile = "/etc/default/crio-lxc" // The singelton that wraps the lxc.Container var clxc struct { lxcontainer.Runtime + ContainerConfig lxcontainer.ContainerConfig Command string CreateHook string @@ -57,35 +57,35 @@ func main() { Usage: "set the runtime log level (trace|debug|info|warn|error)", EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, Value: "info", - Destination: &clxc.LogLevel, + Destination: &clxc.Log.Level, }, &cli.StringFlag{ Name: "container-log-level", Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, Value: "warn", - Destination: &clxc.ContainerLogLevel, + Destination: &clxc.Log.LevelContainer, }, &cli.StringFlag{ Name: "log-file", Usage: "path to the log file for runtime and container output", EnvVars: []string{"CRIO_LXC_LOG_FILE"}, Value: "/var/log/crio-lxc/crio-lxc.log", - Destination: &clxc.LogFilePath, + Destination: &clxc.Log.FilePath, }, &cli.StringFlag{ Name: "log-timestamp", Usage: "timestamp format for the runtime log (see golang time package), default matches liblxc timestamp", EnvVars: []string{"CRIO_LXC_LOG_TIMESTAMP"}, // e.g '0102 15:04:05.000' Value: "20060102150405.000", - Destination: &clxc.LogTimestamp, + Destination: &clxc.Log.Timestamp, }, &cli.StringFlag{ Name: "root", Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended.", // exec permissions are not required because init is bind mounted into the root Value: "/run/crio-lxc", - Destination: &clxc.RuntimeRoot, + Destination: &clxc.Root, }, &cli.BoolFlag{ Name: "systemd-cgroup", @@ -104,21 +104,21 @@ func main() { Usage: "absolute path to container init executable", EnvVars: []string{"CRIO_LXC_INIT_CMD"}, Value: "/usr/local/bin/crio-lxc-init", - Destination: &clxc.InitCommand, + Destination: &clxc.Executables.Init, }, &cli.StringFlag{ Name: "cmd-start", Usage: "absolute path to container start executable", EnvVars: []string{"CRIO_LXC_START_CMD"}, Value: "/usr/local/bin/crio-lxc-start", - Destination: &clxc.StartCommand, + Destination: &clxc.Executables.Start, }, &cli.StringFlag{ Name: "container-hook", Usage: "absolute path to container hook executable", EnvVars: []string{"CRIO_LXC_CONTAINER_HOOK"}, Value: "/usr/local/bin/crio-lxc-container-hook", - Destination: &clxc.ContainerHook, + Destination: &clxc.Executables.Hook, }, &cli.BoolFlag{ Name: "apparmor", @@ -194,8 +194,8 @@ func main() { if len(containerID) == 0 { return fmt.Errorf("missing container ID") } - clxc.ContainerID = containerID - return clxc.ConfigureLogging(ctx.Command.Name) + clxc.ContainerConfig.ContainerID = containerID + return clxc.Log.Open(ctx.Command.Name) } for _, cmd := range app.Commands { @@ -238,25 +238,26 @@ var createCmd = cli.Command{ Name: "bundle", Usage: "set bundle directory", Value: ".", - Destination: &clxc.BundlePath, + Destination: &clxc.ContainerConfig.BundlePath, }, &cli.StringFlag{ Name: "console-socket", Usage: "send container pty master fd to this socket path", - Destination: &clxc.ConsoleSocket, + Destination: &clxc.ContainerConfig.ConsoleSocket, }, &cli.StringFlag{ Name: "pid-file", Usage: "path to write container PID", - Destination: &clxc.PidFile, + Destination: &clxc.ContainerConfig.PidFile, }, &cli.DurationFlag{ Name: "timeout", Usage: "maximum duration for create to complete", EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, Value: time.Second * 60, - Destination: &clxc.CreateTimeout, + Destination: &clxc.Timeouts.Create, }, + // TODO implement OCI hooks and move to Runtime.Hooks &cli.StringFlag{ Name: "create-hook", Usage: "absolute path to executable to run after create", @@ -274,31 +275,26 @@ var createCmd = cli.Command{ } func doCreate(unused *cli.Context) error { - err := doCreateInternal(unused) - if clxc.CreateHook != "" { - runCreateHook(err) - } - return err -} - -func doCreateInternal(unused *cli.Context) error { - specPath := filepath.Join(clxc.BundlePath, "config.json") - spec, err := readSpec(specPath) + specPath := filepath.Join(clxc.ContainerConfig.BundlePath, "config.json") + err := clxc.ContainerConfig.LoadSpecJson(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } - return clxc.Create(context.Background(), spec) + c, err := clxc.Create(context.Background(), &clxc.ContainerConfig) + defer c.Release() + runCreateHook(err) + return err } func runCreateHook(err error) { env := []string{ - "CONTAINER_ID=" + clxc.ContainerID, - "LXC_CONFIG=" + clxc.ConfigFilePath(), + "CONTAINER_ID=" + clxc.ContainerConfig.ContainerID, + "LXC_CONFIG=" + clxc.ContainerConfig.ConfigFilePath(), "RUNTIME_CMD=" + clxc.Command, - "RUNTIME_PATH=" + clxc.RuntimePath(), - "BUNDLE_PATH=" + clxc.BundlePath, - "SPEC_PATH=" + filepath.Join(clxc.BundlePath, "config.json"), - "LOG_FILE=" + clxc.LogFilePath, + "RUNTIME_PATH=" + clxc.ContainerConfig.RuntimePath(), + "BUNDLE_PATH=" + clxc.ContainerConfig.BundlePath, + "SPEC_PATH=" + clxc.ContainerConfig.SpecPath, + "LOG_FILE=" + clxc.Log.FilePath, } if err != nil { env = append(env, "RUNTIME_ERROR="+err.Error()) @@ -328,13 +324,18 @@ starts Usage: "start timeout", EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, Value: time.Second * 30, - Destination: &clxc.StartTimeout, + Destination: &clxc.Timeouts.Start, }, }, } func doStart(unused *cli.Context) error { - return clxc.Start(context.Background()) + c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + if err != nil { + return fmt.Errorf("failed to load container: %w", err) + } + + return clxc.Start(context.Background(), c) } var stateCmd = cli.Command{ @@ -349,7 +350,11 @@ var stateCmd = cli.Command{ } func doState(unused *cli.Context) error { - state, err := clxc.State() + c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + if err != nil { + return fmt.Errorf("failed to load container: %w", err) + } + state, err := c.State() if err != nil { return err } @@ -377,7 +382,7 @@ var killCmd = cli.Command{ Usage: "timeout for killing all processes in container cgroup", EnvVars: []string{"CRIO_LXC_KILL_TIMEOUT"}, Value: time.Second * 10, - Destination: &clxc.KillTimeout, + Destination: &clxc.Timeouts.Kill, }, }, } @@ -388,7 +393,12 @@ func doKill(ctx *cli.Context) error { if signum == 0 { return fmt.Errorf("invalid signal param %q", sig) } - return clxc.Kill(context.Background(), signum) + + c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + if err != nil { + return fmt.Errorf("failed to load container: %w", err) + } + return clxc.Kill(context.Background(), c, signum) } var deleteCmd = cli.Command{ @@ -409,18 +419,19 @@ var deleteCmd = cli.Command{ Usage: "timeout for deleting container", EnvVars: []string{"CRIO_LXC_DELETE_TIMEOUT"}, Value: time.Second * 10, - Destination: &clxc.DeleteTimeout, + Destination: &clxc.Timeouts.Delete, }, }, } func doDelete(ctx *cli.Context) error { - err := clxc.Delete(context.Background(), ctx.Bool("force")) - if errors.Is(err, lxcontainer.ErrNotExist) { - clxc.Log.Warn().Msg("container does not exist") + c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + if err == lxcontainer.ErrNotExist { + clxc.Log.Info().Msg("container does not exist") return nil } - return err + + return clxc.Delete(context.Background(), c, ctx.Bool("force")) } var execCmd = cli.Command{ @@ -483,7 +494,7 @@ func doExec(ctx *cli.Context) error { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := readSpecProcess(ctx.String("process")) + procSpec, err := lxcontainer.ReadSpecProcessJSON(ctx.String("process")) if err != nil { return err } @@ -491,8 +502,13 @@ func doExec(ctx *cli.Context) error { args = procSpec.Args } + c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + if err != nil { + return err + } + if detach { - pid, err := clxc.ExecDetached(args, procSpec) + pid, err := c.ExecDetached(args, procSpec) if err != nil { return err } @@ -500,7 +516,7 @@ func doExec(ctx *cli.Context) error { return lxcontainer.CreatePidFile(pidFile, pid) } } else { - status, err := clxc.Exec(args, procSpec) + status, err := c.Exec(args, procSpec) if err != nil { return err } @@ -510,30 +526,3 @@ func doExec(ctx *cli.Context) error { } return nil } - -func readSpec(src string) (*specs.Spec, error) { - spec := new(specs.Spec) - err := lxcontainer.DecodeFileJSON(spec, src) - return spec, err -} - -func readSpecProcess(src string) (*specs.Process, error) { - if src == "" { - return nil, nil - } - proc := new(specs.Process) - err := lxcontainer.DecodeFileJSON(proc, src) - return proc, err -} - -/* -func (c ContainerInfo) SpecPath() string { - return filepath.Join(c.BundlePath, "config.json") -} - -func (c *ContainerInfo) ReadSpec() (*specs.Spec, error) { - spec := new(specs.Spec) - err := DecodeFileJSON(spec, c.SpecPath()) - return spec, err -} -*/ From aa871f78afdcce1c8ab3b22136b2ee7d49bb5be4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 14:55:38 +0100 Subject: [PATCH 205/373] Fix refactoring regressions. Signed-off-by: Ruben Jenster --- cmd/cli.go | 4 +++- lxcontainer/container.go | 6 +++--- lxcontainer/create.go | 4 ---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index cb827e2d..f02e1caf 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -281,7 +281,9 @@ func doCreate(unused *cli.Context) error { return fmt.Errorf("failed to load container spec from bundle: %w", err) } c, err := clxc.Create(context.Background(), &clxc.ContainerConfig) - defer c.Release() + if err == nil { + defer c.Release() + } runCreateHook(err) return err } diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 7ddc041d..3579b4c4 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -66,6 +66,7 @@ func (cfg ContainerConfig) Pid() (int, error) { func (c *ContainerConfig) LoadSpecJson(p string) error { c.SpecPath = p + c.Spec = &specs.Spec{} return decodeFileJSON(c.Spec, p) } @@ -334,9 +335,8 @@ func (c *Container) Kill(ctx context.Context, signum unix.Signal) error { } // SaveConfig creates and atomically enables the lxc config file. -// It must be called after #createContainer and only once. -// Any config changes via clxc.setConfigItem must be done -// before calling SaveConfig. +// It must be called only once. It is automatically called by Runtime#Create. +// Any config changes via clxc.setConfigItem must be done before calling SaveConfig. // FIXME revise the config file mechanism func (c *Container) SaveConfig() error { // createContainer creates the tmpfile diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 29856b18..e6b2ff49 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -38,10 +38,6 @@ func (rt *Runtime) Create(ctx context.Context, config *ContainerConfig) (*Contai return nil, errorf("failed to configure container: %w", err) } - if err := c.SaveConfig(); err != nil { - return nil, errorf("failed to save container descriptor: %w", err) - } - if err := rt.runStartCmd(ctx, c); err != nil { return nil, errorf("failed to run container process: %w", err) } From 2e115d27561be2f56f95a92b9f85d711914a00fe Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 22:07:24 +0100 Subject: [PATCH 206/373] Use container Log if possible. Signed-off-by: Ruben Jenster --- lxcontainer/cgroup.go | 8 ++++---- lxcontainer/create.go | 12 ++++++------ lxcontainer/devices.go | 40 +++++++++++++++++++-------------------- lxcontainer/mount.go | 18 +++++++++--------- lxcontainer/mount_test.go | 6 +++--- lxcontainer/runtime.go | 12 ++++++------ 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/lxcontainer/cgroup.go b/lxcontainer/cgroup.go index 9a619382..1abb6ccd 100644 --- a/lxcontainer/cgroup.go +++ b/lxcontainer/cgroup.go @@ -41,7 +41,7 @@ func configureCgroup(rt *Runtime, c *Container) error { } if mem := c.Linux.Resources.Memory; mem != nil { - rt.Log.Debug().Msg("TODO cgroup memory controller not implemented") + c.Log.Debug().Msg("TODO cgroup memory controller not implemented") } if cpu := c.Linux.Resources.CPU; cpu != nil { @@ -56,15 +56,15 @@ func configureCgroup(rt *Runtime, c *Container) error { } } if blockio := c.Linux.Resources.BlockIO; blockio != nil { - rt.Log.Debug().Msg("TODO cgroup blockio controller not implemented") + c.Log.Debug().Msg("TODO cgroup blockio controller not implemented") } if hugetlb := c.Linux.Resources.HugepageLimits; hugetlb != nil { // set Hugetlb limit (in bytes) - rt.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") + c.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") } if net := c.Linux.Resources.Network; net != nil { - rt.Log.Debug().Msg("TODO cgroup network controller not implemented") + c.Log.Debug().Msg("TODO cgroup network controller not implemented") } return nil } diff --git a/lxcontainer/create.go b/lxcontainer/create.go index e6b2ff49..f2233a5d 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -118,7 +118,7 @@ func configureContainer(rt *Runtime, c *Container) error { return err } - if err := configureMounts(c); err != nil { + if err := configureMounts(rt, c); err != nil { return err } @@ -161,7 +161,7 @@ func configureContainer(rt *Runtime, c *Container) error { } } } else { - c.Log.Warn().Msg("seccomp feature is disabled - all system calls are allowed") + rt.Log.Warn().Msg("seccomp feature is disabled - all system calls are allowed") } if rt.Features.Capabilities { @@ -176,7 +176,7 @@ func configureContainer(rt *Runtime, c *Container) error { if err := c.SetConfigItem("lxc.autodev", "0"); err != nil { return err } - if err := ensureDefaultDevices(rt, c); err != nil { + if err := ensureDefaultDevices(c); err != nil { return fmt.Errorf("failed to add default devices: %w", err) } @@ -294,16 +294,16 @@ func configureCapabilities(c *Container) error { return c.SetConfigItem("lxc.cap.keep", keepCaps) } -func writeMasked(dst string, spec *Container) error { +func writeMasked(dst string, c *Container) error { // #nosec - if spec.Linux.MaskedPaths == nil { + if c.Linux.MaskedPaths == nil { return nil } f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } - for _, p := range spec.Linux.MaskedPaths { + for _, p := range c.Linux.MaskedPaths { _, err = fmt.Fprintln(f, p) if err != nil { f.Close() diff --git a/lxcontainer/devices.go b/lxcontainer/devices.go index 6a5d009d..e9eef505 100644 --- a/lxcontainer/devices.go +++ b/lxcontainer/devices.go @@ -7,8 +7,8 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -func isDeviceEnabled(spec *Container, dev specs.LinuxDevice) bool { - for _, specDev := range spec.Linux.Devices { +func isDeviceEnabled(c *Container, dev specs.LinuxDevice) bool { + for _, specDev := range c.Linux.Devices { if specDev.Path == dev.Path { return true } @@ -16,18 +16,18 @@ func isDeviceEnabled(spec *Container, dev specs.LinuxDevice) bool { return false } -func addDevice(spec *Container, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { +func addDevice(c *Container, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { dev.FileMode = &mode dev.UID = &uid dev.GID = &gid - spec.Linux.Devices = append(spec.Linux.Devices, dev) + c.Linux.Devices = append(c.Linux.Devices, dev) - addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) + addDevicePerms(c, dev.Type, &dev.Major, &dev.Minor, access) } -func addDevicePerms(spec *Container, devType string, major *int64, minor *int64, access string) { +func addDevicePerms(c *Container, devType string, major *int64, minor *int64, access string) { devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} - spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) + c.Linux.Resources.Devices = append(c.Linux.Resources.Devices, devCgroup) } // ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) @@ -35,9 +35,9 @@ func addDevicePerms(spec *Container, devType string, major *int64, minor *int64, // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(c *Runtime, spec *Container) error { +func ensureDefaultDevices(c *Container) error { mode := os.FileMode(0666) - var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID + var uid, gid uint32 = c.Process.User.UID, c.Process.User.GID devices := []specs.LinuxDevice{ specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, @@ -53,38 +53,38 @@ func ensureDefaultDevices(c *Runtime, spec *Container) error { } ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} - addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx + addDevicePerms(c, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} - addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] + addDevicePerms(c, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] - if spec.Linux.Resources == nil { - spec.Linux.Resources = &specs.LinuxResources{} + if c.Linux.Resources == nil { + c.Linux.Resources = &specs.LinuxResources{} } // add missing default devices for _, dev := range devices { - if !isDeviceEnabled(spec, dev) { - addDevice(spec, dev, mode, uid, gid, "rwm") + if !isDeviceEnabled(c, dev) { + addDevice(c, dev, mode, uid, gid, "rwm") } } return nil } -func writeDevices(dst string, spec *Container) error { - if spec.Linux.Devices == nil { +func writeDevices(dst string, c *Container) error { + if c.Linux.Devices == nil { return nil } f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } - for _, d := range spec.Linux.Devices { - uid := spec.Process.User.UID + for _, d := range c.Linux.Devices { + uid := c.Process.User.UID if d.UID != nil { uid = *d.UID } - gid := spec.Process.User.GID + gid := c.Process.User.GID if d.GID != nil { gid = *d.GID } diff --git a/lxcontainer/mount.go b/lxcontainer/mount.go index ee1b7a86..e0b6afe0 100644 --- a/lxcontainer/mount.go +++ b/lxcontainer/mount.go @@ -9,7 +9,7 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -func removeMountOptions(c *Container, fs string, opts []string, unsupported ...string) []string { +func removeMountOptions(rt *Runtime, fs string, opts []string, unsupported ...string) []string { supported := make([]string, 0, len(opts)) for _, opt := range opts { addOption := true @@ -22,27 +22,27 @@ func removeMountOptions(c *Container, fs string, opts []string, unsupported ...s if addOption { supported = append(supported, opt) } else { - c.Log.Info().Str("fs", fs).Str("option", opt).Msg("removed mount option") + rt.Log.Info().Str("fs", fs).Str("option", opt).Msg("removed mount option") } } return supported } -func filterMountOptions(c *Container, fs string, opts []string) []string { +func filterMountOptions(rt *Runtime, fs string, opts []string) []string { switch fs { case "sysfs": - return removeMountOptions(c, fs, opts, "rslave") + return removeMountOptions(rt, fs, opts, "rslave") case "tmpfs": // TODO make this configurable per filesystem - return removeMountOptions(c, fs, opts, "rprivate", "tmpcopyup") + return removeMountOptions(rt, fs, opts, "rprivate", "tmpcopyup") case "cgroup2": // TODO make this configurable per filesystem - return removeMountOptions(c, fs, opts, "private", "rslave") + return removeMountOptions(rt, fs, opts, "private", "rslave") } return opts } -func configureMounts(c *Container) error { +func configureMounts(rt *Runtime, c *Container) error { // excplicitly disable auto-mounting if err := c.SetConfigItem("lxc.mount.auto", ""); err != nil { return err @@ -65,7 +65,7 @@ func configureMounts(c *Container) error { mountDest, err := resolveMountDestination(c.Root.Path, ms.Destination) // Intermediate path resolution failed. This is not an error, since // the remaining directories / files are automatically created (create=dir|file) - c.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") + rt.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. if !filepath.HasPrefix(mountDest, c.Root.Path) { @@ -79,7 +79,7 @@ func configureMounts(c *Container) error { return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) } - ms.Options = filterMountOptions(c, ms.Type, ms.Options) + ms.Options = filterMountOptions(rt, ms.Type, ms.Options) mnt := fmt.Sprintf("%s %s %s %s", ms.Source, ms.Destination, ms.Type, strings.Join(ms.Options, ",")) diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index 989c585e..72e78938 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -74,13 +74,13 @@ func TestResolveMountDestination_relative(t *testing.T) { } func TestFilterMountOptions(t *testing.T) { - c := &Container{Log: testLogger()} + rt := Runtime{Log: log.NewTestLogger(true)} opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") - out := filterMountOptions(c, "tmpfs", opts) + out := filterMountOptions(&rt, "tmpfs", opts) require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) - out = filterMountOptions(c, "nosuchfs", opts) + out = filterMountOptions(&rt, "nosuchfs", opts) require.Equal(t, opts, out) } diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index f272ba4a..a429f834 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -68,7 +68,7 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Start) defer cancel() - c.Log.Info().Msg("notify init to start container process") + rt.Log.Info().Msg("notify init to start container process") state, err := c.State() if err != nil { @@ -102,7 +102,7 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { return err } - c.Log.Debug().Msg("starting lxc monitor process") + rt.Log.Debug().Msg("starting lxc monitor process") if c.ConsoleSocket != "" { err = runStartCmdConsole(ctx, cmd, c.ConsoleSocket) } else { @@ -120,19 +120,19 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // NOTE this goroutine may leak until crio-lxc is terminated ps, err := cmd.Process.Wait() if err != nil { - c.Log.Error().Err(err).Msg("failed to wait for start process") + rt.Log.Error().Err(err).Msg("failed to wait for start process") } else { - c.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") + rt.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") } cancel() }() - c.Log.Debug().Msg("waiting for init") + rt.Log.Debug().Msg("waiting for init") if err := c.waitCreated(ctx); err != nil { return err } - c.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") + rt.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") return CreatePidFile(c.PidFile, cmd.Process.Pid) } From 0837c9d749ef515724fc182c32780ab7a4505878 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 22:12:39 +0100 Subject: [PATCH 207/373] log: Let caller handle Logger configuration. Runtime and Container have separate Log instances. The Log instance of the Container can be set through the ContainerConfig. The Log instance must be set by the caller (cli). Move existing Log configuration into separate log package for convenience access to zerlog. Signed-off-by: Ruben Jenster --- lxcontainer/container.go | 51 +++++-------------------- lxcontainer/create.go | 45 ++++++++++++++++++++++ lxcontainer/log.go | 78 --------------------------------------- lxcontainer/log/log.go | 57 ++++++++++++++++++++++++++++ lxcontainer/mount_test.go | 1 + lxcontainer/runtime.go | 8 ++-- 6 files changed, 115 insertions(+), 125 deletions(-) delete mode 100644 lxcontainer/log.go create mode 100644 lxcontainer/log/log.go diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 3579b4c4..33c85af8 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -18,6 +18,7 @@ import ( type ContainerConfig struct { *specs.Spec + SpecPath string RuntimeDir string @@ -27,11 +28,18 @@ type ContainerConfig struct { BundlePath string ConsoleSocket string `json:",omitempty"` + // PidFile is the absolute path to the PID file of the container monitor process (crio-lxc-start) PidFile string MonitorCgroupDir string CgroupDir string + + // lxc log file and level + LogLevel string + LogFile string + + Log zerolog.Logger `json:"-"` } func (cfg ContainerConfig) ConfigFilePath() string { @@ -76,7 +84,6 @@ func (c *ContainerConfig) LoadSpecJson(p string) error { type Container struct { linuxcontainer *lxc.Container `json:"-"` *ContainerConfig - Log zerolog.Logger `json:"-"` } func NewContainer(config *ContainerConfig) (*Container, error) { @@ -131,51 +138,11 @@ func LoadContainer(cfg *ContainerConfig) (*Container, error) { err = c.linuxcontainer.LoadConfigFile(c.ConfigFilePath()) if err != nil { - return nil, fmt.Errorf("failed to load config file: %w", err) - } - return c, nil -} - -func (c *Container) SetLog(logFile string, level string) error { - // Never let lxc write to stdout, stdout belongs to the container init process. - // Explicitly disable it - allthough it is currently the default. - c.linuxcontainer.SetVerbosity(lxc.Quiet) - // The log level for a running container is set, and may change, per runtime call. - err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(level)) - if err != nil { - return fmt.Errorf("failed to set container loglevel: %w", err) - } - if err := c.linuxcontainer.SetLogFile(logFile); err != nil { - return fmt.Errorf("failed to set container log file: %w", err) + return fmt.Errorf("failed to load config file: %w", err) } return nil } -func parseContainerLogLevel(level string) lxc.LogLevel { - switch strings.ToLower(level) { - case "trace": - return lxc.TRACE - case "debug": - return lxc.DEBUG - case "info": - return lxc.INFO - case "notice": - return lxc.NOTICE - case "warn": - return lxc.WARN - case "error": - return lxc.ERROR - case "crit": - return lxc.CRIT - case "alert": - return lxc.ALERT - case "fatal": - return lxc.FATAL - default: - return lxc.WARN - } -} - func (c *Container) waitCreated(ctx context.Context) error { for { select { diff --git a/lxcontainer/create.go b/lxcontainer/create.go index f2233a5d..04494f26 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -222,6 +222,11 @@ func configureContainer(rt *Runtime, c *Container) error { return err } } + + if err := setLog(c); err != nil { + return errorf("failed to configure container log: %w", err) + } + return nil } @@ -354,3 +359,43 @@ func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string } return ptmx.Close() } + +func setLog(c *Container) error { + // Never let lxc write to stdout, stdout belongs to the container init process. + // Explicitly disable it - allthough it is currently the default. + c.linuxcontainer.SetVerbosity(lxc.Quiet) + // The log level for a running container is set, and may change, per runtime call. + err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(c.LogLevel)) + if err != nil { + return fmt.Errorf("failed to set container loglevel: %w", err) + } + if err := c.linuxcontainer.SetLogFile(c.LogFile); err != nil { + return fmt.Errorf("failed to set container log file: %w", err) + } + return nil +} + +func parseContainerLogLevel(level string) lxc.LogLevel { + switch strings.ToLower(level) { + case "trace": + return lxc.TRACE + case "debug": + return lxc.DEBUG + case "info": + return lxc.INFO + case "notice": + return lxc.NOTICE + case "warn": + return lxc.WARN + case "error": + return lxc.ERROR + case "crit": + return lxc.CRIT + case "alert": + return lxc.ALERT + case "fatal": + return lxc.FATAL + default: + return lxc.WARN + } +} diff --git a/lxcontainer/log.go b/lxcontainer/log.go deleted file mode 100644 index 842fa7a4..00000000 --- a/lxcontainer/log.go +++ /dev/null @@ -1,78 +0,0 @@ -package lxcontainer - -import ( - "fmt" - "github.com/rs/zerolog" - "os" - "path/filepath" - "strconv" - "strings" - "time" -) - -type Log struct { - zerolog.Logger `json:"-"` - File *os.File `json:"-"` - FilePath string - Level string - Timestamp string - LevelContainer string -} - -func (log Log) Open(cmdName string) error { - logDir := filepath.Dir(log.FilePath) - err := os.MkdirAll(logDir, 0750) - if err != nil { - return fmt.Errorf("failed to create log file directory %s: %w", logDir, err) - } - - log.File, err = os.OpenFile(log.FilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) - if err != nil { - return err - } - - zerolog.LevelFieldName = "l" - zerolog.MessageFieldName = "m" - - // match liblxc timestamp format - zerolog.TimestampFieldName = "t" - zerolog.TimeFieldFormat = log.Timestamp - zerolog.TimestampFunc = func() time.Time { - return time.Now().UTC() - } - - // TODO only log caller information in debug and trace level - zerolog.CallerFieldName = "c" - zerolog.CallerMarshalFunc = func(file string, line int) string { - return filepath.Base(file) + ":" + strconv.Itoa(line) - } - - // NOTE Unfortunately it's not possible change the possition of the timestamp. - // The ttimestamp is appended to the to the log output because it is dynamically rendered - // see https://github.com/rs/zerolog/issues/109 - // FIXME ContainerID is not part of the runtime anymore - // rt.Log = zerolog.New(rt.LogFile).With().Timestamp().Caller(). - // Str("cmd", cmdName).Str("cid", c.ContainerID).Logger() - log.Logger = zerolog.New(log.File).With().Timestamp().Caller(). - Str("cmd", cmdName).Logger() - - level, err := zerolog.ParseLevel(strings.ToLower(log.Level)) - if err != nil { - level = zerolog.InfoLevel - log.Warn().Err(err).Str("val", log.Level).Stringer("default", level). - Msg("failed to parse log-level - fallback to default") - } - zerolog.SetGlobalLevel(level) - return nil -} - -func (log Log) Close() error { - return log.File.Close() -} - -// FIXME move to test utils ? -func testLogger() zerolog.Logger { - z := zerolog.New(os.Stderr) - zerolog.SetGlobalLevel(zerolog.DebugLevel) - return z -} diff --git a/lxcontainer/log/log.go b/lxcontainer/log/log.go new file mode 100644 index 00000000..689061e2 --- /dev/null +++ b/lxcontainer/log/log.go @@ -0,0 +1,57 @@ +package log + +import ( + "fmt" + "io" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/rs/zerolog" +) + +// TODO log to systemd journal ? + +func init() { + zerolog.LevelFieldName = "l" + zerolog.MessageFieldName = "m" + + // match liblxc timestamp format + zerolog.TimestampFieldName = "t" + //zerolog.TimeFieldFormat = "20060102150405.000" + zerolog.TimestampFunc = func() time.Time { + return time.Now().UTC() + } + + // TODO only log caller information in debug and trace level + zerolog.CallerFieldName = "c" + zerolog.CallerMarshalFunc = func(file string, line int) string { + return filepath.Base(file) + ":" + strconv.Itoa(line) + } +} + +func OpenFile(name string, mode os.FileMode) (*os.File, error) { + logDir := filepath.Dir(name) + err := os.MkdirAll(logDir, 0750) + if err != nil { + return nil, fmt.Errorf("failed to create log file directory %s: %w", logDir, err) + } + return os.OpenFile(name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, mode) +} + +func ParseLevel(level string) (zerolog.Level, error) { + return zerolog.ParseLevel(strings.ToLower(level)) +} + +func NewLogger(out io.Writer, level zerolog.Level) zerolog.Context { + // NOTE Unfortunately it's not possible change the possition of the timestamp. + // The ttimestamp is appended to the to the log output because it is dynamically rendered + // see https://github.com/rs/zerolog/issues/109 + return zerolog.New(out).Level(level).With().Timestamp().Caller() +} + +func NewTestLogger(color bool) zerolog.Logger { + return zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: !color}).Level(zerolog.DebugLevel).With().Timestamp().Caller().Logger() +} diff --git a/lxcontainer/mount_test.go b/lxcontainer/mount_test.go index 72e78938..468e49f9 100644 --- a/lxcontainer/mount_test.go +++ b/lxcontainer/mount_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer/log" "github.com/stretchr/testify/require" ) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index a429f834..cb006524 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -5,9 +5,11 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "time" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/rs/zerolog" "golang.org/x/sys/unix" ) @@ -15,7 +17,7 @@ var ErrNotExist = fmt.Errorf("container does not exist") var ErrExist = fmt.Errorf("container already exists") type Runtime struct { - Log + Log zerolog.Logger Root string // Use systemd encoded cgroup path (from crio-o/conmon) @@ -173,10 +175,6 @@ func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { return nil } -func (rt *Runtime) Release() error { - return rt.Log.Close() -} - func ReadSpecProcessJSON(src string) (*specs.Process, error) { proc := new(specs.Process) err := decodeFileJSON(proc, src) From 6be1c7e748d78393f6a03a9b44170569644ae93a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 22:19:13 +0100 Subject: [PATCH 208/373] Fix container loading. Disable SystemdCheck on container creation. Signed-off-by: Ruben Jenster --- lxcontainer/container.go | 30 +++++++++++++----------------- lxcontainer/create.go | 15 ++++++--------- lxcontainer/runtime.go | 11 ++++++++--- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 33c85af8..6c9d84c1 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -86,15 +86,12 @@ type Container struct { *ContainerConfig } -func NewContainer(config *ContainerConfig) (*Container, error) { - c := &Container{ContainerConfig: config} - +func (c *Container) Create() error { if c.runtimeDirExists() { - return nil, ErrExist + return ErrExist } - if err := os.MkdirAll(c.RuntimeDir, 0700); err != nil { - return nil, fmt.Errorf("failed to create container dir: %w", err) + return fmt.Errorf("failed to create container dir: %w", err) } // An empty tmpfile is created to ensure that createContainer can only succeed once. @@ -102,38 +99,37 @@ func NewContainer(config *ContainerConfig) (*Container, error) { // #nosec f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) if err != nil { - return nil, err + return err } if err := f.Close(); err != nil { - return nil, fmt.Errorf("failed to close empty config tmpfile: %w", err) + return fmt.Errorf("failed to close empty config tmpfile: %w", err) } c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) if err != nil { - return nil, err + return err } - return c, nil -} -func LoadContainer(cfg *ContainerConfig) (*Container, error) { - c := &Container{ContainerConfig: cfg} + return nil +} +func (c *Container) Load() error { if !c.runtimeDirExists() { - return nil, ErrNotExist + return ErrNotExist } err := decodeFileJSON(&c.ContainerConfig, c.RuntimePath("container.json")) if err != nil { - return nil, fmt.Errorf("failed to load container config: %w", err) + return fmt.Errorf("failed to load container config: %w", err) } _, err = os.Stat(c.ConfigFilePath()) if err != nil { - return nil, fmt.Errorf("failed to load lxc config file: %w", err) + return fmt.Errorf("failed to load lxc config file: %w", err) } c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) if err != nil { - return nil, fmt.Errorf("failed to create lxc container: %w", err) + return fmt.Errorf("failed to create lxc container: %w", err) } err = c.linuxcontainer.LoadConfigFile(c.ConfigFilePath()) diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 04494f26..56d1f8d8 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -16,21 +16,18 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -func (rt *Runtime) Create(ctx context.Context, config *ContainerConfig) (*Container, error) { +func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Create) defer cancel() - if err := rt.checkSystem(); err != nil { + if err := rt.checkConfig(cfg); err != nil { return nil, err } - if err := rt.checkConfig(config); err != nil { - return nil, err - } + c := &Container{ContainerConfig: cfg} + c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) - config.RuntimeDir = filepath.Join(rt.Root, config.ContainerID) - c, err := NewContainer(config) - if err != nil { + if err := c.Create(); err != nil { return nil, errorf("failed to create container: %w", err) } @@ -48,7 +45,7 @@ func (rt *Runtime) Create(ctx context.Context, config *ContainerConfig) (*Contai return c, nil } -func (rt *Runtime) checkSystem() error { +func (rt *Runtime) CheckSystem() error { err := canExecute(rt.Executables.Start, rt.Executables.Hook, rt.Executables.Init) if err != nil { return errorf("access check failed: %w", err) diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index cb006524..a69ad90e 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -61,9 +61,14 @@ type Runtime struct { } } -// Release releases/closes allocated resources (lxc.Container, LogFile) -func (rt *Runtime) Close() error { - return rt.Log.File.Close() +func (rt *Runtime) LoadContainer(cfg *ContainerConfig) (*Container, error) { + c := &Container{ContainerConfig: cfg} + c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) + + if err := c.Load(); err != nil { + return nil, err + } + return c, nil } func (rt *Runtime) Start(ctx context.Context, c *Container) error { From ebd9f028b3162d33a8ee9de508a2f6e9dd93cbb8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 22:23:06 +0100 Subject: [PATCH 209/373] cli: Updates for lxcontainer changes. Signed-off-by: Ruben Jenster --- cmd/cli.go | 145 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 97 insertions(+), 48 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index f02e1caf..120b5423 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -11,6 +11,7 @@ import ( "time" "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer" + "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer/log" "github.com/urfave/cli/v2" ) @@ -18,14 +19,50 @@ import ( // Existing environment variables are preserved. var envFile = "/etc/default/crio-lxc" -// The singelton that wraps the lxc.Container -var clxc struct { +const defaultLogFile = "/var/log/crio-lxc/crio-lxc.log" + +type app struct { lxcontainer.Runtime - ContainerConfig lxcontainer.ContainerConfig + containerConfig lxcontainer.ContainerConfig + + logConfig struct { + File *os.File + FilePath string + Level string + Timestamp string + } - Command string - CreateHook string - CreateHookTimeout time.Duration + command string + createHook string + createHookTimeout time.Duration +} + +var clxc = app{} + +func (app *app) configureLogger() error { + // TODO use console logger if filepath is /dev/stdout or /dev/stderr ? + l, err := log.OpenFile(app.logConfig.FilePath, 0600) + if err != nil { + return fmt.Errorf("failed to open log file: %w", err) + } + app.logConfig.File = l + + level, err := log.ParseLevel(app.logConfig.Level) + if err != nil { + return fmt.Errorf("failed to parse log level: %w", err) + } + logCtx := log.NewLogger(app.logConfig.File, level) + app.Runtime.Log = logCtx.Str("cmd", app.command).Str("cid", app.containerConfig.ContainerID).Logger() + app.containerConfig.Log = app.Runtime.Log + + return nil +} + +func (app *app) release() error { + if app.logConfig.File != nil { + return app.logConfig.File.Close() + } + return nil } var version string @@ -48,7 +85,6 @@ func main() { &deleteCmd, &execCmd, // TODO extend urfave/cli to render a default environment file. - } app.Flags = []cli.Flag{ @@ -57,28 +93,34 @@ func main() { Usage: "set the runtime log level (trace|debug|info|warn|error)", EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, Value: "info", - Destination: &clxc.Log.Level, - }, - &cli.StringFlag{ - Name: "container-log-level", - Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", - EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, - Value: "warn", - Destination: &clxc.Log.LevelContainer, + Destination: &clxc.logConfig.Level, }, &cli.StringFlag{ Name: "log-file", Usage: "path to the log file for runtime and container output", EnvVars: []string{"CRIO_LXC_LOG_FILE"}, - Value: "/var/log/crio-lxc/crio-lxc.log", - Destination: &clxc.Log.FilePath, + Value: defaultLogFile, + Destination: &clxc.logConfig.FilePath, }, &cli.StringFlag{ Name: "log-timestamp", Usage: "timestamp format for the runtime log (see golang time package), default matches liblxc timestamp", EnvVars: []string{"CRIO_LXC_LOG_TIMESTAMP"}, // e.g '0102 15:04:05.000' - Value: "20060102150405.000", - Destination: &clxc.Log.Timestamp, + Destination: &clxc.logConfig.Timestamp, + }, + &cli.StringFlag{ + Name: "container-log-level", + Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", + EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, + Value: "warn", + Destination: &clxc.containerConfig.LogLevel, + }, + &cli.StringFlag{ + Name: "container-log-file", + Usage: "path to the log file for runtime and container output", + EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_FILE"}, + Value: defaultLogFile, + Destination: &clxc.containerConfig.LogFile, }, &cli.StringFlag{ Name: "root", @@ -185,7 +227,7 @@ func main() { app.OnUsageError = errUsage app.Before = func(ctx *cli.Context) error { - clxc.Command = ctx.Args().Get(0) + clxc.command = ctx.Args().Get(0) return nil } @@ -194,8 +236,12 @@ func main() { if len(containerID) == 0 { return fmt.Errorf("missing container ID") } - clxc.ContainerConfig.ContainerID = containerID - return clxc.Log.Open(ctx.Command.Name) + clxc.containerConfig.ContainerID = containerID + + if err := clxc.configureLogger(); err != nil { + return fmt.Errorf("failed to configure logger: %w", err) + } + return nil } for _, cmd := range app.Commands { @@ -209,7 +255,7 @@ func main() { if err != nil { clxc.Log.Error().Err(err).Dur("duration", cmdDuration).Msg("cmd failed") - clxc.Release() + clxc.release() // write diagnostics message to stderr for crio/kubelet println(err.Error()) @@ -222,7 +268,7 @@ func main() { } clxc.Log.Debug().Dur("duration", cmdDuration).Msg("cmd completed") - if clxc.Release(); err != nil { + if clxc.release(); err != nil { println(err.Error()) os.Exit(1) } @@ -238,17 +284,17 @@ var createCmd = cli.Command{ Name: "bundle", Usage: "set bundle directory", Value: ".", - Destination: &clxc.ContainerConfig.BundlePath, + Destination: &clxc.containerConfig.BundlePath, }, &cli.StringFlag{ Name: "console-socket", Usage: "send container pty master fd to this socket path", - Destination: &clxc.ContainerConfig.ConsoleSocket, + Destination: &clxc.containerConfig.ConsoleSocket, }, &cli.StringFlag{ Name: "pid-file", Usage: "path to write container PID", - Destination: &clxc.ContainerConfig.PidFile, + Destination: &clxc.containerConfig.PidFile, }, &cli.DurationFlag{ Name: "timeout", @@ -262,25 +308,28 @@ var createCmd = cli.Command{ Name: "create-hook", Usage: "absolute path to executable to run after create", EnvVars: []string{"CRIO_LXC_CREATE_HOOK"}, - Destination: &clxc.CreateHook, + Destination: &clxc.createHook, }, &cli.DurationFlag{ Name: "hook-timeout", Usage: "maximum duration for hook to complete", EnvVars: []string{"CRIO_LXC_CREATE_HOOK_TIMEOUT"}, Value: time.Second * 5, - Destination: &clxc.CreateHookTimeout, + Destination: &clxc.createHookTimeout, }, }, } func doCreate(unused *cli.Context) error { - specPath := filepath.Join(clxc.ContainerConfig.BundlePath, "config.json") - err := clxc.ContainerConfig.LoadSpecJson(specPath) + if err := clxc.CheckSystem(); err != nil { + return err + } + specPath := filepath.Join(clxc.containerConfig.BundlePath, "config.json") + err := clxc.containerConfig.LoadSpecJson(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } - c, err := clxc.Create(context.Background(), &clxc.ContainerConfig) + c, err := clxc.Create(context.Background(), &clxc.containerConfig) if err == nil { defer c.Release() } @@ -290,25 +339,25 @@ func doCreate(unused *cli.Context) error { func runCreateHook(err error) { env := []string{ - "CONTAINER_ID=" + clxc.ContainerConfig.ContainerID, - "LXC_CONFIG=" + clxc.ContainerConfig.ConfigFilePath(), - "RUNTIME_CMD=" + clxc.Command, - "RUNTIME_PATH=" + clxc.ContainerConfig.RuntimePath(), - "BUNDLE_PATH=" + clxc.ContainerConfig.BundlePath, - "SPEC_PATH=" + clxc.ContainerConfig.SpecPath, - "LOG_FILE=" + clxc.Log.FilePath, + "CONTAINER_ID=" + clxc.containerConfig.ContainerID, + "LXC_CONFIG=" + clxc.containerConfig.ConfigFilePath(), + "RUNTIME_CMD=" + clxc.command, + "RUNTIME_PATH=" + clxc.containerConfig.RuntimePath(), + "BUNDLE_PATH=" + clxc.containerConfig.BundlePath, + "SPEC_PATH=" + clxc.containerConfig.SpecPath, + "LOG_FILE=" + clxc.logConfig.FilePath, } if err != nil { env = append(env, "RUNTIME_ERROR="+err.Error()) } - ctx, cancel := context.WithTimeout(context.Background(), clxc.CreateHookTimeout) + ctx, cancel := context.WithTimeout(context.Background(), clxc.createHookTimeout) defer cancel() - cmd := exec.CommandContext(ctx, clxc.CreateHook) + cmd := exec.CommandContext(ctx, clxc.createHook) cmd.Env = env - clxc.Log.Debug().Str("file", clxc.CreateHook).Msg("execute create hook") + clxc.Log.Debug().Str("file", clxc.createHook).Msg("execute create hook") if err := cmd.Run(); err != nil { - clxc.Log.Error().Err(err).Str("file", clxc.CreateHook).Msg("failed to execute create hook") + clxc.Log.Error().Err(err).Str("file", clxc.createHook).Msg("failed to execute create hook") } } @@ -332,7 +381,7 @@ starts } func doStart(unused *cli.Context) error { - c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + c, err := clxc.LoadContainer(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -352,7 +401,7 @@ var stateCmd = cli.Command{ } func doState(unused *cli.Context) error { - c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + c, err := clxc.LoadContainer(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -396,7 +445,7 @@ func doKill(ctx *cli.Context) error { return fmt.Errorf("invalid signal param %q", sig) } - c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + c, err := clxc.LoadContainer(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -427,7 +476,7 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { - c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + c, err := clxc.LoadContainer(&clxc.containerConfig) if err == lxcontainer.ErrNotExist { clxc.Log.Info().Msg("container does not exist") return nil @@ -504,7 +553,7 @@ func doExec(ctx *cli.Context) error { args = procSpec.Args } - c, err := lxcontainer.LoadContainer(&clxc.ContainerConfig) + c, err := clxc.LoadContainer(&clxc.containerConfig) if err != nil { return err } From ef14ddccf5cbb5b8d8d57ecb85b9eeae5b683093 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 22:59:33 +0100 Subject: [PATCH 210/373] Cleanup public API visbility. Signed-off-by: Ruben Jenster --- cmd/cli.go | 10 +++++----- lxcontainer/container.go | 12 ++++++------ lxcontainer/create.go | 2 +- lxcontainer/runtime.go | 14 +++++++------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cmd/cli.go b/cmd/cli.go index 120b5423..354fd60c 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -381,7 +381,7 @@ starts } func doStart(unused *cli.Context) error { - c, err := clxc.LoadContainer(&clxc.containerConfig) + c, err := clxc.Load(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -401,7 +401,7 @@ var stateCmd = cli.Command{ } func doState(unused *cli.Context) error { - c, err := clxc.LoadContainer(&clxc.containerConfig) + c, err := clxc.Load(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -445,7 +445,7 @@ func doKill(ctx *cli.Context) error { return fmt.Errorf("invalid signal param %q", sig) } - c, err := clxc.LoadContainer(&clxc.containerConfig) + c, err := clxc.Load(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -476,7 +476,7 @@ var deleteCmd = cli.Command{ } func doDelete(ctx *cli.Context) error { - c, err := clxc.LoadContainer(&clxc.containerConfig) + c, err := clxc.Load(&clxc.containerConfig) if err == lxcontainer.ErrNotExist { clxc.Log.Info().Msg("container does not exist") return nil @@ -553,7 +553,7 @@ func doExec(ctx *cli.Context) error { args = procSpec.Args } - c, err := clxc.LoadContainer(&clxc.containerConfig) + c, err := clxc.Load(&clxc.containerConfig) if err != nil { return err } diff --git a/lxcontainer/container.go b/lxcontainer/container.go index 6c9d84c1..bdf91c06 100644 --- a/lxcontainer/container.go +++ b/lxcontainer/container.go @@ -86,7 +86,7 @@ type Container struct { *ContainerConfig } -func (c *Container) Create() error { +func (c *Container) create() error { if c.runtimeDirExists() { return ErrExist } @@ -113,7 +113,7 @@ func (c *Container) Create() error { return nil } -func (c *Container) Load() error { +func (c *Container) load() error { if !c.runtimeDirExists() { return ErrNotExist } @@ -254,7 +254,7 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { return specs.StateRunning, nil } -func (c *Container) Kill(ctx context.Context, signum unix.Signal) error { +func (c *Container) kill(ctx context.Context, signum unix.Signal) error { c.Log.Info().Int("signum", int(signum)).Msg("killing container process") if signum == unix.SIGKILL || signum == unix.SIGTERM { if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { @@ -301,7 +301,7 @@ func (c *Container) Kill(ctx context.Context, signum unix.Signal) error { // It must be called only once. It is automatically called by Runtime#Create. // Any config changes via clxc.setConfigItem must be done before calling SaveConfig. // FIXME revise the config file mechanism -func (c *Container) SaveConfig() error { +func (c *Container) saveConfig() error { // createContainer creates the tmpfile tmpFile := c.RuntimePath(".config") if _, err := os.Stat(tmpFile); err != nil { @@ -370,7 +370,7 @@ func (c *Container) Release() error { // but not created by this container, MUST NOT be deleted." // TODO - because we set rootfs.managed=0, Destroy() doesn't // delete the /var/lib/lxc/$containerID/config file: -func (c *Container) Destroy() error { +func (c *Container) destroy() error { if err := c.linuxcontainer.Destroy(); err != nil { return fmt.Errorf("failed to destroy container: %w", err) } @@ -383,7 +383,7 @@ func (c *Container) Destroy() error { return os.RemoveAll(c.RuntimePath()) } -func (c *Container) Start(ctx context.Context) error { +func (c *Container) start(ctx context.Context) error { done := make(chan error) go func() { // FIXME fifo must be unblocked otherwise diff --git a/lxcontainer/create.go b/lxcontainer/create.go index 56d1f8d8..34cf399c 100644 --- a/lxcontainer/create.go +++ b/lxcontainer/create.go @@ -27,7 +27,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container c := &Container{ContainerConfig: cfg} c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) - if err := c.Create(); err != nil { + if err := c.create(); err != nil { return nil, errorf("failed to create container: %w", err) } diff --git a/lxcontainer/runtime.go b/lxcontainer/runtime.go index a69ad90e..1d8a2465 100644 --- a/lxcontainer/runtime.go +++ b/lxcontainer/runtime.go @@ -61,11 +61,11 @@ type Runtime struct { } } -func (rt *Runtime) LoadContainer(cfg *ContainerConfig) (*Container, error) { +func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { c := &Container{ContainerConfig: cfg} c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) - if err := c.Load(); err != nil { + if err := c.load(); err != nil { return nil, err } return c, nil @@ -85,7 +85,7 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state.Status) } - return c.Start(ctx) + return c.start(ctx) } func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { @@ -105,7 +105,7 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { cmd.Stderr = os.Stderr } - if err := c.SaveConfig(); err != nil { + if err := c.saveConfig(); err != nil { return err } @@ -154,7 +154,7 @@ func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) e if state == specs.StateStopped { return errorf("container already stopped") } - return c.Kill(ctx, signum) + return c.kill(ctx, signum) } func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { @@ -170,11 +170,11 @@ func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { if !force { return errorf("container is not not stopped (current state %s)", state) } - if err := c.Kill(ctx, unix.SIGKILL); err != nil { + if err := c.kill(ctx, unix.SIGKILL); err != nil { return errorf("failed to kill container: %w", err) } } - if err := c.Destroy(); err != nil { + if err := c.destroy(); err != nil { return errorf("failed to destroy container: %w", err) } return nil From d3981dadd05e452638864746571b125aca175a37 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 23 Mar 2021 23:52:48 +0100 Subject: [PATCH 211/373] Renamed project to lxcri. Signed-off-by: Ruben Jenster --- lxcontainer/cgroup.go => cgroup.go | 2 +- lxcontainer/cgroup_test.go => cgroup_test.go | 2 +- cmd/cli.go | 14 +++++++------- lxcontainer/container.go => container.go | 2 +- lxcontainer/create.go => create.go | 2 +- lxcontainer/devices.go => devices.go | 2 +- go.mod | 2 +- lxcontainer/init.go => init.go | 2 +- {lxcontainer/log => log}/log.go | 0 lxcontainer/mount.go => mount.go | 2 +- lxcontainer/mount_test.go => mount_test.go | 4 ++-- lxcontainer/namespaces.go => namespaces.go | 2 +- lxcontainer/runtime.go => runtime.go | 2 +- lxcontainer/seccomp.go => seccomp.go | 2 +- lxcontainer/utils.go => utils.go | 2 +- 15 files changed, 21 insertions(+), 21 deletions(-) rename lxcontainer/cgroup.go => cgroup.go (99%) rename lxcontainer/cgroup_test.go => cgroup_test.go (93%) rename lxcontainer/container.go => container.go (99%) rename lxcontainer/create.go => create.go (99%) rename lxcontainer/devices.go => devices.go (99%) rename lxcontainer/init.go => init.go (99%) rename {lxcontainer/log => log}/log.go (100%) rename lxcontainer/mount.go => mount.go (99%) rename lxcontainer/mount_test.go => mount_test.go (97%) rename lxcontainer/namespaces.go => namespaces.go (99%) rename lxcontainer/runtime.go => runtime.go (99%) rename lxcontainer/seccomp.go => seccomp.go (99%) rename lxcontainer/utils.go => utils.go (99%) diff --git a/lxcontainer/cgroup.go b/cgroup.go similarity index 99% rename from lxcontainer/cgroup.go rename to cgroup.go index 1abb6ccd..54d69663 100644 --- a/lxcontainer/cgroup.go +++ b/cgroup.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "bytes" diff --git a/lxcontainer/cgroup_test.go b/cgroup_test.go similarity index 93% rename from lxcontainer/cgroup_test.go rename to cgroup_test.go index 912598a8..9b1b7d45 100644 --- a/lxcontainer/cgroup_test.go +++ b/cgroup_test.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "testing" diff --git a/cmd/cli.go b/cmd/cli.go index 354fd60c..51babee3 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -10,8 +10,8 @@ import ( "path/filepath" "time" - "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer" - "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer/log" + "github.com/drachenfels-de/lxcri" + "github.com/drachenfels-de/lxcri/log" "github.com/urfave/cli/v2" ) @@ -22,8 +22,8 @@ var envFile = "/etc/default/crio-lxc" const defaultLogFile = "/var/log/crio-lxc/crio-lxc.log" type app struct { - lxcontainer.Runtime - containerConfig lxcontainer.ContainerConfig + lxcri.Runtime + containerConfig lxcri.ContainerConfig logConfig struct { File *os.File @@ -477,7 +477,7 @@ var deleteCmd = cli.Command{ func doDelete(ctx *cli.Context) error { c, err := clxc.Load(&clxc.containerConfig) - if err == lxcontainer.ErrNotExist { + if err == lxcri.ErrNotExist { clxc.Log.Info().Msg("container does not exist") return nil } @@ -545,7 +545,7 @@ func doExec(ctx *cli.Context) error { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := lxcontainer.ReadSpecProcessJSON(ctx.String("process")) + procSpec, err := lxcri.ReadSpecProcessJSON(ctx.String("process")) if err != nil { return err } @@ -564,7 +564,7 @@ func doExec(ctx *cli.Context) error { return err } if pidFile != "" { - return lxcontainer.CreatePidFile(pidFile, pid) + return lxcri.CreatePidFile(pidFile, pid) } } else { status, err := c.Exec(args, procSpec) diff --git a/lxcontainer/container.go b/container.go similarity index 99% rename from lxcontainer/container.go rename to container.go index bdf91c06..148b706b 100644 --- a/lxcontainer/container.go +++ b/container.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "context" diff --git a/lxcontainer/create.go b/create.go similarity index 99% rename from lxcontainer/create.go rename to create.go index 34cf399c..d5044536 100644 --- a/lxcontainer/create.go +++ b/create.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "context" diff --git a/lxcontainer/devices.go b/devices.go similarity index 99% rename from lxcontainer/devices.go rename to devices.go index e9eef505..918812d3 100644 --- a/lxcontainer/devices.go +++ b/devices.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "fmt" diff --git a/go.mod b/go.mod index e6846658..fb4d1434 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/Drachenfels-GmbH/crio-lxc +module github.com/drachenfels-de/lxcri require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect diff --git a/lxcontainer/init.go b/init.go similarity index 99% rename from lxcontainer/init.go rename to init.go index ecb860df..dc2a9b19 100644 --- a/lxcontainer/init.go +++ b/init.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "fmt" diff --git a/lxcontainer/log/log.go b/log/log.go similarity index 100% rename from lxcontainer/log/log.go rename to log/log.go diff --git a/lxcontainer/mount.go b/mount.go similarity index 99% rename from lxcontainer/mount.go rename to mount.go index e0b6afe0..1f49afd2 100644 --- a/lxcontainer/mount.go +++ b/mount.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "fmt" diff --git a/lxcontainer/mount_test.go b/mount_test.go similarity index 97% rename from lxcontainer/mount_test.go rename to mount_test.go index 468e49f9..3800ff81 100644 --- a/lxcontainer/mount_test.go +++ b/mount_test.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "io/ioutil" @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/Drachenfels-GmbH/crio-lxc/lxcontainer/log" + "github.com/drachenfels-de/lxcri/log" "github.com/stretchr/testify/require" ) diff --git a/lxcontainer/namespaces.go b/namespaces.go similarity index 99% rename from lxcontainer/namespaces.go rename to namespaces.go index 4ac1cd92..0898c3ee 100644 --- a/lxcontainer/namespaces.go +++ b/namespaces.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "fmt" diff --git a/lxcontainer/runtime.go b/runtime.go similarity index 99% rename from lxcontainer/runtime.go rename to runtime.go index 1d8a2465..a56014d1 100644 --- a/lxcontainer/runtime.go +++ b/runtime.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "context" diff --git a/lxcontainer/seccomp.go b/seccomp.go similarity index 99% rename from lxcontainer/seccomp.go rename to seccomp.go index 90b6a92b..de57cec0 100644 --- a/lxcontainer/seccomp.go +++ b/seccomp.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "bufio" diff --git a/lxcontainer/utils.go b/utils.go similarity index 99% rename from lxcontainer/utils.go rename to utils.go index d2f748ea..f6cf02ff 100644 --- a/lxcontainer/utils.go +++ b/utils.go @@ -1,4 +1,4 @@ -package lxcontainer +package lxcri import ( "bytes" From de8551ad6958e747e5d04202752cdb5ae1109528 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 00:43:07 +0100 Subject: [PATCH 212/373] Complete transition to new repository name. Replaced all occurences of crio-lxc and CRIO_LXC. Signed-off-by: Ruben Jenster --- .gitignore | 10 ++- INSTALL.md | 8 +-- Makefile | 10 +-- README.md | 70 +++++++++---------- cmd/cli.go | 56 +++++++-------- cmd/init/Makefile | 7 -- cmd/init/{crio-lxc-init.c => lxcri-init.c} | 2 +- cmd/init/test.bats | 31 -------- cmd/start/{crio-lxc-start.c => lxcri-start.c} | 2 +- container.go | 4 +- .../{install-crio-lxc.sh => install-lxcri.sh} | 14 ++-- deployment/install-node.sh | 6 +- deployment/ubuntu.criolxc.Dockerfile | 7 -- deployment/ubuntu.lxcri.Dockerfile | 7 ++ init.go | 8 +-- runtime.go | 2 +- 16 files changed, 102 insertions(+), 142 deletions(-) delete mode 100644 cmd/init/Makefile rename cmd/init/{crio-lxc-init.c => lxcri-init.c} (99%) delete mode 100644 cmd/init/test.bats rename cmd/start/{crio-lxc-start.c => lxcri-start.c} (96%) rename deployment/{install-crio-lxc.sh => install-lxcri.sh} (52%) delete mode 100644 deployment/ubuntu.criolxc.Dockerfile create mode 100644 deployment/ubuntu.lxcri.Dockerfile diff --git a/.gitignore b/.gitignore index 547fd83e..23fe724a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,9 @@ *~ -crio-lxc -crio-lxc-start -crio-lxc-init -crio-lxc-container-hook +lxcri +lxcri-start +lxcri-init +lxcri-container-hook oci/ roots/ .stacker/ .keeptempdirs -cmd/container-hook/musl-1.2.1.tar.gz -cmd/container-hook/musl-1.2.1/ diff --git a/INSTALL.md b/INSTALL.md index cfd3451e..c978bd34 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -59,7 +59,7 @@ echo /usr/local/lib > /etc/ld.so.conf.d/local.conf ldconfig ``` -### crio-lxc +### lxcri ``` make install @@ -95,13 +95,13 @@ git reset --hard origin/release-1.20 make install PREFIX=/usr/local -CRIO_LXC_ROOT=/run/crio-lxc +CRIO_LXC_ROOT=/run/lxcri # environment for `crio config` export CONTAINER_CONMON=${PREFIX}/bin/conmon export CONTAINER_PINNS_PATH=${PREFIX}/bin/pinns -export CONTAINER_DEFAULT_RUNTIME=crio-lxc -export CONTAINER_RUNTIMES=crio-lxc:${PREFIX}/bin/crio-lxc:$CRIO_LXC_ROOT +export CONTAINER_DEFAULT_RUNTIME=lxcri +export CONTAINER_RUNTIMES=lxcri:${PREFIX}/bin/lxcri:$CRIO_LXC_ROOT crio config > /etc/crio/crio.conf ``` diff --git a/Makefile b/Makefile index 1519c68f..873410bf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ COMMIT_HASH=$(shell git describe --always --tags --long) COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) -BINS := crio-lxc-start crio-lxc-init crio-lxc-container-hook crio-lxc +BINS := lxcri-start lxcri-init lxcri-container-hook lxcri # Installation prefix for BINS PREFIX ?= /usr/local # Note: The default pkg-config directory is search after PKG_CONFIG_PATH @@ -27,18 +27,18 @@ test: lint: golangci-lint run -c ./lint.yaml ./... -crio-lxc: go.mod **/*.go +lxcri: go.mod **/*.go go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd -crio-lxc-start: cmd/start/crio-lxc-start.c +lxcri-start: cmd/start/lxcri-start.c $(CC) -Werror -Wpedantic -o $@ $? $(LIBLXC_LDFLAGS) -crio-lxc-init: cmd/init/crio-lxc-init.c +lxcri-init: cmd/init/lxcri-init.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null -crio-lxc-container-hook: cmd/container-hook/hook.c +lxcri-container-hook: cmd/container-hook/hook.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? fmt: diff --git a/README.md b/README.md index 7e554969..352880d5 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S ## Glossary -* `runtime` the crio-lxc binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) -* `container process` the process that starts and runs the container using liblxc (crio-lxc-start) +* `runtime` the lxcri binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) +* `container process` the process that starts and runs the container using liblxc (lxcri-start) * `container config` the LXC config file -* `bundle config` the crio-lxc container state (bundle path, pidfile ....) +* `bundle config` the lxcri container state (bundle path, pidfile ....) * `runtime spec` the OCI runtime spec from the bundle ## Bugs @@ -28,15 +28,15 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S ### Unimplemented features -* [runtime: Implement POSIX platform hooks](https://github.com/Drachenfels-GmbH/crio-lxc/issues/10) -* [runtime: Implement cgroup2 resource limits](https://github.com/Drachenfels-GmbH/crio-lxc/issues/11) +* [runtime: Implement POSIX platform hooks](https://github.com/Drachenfels-GmbH/lxcri/issues/10) +* [runtime: Implement cgroup2 resource limits](https://github.com/Drachenfels-GmbH/lxcri/issues/11) ## Configuration The runtime binary implements flags that are required by the `OCI runtime spec`,
and flags that are runtime specific (timeouts, hooks, logging ...). -Most of the runtime specific flags have corresponding environment variables. See `crio-lxc --help`.
+Most of the runtime specific flags have corresponding environment variables. See `lxcri --help`.
The runtime evaluates the flag value in the following order (lower order takes precedence). 1. cmdline flag from process arguments (overwrites process environment) @@ -50,46 +50,46 @@ Currently you have to compile to environment file yourself.
To list all available variables: ``` -grep EnvVars cmd/cli.go | grep -o CRIO_LXC_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" +grep EnvVars cmd/cli.go | grep -o LXCRI_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" ``` ### Environment file -The default path to the environment file is `/etc/defaults/crio-lxc`.
-It is loaded on every start of the `crio-lxc` binary, so changes take immediate effect.
+The default path to the environment file is `/etc/defaults/lxcri`.
+It is loaded on every start of the `lxcri` binary, so changes take immediate effect.
Empty lines and those commented with a leading *#* are ignored.
A malformed environment will let the next runtime call fail.
In production it's recommended that you replace the environment file atomically.
-E.g the environment file `/etc/default/crio-lxc` could look like this: +E.g the environment file `/etc/default/lxcri` could look like this: ```sh -CRIO_LXC_LOG_LEVEL=debug -CRIO_LXC_CONTAINER_LOG_LEVEL=debug -#CRIO_LXC_LOG_FILE= -#CRIO_LXC_LOG_TIMESTAMP= -#CRIO_LXC_MONITOR_CGROUP= -#CRIO_LXC_INIT_CMD= -#CRIO_LXC_START_CMD= -#CRIO_LXC_CONTAINER_HOOK= -#CRIO_LXC_APPARMOR= -#CRIO_LXC_CAPABILITIES= -#CRIO_LXC_CGROUP_DEVICES= -#CRIO_LXC_SECCOMP= -#CRIO_LXC_CREATE_TIMEOUT= -#CRIO_LXC_CREATE_HOOK=/usr/local/bin/crio-lxc-backup.sh -#CRIO_LXC_CREATE_HOOK_TIMEOUT= -#CRIO_LXC_START_TIMEOUT= -#CRIO_LXC_KILL_TIMEOUT= -#CRIO_LXC_DELETE_TIMEOUT= +LXCRI_LOG_LEVEL=debug +LXCRI_CONTAINER_LOG_LEVEL=debug +#LXCRI_LOG_FILE= +#LXCRI_LOG_TIMESTAMP= +#LXCRI_MONITOR_CGROUP= +#LXCRI_INIT_CMD= +#LXCRI_START_CMD= +#LXCRI_CONTAINER_HOOK= +#LXCRI_APPARMOR= +#LXCRI_CAPABILITIES= +#LXCRI_CGROUP_DEVICES= +#LXCRI_SECCOMP= +#LXCRI_CREATE_TIMEOUT= +#LXCRI_CREATE_HOOK=/usr/local/bin/lxcri-backup.sh +#LXCRI_CREATE_HOOK_TIMEOUT= +#LXCRI_START_TIMEOUT= +#LXCRI_KILL_TIMEOUT= +#LXCRI_DELETE_TIMEOUT= ``` ### Runtime (security) features All supported runtime security features are enabled by default.
The following runtime (security) features can optionally be disabled.
-Details see `crio-lxc --help` +Details see `lxcri --help` * apparmor * capabilities @@ -115,7 +115,7 @@ For filtering with `jq` you must strip the container process logs with `grep -v E.g Filter show only errors and warnings for runtime `create` command: ```sh - grep -v '^lxc ' /var/log/crio-lxc.log |\ + grep -v '^lxc ' /var/log/lxcri.log |\ jq -c 'select(.cmd == "create" and ( .l == "error or .l == "warn")' ``` @@ -153,7 +153,7 @@ You can use it to backup the runtime spec and container process config for furth The create hook executable must * not use the standard file descriptors (stdin/stdout/stderr) although they are nulled. -* not exceed `CRIO_LXC_CREATE_HOOK_TIMEOUT` or it is killed. +* not exceed `LXCRI_CREATE_HOOK_TIMEOUT` or it is killed. * not modify/delete any resources created by the runtime or container process The process environment contains the following variables: @@ -167,7 +167,7 @@ The process environment contains the following variables: * `LOG_FILE` the path to the log file * `RUNTIME_ERROR` (optional) the error message if the runtime cmd return with error -Example script `crio-lxc-backup.sh` that backs up any container runtime directory: +Example script `lxcri-backup.sh` that backs up any container runtime directory: ```sh #!/bin/sh @@ -181,7 +181,7 @@ cp -r $RUNTIME_PATH $OUT cp $SPEC_PATH $OUT/spec.json # remove non `grep` friendly runtime files (symlinks, binaries, fifos) -rm $OUT/.crio-lxc/cwd -rm $OUT/.crio-lxc/init -rm $OUT/.crio-lxc/syncfifo +rm $OUT/.lxcri/cwd +rm $OUT/.lxcri/init +rm $OUT/.lxcri/syncfifo ``` diff --git a/cmd/cli.go b/cmd/cli.go index 51babee3..71c6b9bb 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -17,9 +17,9 @@ import ( // Environment variables are populated by default from this environment file. // Existing environment variables are preserved. -var envFile = "/etc/default/crio-lxc" +var envFile = "/etc/default/lxcri" -const defaultLogFile = "/var/log/crio-lxc/crio-lxc.log" +const defaultLogFile = "/var/log/lxcri/lxcri.log" type app struct { lxcri.Runtime @@ -69,8 +69,8 @@ var version string func main() { app := cli.NewApp() - app.Name = "crio-lxc" - app.Usage = "crio-lxc is a CRI compliant runtime wrapper for lxc" + app.Name = "lxcri" + app.Usage = "lxcri is a CRI compliant runtime wrapper for lxc" app.Version = version // Disable the default ExitErrHandler. @@ -91,34 +91,34 @@ func main() { &cli.StringFlag{ Name: "log-level", Usage: "set the runtime log level (trace|debug|info|warn|error)", - EnvVars: []string{"CRIO_LXC_LOG_LEVEL"}, + EnvVars: []string{"LXCRI_LOG_LEVEL"}, Value: "info", Destination: &clxc.logConfig.Level, }, &cli.StringFlag{ Name: "log-file", Usage: "path to the log file for runtime and container output", - EnvVars: []string{"CRIO_LXC_LOG_FILE"}, + EnvVars: []string{"LXCRI_LOG_FILE"}, Value: defaultLogFile, Destination: &clxc.logConfig.FilePath, }, &cli.StringFlag{ Name: "log-timestamp", Usage: "timestamp format for the runtime log (see golang time package), default matches liblxc timestamp", - EnvVars: []string{"CRIO_LXC_LOG_TIMESTAMP"}, // e.g '0102 15:04:05.000' + EnvVars: []string{"LXCRI_LOG_TIMESTAMP"}, // e.g '0102 15:04:05.000' Destination: &clxc.logConfig.Timestamp, }, &cli.StringFlag{ Name: "container-log-level", Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", - EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_LEVEL"}, + EnvVars: []string{"LXCRI_CONTAINER_LOG_LEVEL"}, Value: "warn", Destination: &clxc.containerConfig.LogLevel, }, &cli.StringFlag{ Name: "container-log-file", Usage: "path to the log file for runtime and container output", - EnvVars: []string{"CRIO_LXC_CONTAINER_LOG_FILE"}, + EnvVars: []string{"LXCRI_CONTAINER_LOG_FILE"}, Value: defaultLogFile, Destination: &clxc.containerConfig.LogFile, }, @@ -126,7 +126,7 @@ func main() { Name: "root", Usage: "container runtime root where (logs, init and hook scripts). tmpfs is recommended.", // exec permissions are not required because init is bind mounted into the root - Value: "/run/crio-lxc", + Value: "/run/lxcri", Destination: &clxc.Root, }, &cli.BoolFlag{ @@ -138,56 +138,56 @@ func main() { Name: "monitor-cgroup", Usage: "cgroup slice for liblxc monitor process and pivot path", Destination: &clxc.MonitorCgroup, - EnvVars: []string{"CRIO_LXC_MONITOR_CGROUP"}, - Value: "crio-lxc-monitor.slice", + EnvVars: []string{"LXCRI_MONITOR_CGROUP"}, + Value: "lxcri-monitor.slice", }, &cli.StringFlag{ Name: "cmd-init", Usage: "absolute path to container init executable", - EnvVars: []string{"CRIO_LXC_INIT_CMD"}, - Value: "/usr/local/bin/crio-lxc-init", + EnvVars: []string{"LXCRI_INIT_CMD"}, + Value: "/usr/local/bin/lxcri-init", Destination: &clxc.Executables.Init, }, &cli.StringFlag{ Name: "cmd-start", Usage: "absolute path to container start executable", - EnvVars: []string{"CRIO_LXC_START_CMD"}, - Value: "/usr/local/bin/crio-lxc-start", + EnvVars: []string{"LXCRI_START_CMD"}, + Value: "/usr/local/bin/lxcri-start", Destination: &clxc.Executables.Start, }, &cli.StringFlag{ Name: "container-hook", Usage: "absolute path to container hook executable", - EnvVars: []string{"CRIO_LXC_CONTAINER_HOOK"}, - Value: "/usr/local/bin/crio-lxc-container-hook", + EnvVars: []string{"LXCRI_CONTAINER_HOOK"}, + Value: "/usr/local/bin/lxcri-container-hook", Destination: &clxc.Executables.Hook, }, &cli.BoolFlag{ Name: "apparmor", Usage: "set apparmor profile defined in container spec", Destination: &clxc.Features.Apparmor, - EnvVars: []string{"CRIO_LXC_APPARMOR"}, + EnvVars: []string{"LXCRI_APPARMOR"}, Value: true, }, &cli.BoolFlag{ Name: "capabilities", Usage: "keep capabilities defined in container spec", Destination: &clxc.Features.Capabilities, - EnvVars: []string{"CRIO_LXC_CAPABILITIES"}, + EnvVars: []string{"LXCRI_CAPABILITIES"}, Value: true, }, &cli.BoolFlag{ Name: "cgroup-devices", Usage: "allow only devices permitted by container spec", Destination: &clxc.Features.CgroupDevices, - EnvVars: []string{"CRIO_LXC_CGROUP_DEVICES"}, + EnvVars: []string{"LXCRI_CGROUP_DEVICES"}, Value: true, }, &cli.BoolFlag{ Name: "seccomp", Usage: "Generate and apply seccomp profile for lxc from container spec", Destination: &clxc.Features.Seccomp, - EnvVars: []string{"CRIO_LXC_SECCOMP"}, + EnvVars: []string{"LXCRI_SECCOMP"}, Value: true, }, } @@ -299,7 +299,7 @@ var createCmd = cli.Command{ &cli.DurationFlag{ Name: "timeout", Usage: "maximum duration for create to complete", - EnvVars: []string{"CRIO_LXC_CREATE_TIMEOUT"}, + EnvVars: []string{"LXCRI_CREATE_TIMEOUT"}, Value: time.Second * 60, Destination: &clxc.Timeouts.Create, }, @@ -307,13 +307,13 @@ var createCmd = cli.Command{ &cli.StringFlag{ Name: "create-hook", Usage: "absolute path to executable to run after create", - EnvVars: []string{"CRIO_LXC_CREATE_HOOK"}, + EnvVars: []string{"LXCRI_CREATE_HOOK"}, Destination: &clxc.createHook, }, &cli.DurationFlag{ Name: "hook-timeout", Usage: "maximum duration for hook to complete", - EnvVars: []string{"CRIO_LXC_CREATE_HOOK_TIMEOUT"}, + EnvVars: []string{"LXCRI_CREATE_HOOK_TIMEOUT"}, Value: time.Second * 5, Destination: &clxc.createHookTimeout, }, @@ -373,7 +373,7 @@ starts &cli.DurationFlag{ Name: "timeout", Usage: "start timeout", - EnvVars: []string{"CRIO_LXC_START_TIMEOUT"}, + EnvVars: []string{"LXCRI_START_TIMEOUT"}, Value: time.Second * 30, Destination: &clxc.Timeouts.Start, }, @@ -431,7 +431,7 @@ var killCmd = cli.Command{ &cli.DurationFlag{ Name: "timeout", Usage: "timeout for killing all processes in container cgroup", - EnvVars: []string{"CRIO_LXC_KILL_TIMEOUT"}, + EnvVars: []string{"LXCRI_KILL_TIMEOUT"}, Value: time.Second * 10, Destination: &clxc.Timeouts.Kill, }, @@ -468,7 +468,7 @@ var deleteCmd = cli.Command{ &cli.DurationFlag{ Name: "timeout", Usage: "timeout for deleting container", - EnvVars: []string{"CRIO_LXC_DELETE_TIMEOUT"}, + EnvVars: []string{"LXCRI_DELETE_TIMEOUT"}, Value: time.Second * 10, Destination: &clxc.Timeouts.Delete, }, diff --git a/cmd/init/Makefile b/cmd/init/Makefile deleted file mode 100644 index a50d18f6..00000000 --- a/cmd/init/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: crio-lxc-init - -crio-lxc-init: crio-lxc-init.c - /usr/local/musl/bin/musl-gcc -Wpedantic -Wall -static -g -o $@ $? - #musl-gcc -g3 -Wall -static $? -o $@ - # ensure that crio-lxc-init is statically compiled - ! ldd $@ 2>/dev/null diff --git a/cmd/init/crio-lxc-init.c b/cmd/init/lxcri-init.c similarity index 99% rename from cmd/init/crio-lxc-init.c rename to cmd/init/lxcri-init.c index 1c85f68b..8e823dc1 100644 --- a/cmd/init/crio-lxc-init.c +++ b/cmd/init/lxcri-init.c @@ -32,7 +32,7 @@ const char *error_log = "error.log"; #define ERROR(format, ...) \ { \ - dprintf(errfd, "[crio-lxc-init] " format, ##__VA_ARGS__); \ + dprintf(errfd, "[lxcri-init] " format, ##__VA_ARGS__); \ exit(EXIT_FAILURE); \ } diff --git a/cmd/init/test.bats b/cmd/init/test.bats deleted file mode 100644 index 03579f86..00000000 --- a/cmd/init/test.bats +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bats - -bin=$BATS_TEST_DIRNAME/crio-lxc-init - -cd_tmpdir () { - cd $BATS_TEST_DIRNAME -} - -myfoo() { - cd $BATS_TEST_DIRNAME - [ -f environ ] && rm environ - [ -f cmdline ] && rm cmdline - [ -f syncfifo ] && rm syncfifo -} - -#setup cd_tmpdir -teardown myfoo - - -@test "noon-existent environment file" { - #cd $BATS_TEST_DIRNAME - run $bin 12345 - echo $status - [ "$status" -eq 210 ] -} - -@test "non-existent environment file" { - #cd $BATS_TEST_DIRNAME - run $bin 12345 - [ "$status" -eq 210 ] -} diff --git a/cmd/start/crio-lxc-start.c b/cmd/start/lxcri-start.c similarity index 96% rename from cmd/start/crio-lxc-start.c rename to cmd/start/lxcri-start.c index 23d7c941..25abacd9 100644 --- a/cmd/start/crio-lxc-start.c +++ b/cmd/start/lxcri-start.c @@ -17,7 +17,7 @@ #define ERROR(format, ...) \ { \ - fprintf(stderr, "[crio-lxc-start] " format, ##__VA_ARGS__); \ + fprintf(stderr, "[lxcri-start] " format, ##__VA_ARGS__); \ ret = EXIT_FAILURE; \ goto out; \ } diff --git a/container.go b/container.go index 148b706b..4d211bc8 100644 --- a/container.go +++ b/container.go @@ -29,7 +29,7 @@ type ContainerConfig struct { BundlePath string ConsoleSocket string `json:",omitempty"` - // PidFile is the absolute path to the PID file of the container monitor process (crio-lxc-start) + // PidFile is the absolute path to the PID file of the container monitor process (lxcri-start) PidFile string MonitorCgroupDir string @@ -247,7 +247,7 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { return specs.StateStopped, err } - initCmdline := fmt.Sprintf("/.crio-lxc/init\000%s\000", c.ContainerID) + initCmdline := fmt.Sprintf("/.lxcri/init\000%s\000", c.ContainerID) if string(cmdline) == initCmdline { return specs.StateCreated, nil } diff --git a/deployment/install-crio-lxc.sh b/deployment/install-lxcri.sh similarity index 52% rename from deployment/install-crio-lxc.sh rename to deployment/install-lxcri.sh index 176906b3..afe62f01 100755 --- a/deployment/install-crio-lxc.sh +++ b/deployment/install-lxcri.sh @@ -6,15 +6,15 @@ set -e . $(dirname $(readlink -f $0))/utils.sh -CRIO_LXC_GIT_REPO="${CRIO_LXC_GIT_REPO:-https://github.com/Drachenfels-GmbH/crio-lxc.git}" -CRIO_LXC_GIT_VERSION="${CRIO_LXC_GIT_VERSION:-master}" -CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" +LXCRI_GIT_REPO="${LXCRI_GIT_REPO:-https://github.com/drachenfels-de/lxcri.git}" +LXCRI_GIT_VERSION="${LXCRI_GIT_VERSION:-master}" +LXCRI_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" install_crio_lxc() { local tmpdir=/tmp/lxc - git clone $CRIO_LXC_GIT_REPO $tmpdir + git clone $LXCRI_GIT_REPO $tmpdir cd $tmpdir - git reset --hard $CRIO_LXC_GIT_VERSION + git reset --hard $LXCRI_GIT_VERSION # lxc installed from source with dafault installation prefix is prefered export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH make install @@ -22,8 +22,8 @@ install_crio_lxc() { rm -rf $tmpdir } -apt_install $CRIO_LXC_BUILD_DEPS +apt_install $LXCRI_BUILD_DEPS install_golang install_crio_lxc uninstall_golang -apt_clean $CRIO_LXC_BUILD_DEPS +apt_clean $LXCRI_BUILD_DEPS diff --git a/deployment/install-node.sh b/deployment/install-node.sh index bd71368f..f5f441c8 100755 --- a/deployment/install-node.sh +++ b/deployment/install-node.sh @@ -57,12 +57,12 @@ install_crio() { # configure cri-o PREFIX=/usr/local - CRIO_LXC_ROOT=/run/crio-lxc + CRIO_LXC_ROOT=/run/lxcri # environment for `crio config` export CONTAINER_CONMON=${PREFIX}/bin/conmon export CONTAINER_PINNS_PATH=${PREFIX}/bin/pinns - export CONTAINER_DEFAULT_RUNTIME=crio-lxc - export CONTAINER_RUNTIMES=crio-lxc:${PREFIX}/bin/crio-lxc:$CRIO_LXC_ROOT + export CONTAINER_DEFAULT_RUNTIME=lxcri + export CONTAINER_RUNTIMES=lxcri:${PREFIX}/bin/lxcri:$CRIO_LXC_ROOT export CONTAINER_CNI_PLUGIN_DIR=$CNI_PLUGIN_DIR crio config >/etc/crio/crio.conf diff --git a/deployment/ubuntu.criolxc.Dockerfile b/deployment/ubuntu.criolxc.Dockerfile deleted file mode 100644 index d485a12a..00000000 --- a/deployment/ubuntu.criolxc.Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM lxc:0.1 - -ENV CRIO_LXC_GIT_VERSION=origin/standalone - -COPY install-crio-lxc.sh utils.sh /tmp -RUN /tmp/install-crio-lxc.sh -RUN rm /tmp/install-crio-lxc.sh /tmp/utils.sh diff --git a/deployment/ubuntu.lxcri.Dockerfile b/deployment/ubuntu.lxcri.Dockerfile new file mode 100644 index 00000000..9635b2e9 --- /dev/null +++ b/deployment/ubuntu.lxcri.Dockerfile @@ -0,0 +1,7 @@ +FROM lxc:0.1 + +ENV LXCRI_GIT_VERSION=origin/master + +COPY install-lxcri.sh utils.sh /tmp +RUN /tmp/install-lxcri.sh +RUN rm /tmp/install-lxcri.sh /tmp/utils.sh diff --git a/init.go b/init.go index dc2a9b19..722ed63f 100644 --- a/init.go +++ b/init.go @@ -12,9 +12,9 @@ import ( ) const ( - // initDir is the working directory for crio-lxc-init. + // initDir is the working directory for lxcri-init. // It contains the init binary itself and all files required for it. - initDir = "/.crio-lxc" + initDir = "/.lxcri" ) func createFifo(dst string, uid int, gid int, mode uint32) error { @@ -52,7 +52,7 @@ func configureInit(rt *Runtime, c *Container) error { uid := int(c.Process.User.UID) gid := int(c.Process.User.GID) - // create files required for crio-lxc-init + // create files required for lxcri-init if err := createFifo(c.syncFifoPath(), uid, gid, 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } @@ -80,7 +80,7 @@ func configureInit(rt *Runtime, c *Container) error { return err } - // bind mount crio-lxc-init into the container + // bind mount lxcri-init into the container initCmdPath := filepath.Join(runtimeInitDir, "init") err = touchFile(initCmdPath, 0) if err != nil { diff --git a/runtime.go b/runtime.go index a56014d1..3429ddf9 100644 --- a/runtime.go +++ b/runtime.go @@ -124,7 +124,7 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { defer cancel() go func() { - // NOTE this goroutine may leak until crio-lxc is terminated + // NOTE this goroutine may leak until lxcri-start is terminated ps, err := cmd.Process.Wait() if err != nil { rt.Log.Error().Err(err).Msg("failed to wait for start process") From 1570e13586829e7db67a14ee03d129c63386520f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 01:28:54 +0100 Subject: [PATCH 213/373] readme: Add notes about the relation to lxc/crio-lxc Signed-off-by: Ruben Jenster --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 352880d5..1a7aec68 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,16 @@ # About -This is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as -a drop-in container runtime replacement for use by -[CRI-O](https://github.com/kubernetes-sigs/cri-o). +`lxcri` is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as +a drop-in container runtime replacement for use by [CRI-O](https://github.com/kubernetes-sigs/cri-o). + +### History + +The project started as a fork of lxc/crio-lxc but has undergone several refactorings +and yet shares very little code with lxc/crio-lxc and was therefore renamed to `lxcri` + +### OCI compliance + +With liblxc >= https://github.com/lxc/lxc/commit/b5daeddc5afce1cad4915aef3e71fdfe0f428709 it passes all sonobuoy conformance tests. ## Installation From 6dc1b56d47dc136f59c16a36ab7422a7bd97feef Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 11:24:42 +0100 Subject: [PATCH 214/373] ci: Add workflow to check and build project. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..0af90ac5 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,28 @@ +--- +name: Build project with default make target +on: + - push + - pull_request + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.16.x + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo add-apt-repository ppa:ubuntu-lxc/daily -y + sudo apt-get install -qq lxc-dev musl musl-tools libc6-dev pkg-config make + + - name: Build + run: make + + - name: Run tests + run: make test From dd8470b721536b0ae394f53d7868963ede6c92f4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 12:00:52 +0100 Subject: [PATCH 215/373] workflow: Check .go files format. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0af90ac5..c2d7a73f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,11 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Check format + run: | + go fmt ./... + git diff-files --quiet + - name: Install dependencies run: | sudo add-apt-repository ppa:ubuntu-lxc/daily -y From caff432b429a570c194a0b050b6a33876f748629 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 13:59:34 +0100 Subject: [PATCH 216/373] Format sources in Makefile and check format in github workflow. Use shfmt to format and check shellscripts and golint to lint go sources. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 18 +++++++++++++++--- Makefile | 31 +++++++++++++++++++------------ lint.yaml | 17 ----------------- 3 files changed, 34 insertions(+), 32 deletions(-) delete mode 100644 lint.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2d7a73f..1cd2f714 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,6 @@ --- -name: Build project with default make target +# see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: Static check and build project on: - push - pull_request @@ -16,10 +17,21 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Check format + - name: Check format of go sources run: | go fmt ./... - git diff-files --quiet + git diff --exit-code + + - name: Check format of shell scripts + run: | + GO111MODULE=off go get -u mvdan.cc/sh/v3/cmd/shfmt + find . -name \*.sh | xargs shfmt -d + + - name: Lint go sources + run: | + GO111MODULE=off go get -u golang.org/x/lint/golint + golint -set_exit_status ./... + - name: Install dependencies run: | diff --git a/Makefile b/Makefile index 873410bf..ff028f96 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -COMMIT_HASH=$(shell git describe --always --tags --long) -COMMIT=$(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) +COMMIT_HASH = $(shell git describe --always --tags --long) +COMMIT = $(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) BINS := lxcri-start lxcri-init lxcri-container-hook lxcri # Installation prefix for BINS PREFIX ?= /usr/local @@ -10,22 +10,24 @@ LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) LDFLAGS=-X main.version=$(COMMIT) CC ?= cc MUSL_CC ?= musl-gcc +SHELL_SCRIPTS = $(wildcard **/*.sh) -all: fmt test $(BINS) +all: fmt test build -install: $(BINS) - cp -v $(BINS) $(PREFIX)/bin +update-tools: + GO111MODULE=off go get -u mvdan.cc/sh/v3/cmd/shfmt + GO111MODULE=off go get -u golang.org/x/lint/golint -.PHONY: clean -clean: - -rm -f $(BINS) +fmt: + go fmt ./... + shfmt -w $(SHELL_SCRIPTS) + golint ./... .PHONY: test test: go test -v ./... -lint: - golangci-lint run -c ./lint.yaml ./... +build: $(BINS) lxcri: go.mod **/*.go go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd @@ -41,5 +43,10 @@ lxcri-init: cmd/init/lxcri-init.c lxcri-container-hook: cmd/container-hook/hook.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? -fmt: - go fmt ./... +install: $(BINS) + cp -v $(BINS) $(PREFIX)/bin + +.PHONY: clean +clean: + -rm -f $(BINS) + diff --git a/lint.yaml b/lint.yaml deleted file mode 100644 index f58ce3b1..00000000 --- a/lint.yaml +++ /dev/null @@ -1,17 +0,0 @@ -issues: - exclude: - - 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked' - - 'error strings should not be capitalized' - - 'error strings should not end with punctuation' - - 'File is not `goimports`-ed' - - 'has \d* occurrences, make it a constant' - - 'line is \d* characters' - - 'is a global variable' - - 'ifElseChain: rewrite if-else to switch statement' - - 'Error return value of `.*` is not checked' - - 'cyclomatic complexity \d* of func' - - 'G107: Potential HTTP request made with variable url' - - 'should have name of the form ErrFoo' - - 'naked return in func' - - 'by other packages, and that stutters; consider calling this' - - 'File is not `gofmt`-ed with `-s`' From 219df7bb9bb2b757349622d269cf7bb818d3fdf6 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 14:31:16 +0100 Subject: [PATCH 217/373] ci: Continue if golint fails. Revert this commit when all exports are documented. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1cd2f714..cad05e16 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: run: | GO111MODULE=off go get -u golang.org/x/lint/golint golint -set_exit_status ./... - + continue-on-error: true - name: Install dependencies run: | From e68f326cd557415bd93c879af20936969cd2cc2e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 14:52:29 +0100 Subject: [PATCH 218/373] Use Makefile build target. The Makefile default target does stuff which already runs separate workflow steps. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cad05e16..a018e9e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: sudo apt-get install -qq lxc-dev musl musl-tools libc6-dev pkg-config make - name: Build - run: make + run: make build - name: Run tests run: make test From ed9063bf36fae366d2bb9a1683a425d7c2b06104 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 08:28:39 +0100 Subject: [PATCH 219/373] Add OnCreate hook to container. Run OnCreate hooks directly after creating the container runtime directory. Signed-off-by: Ruben Jenster --- container.go | 2 ++ create.go | 10 +++++++--- runtime.go | 16 +++++++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/container.go b/container.go index 4d211bc8..975f792e 100644 --- a/container.go +++ b/container.go @@ -40,6 +40,8 @@ type ContainerConfig struct { LogFile string Log zerolog.Logger `json:"-"` + + Hooks `json:"-"` } func (cfg ContainerConfig) ConfigFilePath() string { diff --git a/create.go b/create.go index d5044536..6aeb60b3 100644 --- a/create.go +++ b/create.go @@ -31,6 +31,13 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return nil, errorf("failed to create container: %w", err) } + if rt.OnCreate != nil { + rt.OnCreate(ctx, c) + } + if c.OnCreate != nil { + c.OnCreate(ctx, c) + } + if err := configureContainer(rt, c); err != nil { return nil, errorf("failed to configure container: %w", err) } @@ -39,9 +46,6 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return nil, errorf("failed to run container process: %w", err) } - if rt.Hooks.AfterCreate != nil { - defer rt.Hooks.AfterCreate(ctx, c) - } return c, nil } diff --git a/runtime.go b/runtime.go index 3429ddf9..2ebfb426 100644 --- a/runtime.go +++ b/runtime.go @@ -16,6 +16,17 @@ import ( var ErrNotExist = fmt.Errorf("container does not exist") var ErrExist = fmt.Errorf("container already exists") +type RuntimeHook func(ctx context.Context, c *Container) error + +// RuntimeHooks are callback functions executed within the container lifecycle. +type Hooks struct { + // OnCreate is called right after creation of container runtime directory + // and descriptor, but before the liblxc 'config' file is written. + // At this point it's possible to add files to the container runtime directory + // and modify the ContainerConfig. + OnCreate RuntimeHook +} + type Runtime struct { Log zerolog.Logger @@ -54,11 +65,6 @@ type Runtime struct { // runtime hooks (not OCI runtime hooks) - Hooks struct { - // AfterCreateContainer is called right after creating the container runtime directory and descriptor, - // and before creating the lxc 'config' file for the container. - AfterCreate func(ctx context.Context, c *Container) error `json:"-"` - } } func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { From cfa497a0070e02a44c7fb365f50eab95042cbff8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 08:45:33 +0100 Subject: [PATCH 220/373] Move liblxc log configuration to container file Signed-off-by: Ruben Jenster --- container.go | 40 ++++++++++++++++++++++++++++++++++++++++ create.go | 40 ---------------------------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/container.go b/container.go index 975f792e..00bcece5 100644 --- a/container.go +++ b/container.go @@ -486,3 +486,43 @@ func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.Atta } return opts, nil } + +func setLog(c *Container) error { + // Never let lxc write to stdout, stdout belongs to the container init process. + // Explicitly disable it - allthough it is currently the default. + c.linuxcontainer.SetVerbosity(lxc.Quiet) + // The log level for a running container is set, and may change, per runtime call. + err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(c.LogLevel)) + if err != nil { + return fmt.Errorf("failed to set container loglevel: %w", err) + } + if err := c.linuxcontainer.SetLogFile(c.LogFile); err != nil { + return fmt.Errorf("failed to set container log file: %w", err) + } + return nil +} + +func parseContainerLogLevel(level string) lxc.LogLevel { + switch strings.ToLower(level) { + case "trace": + return lxc.TRACE + case "debug": + return lxc.DEBUG + case "info": + return lxc.INFO + case "notice": + return lxc.NOTICE + case "warn": + return lxc.WARN + case "error": + return lxc.ERROR + case "crit": + return lxc.CRIT + case "alert": + return lxc.ALERT + case "fatal": + return lxc.FATAL + default: + return lxc.WARN + } +} diff --git a/create.go b/create.go index 6aeb60b3..cb278922 100644 --- a/create.go +++ b/create.go @@ -360,43 +360,3 @@ func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string } return ptmx.Close() } - -func setLog(c *Container) error { - // Never let lxc write to stdout, stdout belongs to the container init process. - // Explicitly disable it - allthough it is currently the default. - c.linuxcontainer.SetVerbosity(lxc.Quiet) - // The log level for a running container is set, and may change, per runtime call. - err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(c.LogLevel)) - if err != nil { - return fmt.Errorf("failed to set container loglevel: %w", err) - } - if err := c.linuxcontainer.SetLogFile(c.LogFile); err != nil { - return fmt.Errorf("failed to set container log file: %w", err) - } - return nil -} - -func parseContainerLogLevel(level string) lxc.LogLevel { - switch strings.ToLower(level) { - case "trace": - return lxc.TRACE - case "debug": - return lxc.DEBUG - case "info": - return lxc.INFO - case "notice": - return lxc.NOTICE - case "warn": - return lxc.WARN - case "error": - return lxc.ERROR - case "crit": - return lxc.CRIT - case "alert": - return lxc.ALERT - case "fatal": - return lxc.FATAL - default: - return lxc.WARN - } -} From 53818ca16fad053811e8dcbbb88cdee0aa4cae4b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 08:47:45 +0100 Subject: [PATCH 221/373] Run go mod tidy in fmt target. Signed-off-by: Ruben Jenster --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index ff028f96..bb7d17d2 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ fmt: go fmt ./... shfmt -w $(SHELL_SCRIPTS) golint ./... + go mod tidy .PHONY: test test: From afaa0143ceffd172f83181e60a3af6e85116fc87 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 08:52:33 +0100 Subject: [PATCH 222/373] Update godoc comments. Group variables. Signed-off-by: Ruben Jenster --- container.go | 5 ++--- create.go | 10 ++++++++-- namespaces.go | 41 +++++++++++++++++++++-------------------- runtime.go | 10 ++++++++-- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/container.go b/container.go index 00bcece5..de1b8fec 100644 --- a/container.go +++ b/container.go @@ -16,6 +16,7 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) +// ContainerConfig is the configuration for a single Container instance. type ContainerConfig struct { *specs.Spec @@ -80,9 +81,7 @@ func (c *ContainerConfig) LoadSpecJson(p string) error { return decodeFileJSON(c.Spec, p) } -// ContainerInfo holds the information about a single container. -// It is created at 'create' within the container runtime dir and not changed afterwards. -// It is removed when the container is deleted. +// Container is the runtime state of a container instance. type Container struct { linuxcontainer *lxc.Container `json:"-"` *ContainerConfig diff --git a/create.go b/create.go index cb278922..84d7ef7f 100644 --- a/create.go +++ b/create.go @@ -9,13 +9,16 @@ import ( "path/filepath" "strings" - "golang.org/x/sys/unix" - "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" "gopkg.in/lxc/go-lxc.v2" ) +// Create creates a single container instance from the given ContainerConfig. +// Create is the first runtime method to call within the lifecycle of a container. +// You may have to call Runtime.Delete to cleanup container runtime state, +// if Create returns with an error. func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Create) defer cancel() @@ -49,6 +52,9 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, nil } +// CheckSystem checks the hosts system configuration. +// Unsupported runtime features are disabled and a warning message is logged. +// CheckSystem should be called (once) before using the Runtime. func (rt *Runtime) CheckSystem() error { err := canExecute(rt.Executables.Start, rt.Executables.Hook, rt.Executables.Init) if err != nil { diff --git a/namespaces.go b/namespaces.go index 0898c3ee..4aee4088 100644 --- a/namespaces.go +++ b/namespaces.go @@ -16,26 +16,27 @@ type Namespace struct { CloneFlag int } -var CgroupNamespace = Namespace{"cgroup", unix.CLONE_NEWCGROUP} -var IPCNamespace = Namespace{"ipc", unix.CLONE_NEWIPC} -var MountNamespace = Namespace{"mnt", unix.CLONE_NEWNS} -var NetworkNamespace = Namespace{"net", unix.CLONE_NEWNET} -var PIDNamespace = Namespace{"pid", unix.CLONE_NEWPID} -var TimeNamespace = Namespace{"time", unix.CLONE_NEWTIME} -var UserNamespace = Namespace{"user", unix.CLONE_NEWUSER} -var UTSNamespace = Namespace{"uts", unix.CLONE_NEWUTS} - -// maps from CRIO namespace names to LXC names and clone flags -var namespaceMap = map[specs.LinuxNamespaceType]Namespace{ - specs.CgroupNamespace: CgroupNamespace, - specs.IPCNamespace: IPCNamespace, - specs.MountNamespace: MountNamespace, - specs.NetworkNamespace: NetworkNamespace, - specs.PIDNamespace: PIDNamespace, - // specs.TimeNamespace: TimeNamespace, - specs.UserNamespace: UserNamespace, - specs.UTSNamespace: UTSNamespace, -} +var ( + CgroupNamespace = Namespace{"cgroup", unix.CLONE_NEWCGROUP} + IPCNamespace = Namespace{"ipc", unix.CLONE_NEWIPC} + MountNamespace = Namespace{"mnt", unix.CLONE_NEWNS} + NetworkNamespace = Namespace{"net", unix.CLONE_NEWNET} + PIDNamespace = Namespace{"pid", unix.CLONE_NEWPID} + TimeNamespace = Namespace{"time", unix.CLONE_NEWTIME} + UserNamespace = Namespace{"user", unix.CLONE_NEWUSER} + UTSNamespace = Namespace{"uts", unix.CLONE_NEWUTS} + + namespaceMap = map[specs.LinuxNamespaceType]Namespace{ + specs.CgroupNamespace: CgroupNamespace, + specs.IPCNamespace: IPCNamespace, + specs.MountNamespace: MountNamespace, + specs.NetworkNamespace: NetworkNamespace, + specs.PIDNamespace: PIDNamespace, + // specs.TimeNamespace: TimeNamespace, + specs.UserNamespace: UserNamespace, + specs.UTSNamespace: UTSNamespace, + } +) func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { flags := 0 diff --git a/runtime.go b/runtime.go index 2ebfb426..6a34f4a3 100644 --- a/runtime.go +++ b/runtime.go @@ -13,8 +13,10 @@ import ( "golang.org/x/sys/unix" ) -var ErrNotExist = fmt.Errorf("container does not exist") -var ErrExist = fmt.Errorf("container already exists") +var ( + ErrNotExist = fmt.Errorf("container does not exist") + ErrExist = fmt.Errorf("container already exists") +) type RuntimeHook func(ctx context.Context, c *Container) error @@ -28,8 +30,12 @@ type Hooks struct { } type Runtime struct { + // Log is the logger used by the runtime. Log zerolog.Logger + // Root is the file path to the runtime directory. + // Directories for containers created by the runtime + // are created within this directory. Root string // Use systemd encoded cgroup path (from crio-o/conmon) // is true if /etc/crio/crio.conf#cgroup_manager = "systemd" From fc8de74b07d605eed24709d68312efa94c71a2dd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 08:56:05 +0100 Subject: [PATCH 223/373] Add DefaultRuntime and wrapper functions Signed-off-by: Ruben Jenster --- create.go | 6 +-- log/log.go | 2 +- mount_test.go | 7 +--- runtime.go | 111 +++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 94 insertions(+), 32 deletions(-) diff --git a/create.go b/create.go index 84d7ef7f..aeb2ef73 100644 --- a/create.go +++ b/create.go @@ -31,7 +31,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) if err := c.create(); err != nil { - return nil, errorf("failed to create container: %w", err) + return c, errorf("failed to create container: %w", err) } if rt.OnCreate != nil { @@ -42,11 +42,11 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container } if err := configureContainer(rt, c); err != nil { - return nil, errorf("failed to configure container: %w", err) + return c, errorf("failed to configure container: %w", err) } if err := rt.runStartCmd(ctx, c); err != nil { - return nil, errorf("failed to run container process: %w", err) + return c, errorf("failed to run container process: %w", err) } return c, nil diff --git a/log/log.go b/log/log.go index 689061e2..6f77e533 100644 --- a/log/log.go +++ b/log/log.go @@ -52,6 +52,6 @@ func NewLogger(out io.Writer, level zerolog.Level) zerolog.Context { return zerolog.New(out).Level(level).With().Timestamp().Caller() } -func NewTestLogger(color bool) zerolog.Logger { +func ConsoleLogger(color bool) zerolog.Logger { return zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: !color}).Level(zerolog.DebugLevel).With().Timestamp().Caller().Logger() } diff --git a/mount_test.go b/mount_test.go index 3800ff81..5e2097df 100644 --- a/mount_test.go +++ b/mount_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/drachenfels-de/lxcri/log" "github.com/stretchr/testify/require" ) @@ -75,13 +74,11 @@ func TestResolveMountDestination_relative(t *testing.T) { } func TestFilterMountOptions(t *testing.T) { - rt := Runtime{Log: log.NewTestLogger(true)} - opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") - out := filterMountOptions(&rt, "tmpfs", opts) + out := filterMountOptions(DefaultRuntime, "tmpfs", opts) require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) - out = filterMountOptions(&rt, "nosuchfs", opts) + out = filterMountOptions(DefaultRuntime, "nosuchfs", opts) require.Equal(t, opts, out) } diff --git a/runtime.go b/runtime.go index 6a34f4a3..49bd2f86 100644 --- a/runtime.go +++ b/runtime.go @@ -11,6 +11,13 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" + + "github.com/drachenfels-de/lxcri/log" +) + +const ( + // DefaultRuntimeRoot is the path to the default runtime directory. + DefaultRuntimeRoot = "/var/lib/lxcri" ) var ( @@ -18,6 +25,33 @@ var ( ErrExist = fmt.Errorf("container already exists") ) +// RuntimeExecutables contains names for all (external) executed commands. +// The excutable name is used as path if it contains a slash, otherwise +// the PATH environment variable is consulted to resolve the executable path. +type RuntimeExecutables struct { + Start string + Init string + Hook string +} + +// RuntimeTimeouts are timeouts for Runtime API calls. +type RuntimeTimeouts struct { + Create time.Duration + Start time.Duration + Kill time.Duration + Delete time.Duration +} + +// RuntimeFeatures are (security) features supported by the Runtime. +// The supported features are enabled on any Container instance +// created by Runtime.Create. +type RuntimeFeatures struct { + Seccomp bool + Capabilities bool + Apparmor bool + CgroupDevices bool +} + type RuntimeHook func(ctx context.Context, c *Container) error // RuntimeHooks are callback functions executed within the container lifecycle. @@ -44,33 +78,64 @@ type Runtime struct { // similar to /etc/crio/crio.conf#conmon_cgroup MonitorCgroup string - // Executables contains names for all (external) executed commands. - // The excutable name is used as path if it contains a slash, otherwise - // the PATH environment variable is consulted to resolve the executable path. - Executables struct { - Start string - Init string - Hook string - } + Executables RuntimeExecutables + Timeouts RuntimeTimeouts + Features RuntimeFeatures - // Timeouts for API commands - Timeouts struct { - Create time.Duration - Start time.Duration - Kill time.Duration - Delete time.Duration - } + Hooks `json:"-"` +} - // feature gates - Features struct { - Seccomp bool - Capabilities bool - Apparmor bool - CgroupDevices bool - } +var DefaultRuntime = &Runtime{ + Log: log.ConsoleLogger(true), + Root: DefaultRuntimeRoot, + SystemdCgroup: true, + Executables: RuntimeExecutables{ + Start: "lxcri-start", + Init: "lxcri-init", + Hook: "lxcri-hook", + }, + Timeouts: RuntimeTimeouts{ + Create: time.Second * 60, + Start: time.Second * 30, + Kill: time.Second * 30, + Delete: time.Second * 60, + }, + Features: RuntimeFeatures{ + Seccomp: true, + Capabilities: true, + Apparmor: true, + CgroupDevices: true, + }, +} + +// CheckSystem is a wrapper around DefaultRuntime.CheckSystem +func CheckSystem() error { + return DefaultRuntime.CheckSystem() +} + +// Create is a wrapper around DefaultRuntime.Create +func Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { + return DefaultRuntime.Create(ctx, cfg) +} - // runtime hooks (not OCI runtime hooks) +// Load is a wrapper around DefaultRuntime.Load +func Load(cfg *ContainerConfig) (*Container, error) { + return DefaultRuntime.Load(cfg) +} + +// Start is a wrapper around DefaultRuntime.Start +func Start(ctx context.Context, c *Container) error { + return DefaultRuntime.Start(ctx, c) +} + +// Kill is a wrapper around DefaultRuntime.Kill +func Kill(ctx context.Context, c *Container, signum unix.Signal) error { + return DefaultRuntime.Kill(ctx, c, signum) +} +// Delete is a wrapper around DefaultRuntime.Delete +func Delete(ctx context.Context, c *Container, force bool) error { + return DefaultRuntime.Delete(ctx, c, force) } func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { From 60fa1b2b760ed7f8ca0205baea5ae6b392e3969a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 08:30:18 +0100 Subject: [PATCH 224/373] Small build bugfixes. Signed-off-by: Ruben Jenster --- deployment/install-lxcri.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/install-lxcri.sh b/deployment/install-lxcri.sh index afe62f01..24aec121 100755 --- a/deployment/install-lxcri.sh +++ b/deployment/install-lxcri.sh @@ -15,7 +15,7 @@ install_crio_lxc() { git clone $LXCRI_GIT_REPO $tmpdir cd $tmpdir git reset --hard $LXCRI_GIT_VERSION - # lxc installed from source with dafault installation prefix is prefered + # lxc installed from source with default installation prefix is prefered export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH make install cd From cf83a48a7ecc175e5882df6af686662b41fcadf3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 19 Feb 2021 23:34:37 +0100 Subject: [PATCH 225/373] Move GIT based lxc installation function to utils.sh Signed-off-by: Ruben Jenster --- deployment/ubuntu-install-lxc.sh | 30 ------------------------------ deployment/utils.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh index 0a4185e2..9e7ab1a2 100755 --- a/deployment/ubuntu-install-lxc.sh +++ b/deployment/ubuntu-install-lxc.sh @@ -4,9 +4,6 @@ set -x # abort if subshell command exits non-zero set -e -# Bash auto indentation `gg=G` -# see https://unix.stackexchange.com/questions/19945/auto-indent-format-code-for-vim - # see `man 5 os-release` and http://0pointer.de/blog/projects/os-release . /etc/os-release @@ -24,38 +21,11 @@ install_lxc_ppa() { apt_install lxc } -LXC_GIT_REPO="${LXC_GIT_REPO:-https://github.com/lxc/lxc.git}" -LXC_GIT_VERSION="${LXC_GIT_VERSION:-master}" - -LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} -LXC_INSTALL_COMMANDS=${LXC_INSTALL_COMMANDS:-no} -LXC_INSTALL_DOC=${LXC_INSTALL_DOC:-no} -LXC_INSTALL_API_DOCS=${LXC_INSTALL_API_DOCS:-no} - LXC_BUILD_TOOLS="build-essential libtool automake pkg-config git ca-certificates" LXC_BUILD_LIBS="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev" LXC_BUILD_DEPS="$LXC_BUILD_TOOLS $LXC_BUILD_LIBS" LXC_RUNTIME_DEPS="libseccomp2 libapparmor1 libbtrfs0 libdevmapper1.02.1 libcap2" -install_lxc_git() { - local tmpdir=/tmp/lxc - git clone $LXC_GIT_REPO $tmpdir - cd $tmpdir - git reset --hard $LXC_GIT_VERSION - ./autogen.sh - ./configure --enable-bash=no --enable-seccomp=yes \ - --enable-capabilities=yes --enable-apparmor=yes \ - --enable-tools=$LXC_INSTALL_TOOLS --enable-commands=$LXC_INSTALL_COMMANDS \ - --enable-static=no --enable-examples=no \ - --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS - make install - git describe --tags >/usr/local/lib/liblxc.version.txt - echo /usr/local/lib >>/etc/ld.so.conf.d/local.conf - ldconfig - cd - rm -rf $tmpdir -} - case $LXC_INSTALL_FROM in "git") apt_install $LXC_BUILD_DEPS $LXC_RUNTIME_DEPS diff --git a/deployment/utils.sh b/deployment/utils.sh index 6971dff9..68f98c0a 100755 --- a/deployment/utils.sh +++ b/deployment/utils.sh @@ -33,3 +33,30 @@ uninstall_golang() { rm -rf $(go env GOCACHE) rm -rf $(go env GOROOT) } + +LXC_GIT_REPO="${LXC_GIT_REPO:-https://github.com/lxc/lxc.git}" +LXC_GIT_VERSION="${LXC_GIT_VERSION:-master}" + +LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} +LXC_INSTALL_COMMANDS=${LXC_INSTALL_COMMANDS:-no} +LXC_INSTALL_DOC=${LXC_INSTALL_DOC:-no} +LXC_INSTALL_API_DOCS=${LXC_INSTALL_API_DOCS:-no} + +install_lxc_git() { + local tmpdir=/tmp/lxc + git clone $LXC_GIT_REPO $tmpdir + cd $tmpdir + git reset --hard $LXC_GIT_VERSION + ./autogen.sh + ./configure --enable-bash=no --enable-seccomp=yes \ + --enable-capabilities=yes --enable-apparmor=yes \ + --enable-tools=$LXC_INSTALL_TOOLS --enable-commands=$LXC_INSTALL_COMMANDS \ + --enable-static=no --enable-examples=no \ + --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS + make install + git describe --tags >/usr/local/lib/liblxc.version.txt + echo /usr/local/lib >>/etc/ld.so.conf.d/local.conf + ldconfig + cd + rm -rf $tmpdir +} From 9664a50b17766bb1ed8a9581a3911011cd822001 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 24 Mar 2021 08:35:31 +0100 Subject: [PATCH 226/373] deployment: Set shell options directly via shebang. Signed-off-by: Ruben Jenster --- deployment/install-lxcri.sh | 6 +----- deployment/ubuntu-install-lxc.sh | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/deployment/install-lxcri.sh b/deployment/install-lxcri.sh index 24aec121..4f68bf70 100755 --- a/deployment/install-lxcri.sh +++ b/deployment/install-lxcri.sh @@ -1,8 +1,4 @@ -#!/bin/sh -# enable debug logging -set -x -# abort if subshell command exits non-zero -set -e +#!/bin/sh -eux . $(dirname $(readlink -f $0))/utils.sh diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh index 9e7ab1a2..4be4bad9 100755 --- a/deployment/ubuntu-install-lxc.sh +++ b/deployment/ubuntu-install-lxc.sh @@ -1,8 +1,4 @@ -#!/bin/sh -# enable debug logging -set -x -# abort if subshell command exits non-zero -set -e +#!/bin/sh -eux # see `man 5 os-release` and http://0pointer.de/blog/projects/os-release . /etc/os-release From 4281192bfafc3218ff9a3ad511408079eea48b83 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 09:50:30 +0100 Subject: [PATCH 227/373] Rename executables consistently. Signed-off-by: Ruben Jenster --- .gitignore | 11 ++++------ Makefile | 12 +++++------ README.md | 6 +++--- .../hook.c => lxcri-hook/lxcri-hook.c} | 0 cmd/{init => lxcri-init}/lxcri-init.c | 0 cmd/{start => lxcri-start}/lxcri-start.c | 0 cmd/{ => lxcri}/cli.go | 20 +++++++++---------- cmd/{ => lxcri}/utils.go | 0 cmd/{ => lxcri}/utils_test.go | 0 9 files changed, 23 insertions(+), 26 deletions(-) rename cmd/{container-hook/hook.c => lxcri-hook/lxcri-hook.c} (100%) rename cmd/{init => lxcri-init}/lxcri-init.c (100%) rename cmd/{start => lxcri-start}/lxcri-start.c (100%) rename cmd/{ => lxcri}/cli.go (97%) rename cmd/{ => lxcri}/utils.go (100%) rename cmd/{ => lxcri}/utils_test.go (100%) diff --git a/.gitignore b/.gitignore index 23fe724a..72a57242 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ *~ -lxcri -lxcri-start -lxcri-init -lxcri-container-hook -oci/ -roots/ +/lxcri +/lxcri-start +/lxcri-init +/lxcri-hook .stacker/ -.keeptempdirs diff --git a/Makefile b/Makefile index bb7d17d2..c1776e44 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ COMMIT_HASH = $(shell git describe --always --tags --long) COMMIT = $(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) -BINS := lxcri-start lxcri-init lxcri-container-hook lxcri +BINS := lxcri-start lxcri-init lxcri-hook lxcri # Installation prefix for BINS PREFIX ?= /usr/local # Note: The default pkg-config directory is search after PKG_CONFIG_PATH @@ -10,7 +10,7 @@ LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) LDFLAGS=-X main.version=$(COMMIT) CC ?= cc MUSL_CC ?= musl-gcc -SHELL_SCRIPTS = $(wildcard **/*.sh) +SHELL_SCRIPTS = $(wildcard **/*.sh) all: fmt test build @@ -31,17 +31,17 @@ test: build: $(BINS) lxcri: go.mod **/*.go - go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd + go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri -lxcri-start: cmd/start/lxcri-start.c +lxcri-start: cmd/lxcri-start/lxcri-start.c $(CC) -Werror -Wpedantic -o $@ $? $(LIBLXC_LDFLAGS) -lxcri-init: cmd/init/lxcri-init.c +lxcri-init: cmd/lxcri-init/lxcri-init.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null -lxcri-container-hook: cmd/container-hook/hook.c +lxcri-hook: cmd/lxcri-hook/lxcri-hook.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? install: $(BINS) diff --git a/README.md b/README.md index 1a7aec68..ec2ab197 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,9 @@ LXCRI_CONTAINER_LOG_LEVEL=debug #LXCRI_LOG_FILE= #LXCRI_LOG_TIMESTAMP= #LXCRI_MONITOR_CGROUP= -#LXCRI_INIT_CMD= -#LXCRI_START_CMD= -#LXCRI_CONTAINER_HOOK= +#LXCRI_INIT_EXEC= +#LXCRI_START_EXEC= +#LXCRI_HOOK_EXEC= #LXCRI_APPARMOR= #LXCRI_CAPABILITIES= #LXCRI_CGROUP_DEVICES= diff --git a/cmd/container-hook/hook.c b/cmd/lxcri-hook/lxcri-hook.c similarity index 100% rename from cmd/container-hook/hook.c rename to cmd/lxcri-hook/lxcri-hook.c diff --git a/cmd/init/lxcri-init.c b/cmd/lxcri-init/lxcri-init.c similarity index 100% rename from cmd/init/lxcri-init.c rename to cmd/lxcri-init/lxcri-init.c diff --git a/cmd/start/lxcri-start.c b/cmd/lxcri-start/lxcri-start.c similarity index 100% rename from cmd/start/lxcri-start.c rename to cmd/lxcri-start/lxcri-start.c diff --git a/cmd/cli.go b/cmd/lxcri/cli.go similarity index 97% rename from cmd/cli.go rename to cmd/lxcri/cli.go index 71c6b9bb..1b7400b6 100644 --- a/cmd/cli.go +++ b/cmd/lxcri/cli.go @@ -142,24 +142,24 @@ func main() { Value: "lxcri-monitor.slice", }, &cli.StringFlag{ - Name: "cmd-init", - Usage: "absolute path to container init executable", - EnvVars: []string{"LXCRI_INIT_CMD"}, - Value: "/usr/local/bin/lxcri-init", + Name: "exec-init", + Usage: "path to container init executable", + EnvVars: []string{"LXCRI_INIT_EXEC"}, + Value: "lxcri-init", Destination: &clxc.Executables.Init, }, &cli.StringFlag{ - Name: "cmd-start", + Name: "exec-start", Usage: "absolute path to container start executable", - EnvVars: []string{"LXCRI_START_CMD"}, - Value: "/usr/local/bin/lxcri-start", + EnvVars: []string{"LXCRI_START_EXEC"}, + Value: "lxcri-start", Destination: &clxc.Executables.Start, }, &cli.StringFlag{ - Name: "container-hook", + Name: "exec-hook", Usage: "absolute path to container hook executable", - EnvVars: []string{"LXCRI_CONTAINER_HOOK"}, - Value: "/usr/local/bin/lxcri-container-hook", + EnvVars: []string{"LXCRI_HOOK_EXEC"}, + Value: "lxcri-hook", Destination: &clxc.Executables.Hook, }, &cli.BoolFlag{ diff --git a/cmd/utils.go b/cmd/lxcri/utils.go similarity index 100% rename from cmd/utils.go rename to cmd/lxcri/utils.go diff --git a/cmd/utils_test.go b/cmd/lxcri/utils_test.go similarity index 100% rename from cmd/utils_test.go rename to cmd/lxcri/utils_test.go From 4b031444fcc12d07c1a354b9fa524ad3188f032b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 11:21:12 +0100 Subject: [PATCH 228/373] Fix missing prerequisites in Makefile. Signed-off-by: Ruben Jenster --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c1776e44..fb26dcfa 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) LDFLAGS=-X main.version=$(COMMIT) CC ?= cc MUSL_CC ?= musl-gcc -SHELL_SCRIPTS = $(wildcard **/*.sh) +SHELL_SCRIPTS = $(shell find . -name \*.sh) +GO_SRC = $(shell find . -name \*.go) all: fmt test build @@ -30,7 +31,7 @@ test: build: $(BINS) -lxcri: go.mod **/*.go +lxcri: go.mod $(GO_SRC) go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri lxcri-start: cmd/lxcri-start/lxcri-start.c @@ -44,7 +45,7 @@ lxcri-init: cmd/lxcri-init/lxcri-init.c lxcri-hook: cmd/lxcri-hook/lxcri-hook.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? -install: $(BINS) +install: build cp -v $(BINS) $(PREFIX)/bin .PHONY: clean From 53b26e9fca13f90073a5c794cd9d0ad7cf8a7f71 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 14:07:28 +0100 Subject: [PATCH 229/373] Load executables from LibexecDir Do not install runtime executables into the PATH. Runtime executables should only be executed by the runtime and should not be visible for the user. Remove Executable flags in favor of the new LibexecDir flag. Executables are always loaded from LibexecDir. Signed-off-by: Ruben Jenster --- Makefile | 13 +++++++++---- README.md | 4 +--- cmd/lxcri/cli.go | 39 +++++++++++++-------------------------- create.go | 4 ++-- init.go | 2 +- runtime.go | 44 +++++++++++++++++++++----------------------- 6 files changed, 47 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index fb26dcfa..ba9b3dfd 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,15 @@ COMMIT_HASH = $(shell git describe --always --tags --long) COMMIT = $(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) -BINS := lxcri-start lxcri-init lxcri-hook lxcri +BINS := lxcri +LIBEXEC_BINS := lxcri-start lxcri-init lxcri-hook # Installation prefix for BINS PREFIX ?= /usr/local +LIBEXEC_DIR = $(PREFIX)/libexec/lxcri # Note: The default pkg-config directory is search after PKG_CONFIG_PATH PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig export PKG_CONFIG_PATH LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) -LDFLAGS=-X main.version=$(COMMIT) +LDFLAGS=-X main.version=$(COMMIT) -X main.libexecDir=$(LIBEXEC_DIR) CC ?= cc MUSL_CC ?= musl-gcc SHELL_SCRIPTS = $(shell find . -name \*.sh) @@ -29,7 +31,7 @@ fmt: test: go test -v ./... -build: $(BINS) +build: $(BINS) $(LIBEXEC_BINS) lxcri: go.mod $(GO_SRC) go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri @@ -46,9 +48,12 @@ lxcri-hook: cmd/lxcri-hook/lxcri-hook.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? install: build + mkdir -p $(PREFIX)/bin cp -v $(BINS) $(PREFIX)/bin + mkdir -p $(LIBEXEC_DIR) + cp -v $(LIBEXEC_BINS) $(LIBEXEC_DIR) .PHONY: clean clean: - -rm -f $(BINS) + -rm -f $(BINS) $(LIBEXEC_BINS) diff --git a/README.md b/README.md index ec2ab197..b7d415f8 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,7 @@ LXCRI_CONTAINER_LOG_LEVEL=debug #LXCRI_LOG_FILE= #LXCRI_LOG_TIMESTAMP= #LXCRI_MONITOR_CGROUP= -#LXCRI_INIT_EXEC= -#LXCRI_START_EXEC= -#LXCRI_HOOK_EXEC= +#LXCRI_LIBEXEC= #LXCRI_APPARMOR= #LXCRI_CAPABILITIES= #LXCRI_CGROUP_DEVICES= diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 1b7400b6..d47ecbbb 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -15,11 +15,14 @@ import ( "github.com/urfave/cli/v2" ) -// Environment variables are populated by default from this environment file. -// Existing environment variables are preserved. -var envFile = "/etc/default/lxcri" - -const defaultLogFile = "/var/log/lxcri/lxcri.log" +var ( + // Environment variables are populated by default from this environment file. + // Existing environment variables are preserved. + envFile = "/etc/default/lxcri" + defaultLogFile = "/var/log/lxcri/lxcri.log" + version = "undefined" + libexecDir = "/usr/libexec/lxcri" +) type app struct { lxcri.Runtime @@ -65,8 +68,6 @@ func (app *app) release() error { return nil } -var version string - func main() { app := cli.NewApp() app.Name = "lxcri" @@ -142,25 +143,11 @@ func main() { Value: "lxcri-monitor.slice", }, &cli.StringFlag{ - Name: "exec-init", - Usage: "path to container init executable", - EnvVars: []string{"LXCRI_INIT_EXEC"}, - Value: "lxcri-init", - Destination: &clxc.Executables.Init, - }, - &cli.StringFlag{ - Name: "exec-start", - Usage: "absolute path to container start executable", - EnvVars: []string{"LXCRI_START_EXEC"}, - Value: "lxcri-start", - Destination: &clxc.Executables.Start, - }, - &cli.StringFlag{ - Name: "exec-hook", - Usage: "absolute path to container hook executable", - EnvVars: []string{"LXCRI_HOOK_EXEC"}, - Value: "lxcri-hook", - Destination: &clxc.Executables.Hook, + Name: "libexec", + Usage: "directory to load runtime executables from", + EnvVars: []string{"LXCRI_LIBEXEC"}, + Value: libexecDir, + Destination: &clxc.LibexecDir, }, &cli.BoolFlag{ Name: "apparmor", diff --git a/create.go b/create.go index aeb2ef73..87c44913 100644 --- a/create.go +++ b/create.go @@ -56,7 +56,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container // Unsupported runtime features are disabled and a warning message is logged. // CheckSystem should be called (once) before using the Runtime. func (rt *Runtime) CheckSystem() error { - err := canExecute(rt.Executables.Start, rt.Executables.Hook, rt.Executables.Init) + err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) if err != nil { return errorf("access check failed: %w", err) } @@ -199,7 +199,7 @@ func configureContainer(rt *Runtime, c *Container) error { if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { return err } - if err := c.SetConfigItem("lxc.hook.mount", rt.Executables.Hook); err != nil { + if err := c.SetConfigItem("lxc.hook.mount", rt.libexec(ExecHook)); err != nil { return err } diff --git a/init.go b/init.go index 722ed63f..a2459e2a 100644 --- a/init.go +++ b/init.go @@ -88,7 +88,7 @@ func configureInit(rt *Runtime, c *Container) error { } initCmd := filepath.Join(initDir, "init") c.Mounts = append(c.Mounts, specs.Mount{ - Source: rt.Executables.Init, + Source: rt.libexec(ExecInit), Destination: strings.TrimLeft(initCmd, "/"), Type: "bind", Options: []string{"bind", "ro", "nosuid"}, diff --git a/runtime.go b/runtime.go index 49bd2f86..9d9663f6 100644 --- a/runtime.go +++ b/runtime.go @@ -15,9 +15,14 @@ import ( "github.com/drachenfels-de/lxcri/log" ) +// Required runtime executables loaded from Runtime.LibexecDir const ( - // DefaultRuntimeRoot is the path to the default runtime directory. - DefaultRuntimeRoot = "/var/lib/lxcri" + // ExecStart starts the liblxc monitor process, similar to lxc-start + ExecStart = "lxcri-start" + // ExecHook is run as liblxc hook and creates additional devices and remounts masked paths. + ExecHook = "lxcri-hook" + // ExecInit is the container init process that execs the container process. + ExecInit = "lxcri-init" ) var ( @@ -25,15 +30,6 @@ var ( ErrExist = fmt.Errorf("container already exists") ) -// RuntimeExecutables contains names for all (external) executed commands. -// The excutable name is used as path if it contains a slash, otherwise -// the PATH environment variable is consulted to resolve the executable path. -type RuntimeExecutables struct { - Start string - Init string - Hook string -} - // RuntimeTimeouts are timeouts for Runtime API calls. type RuntimeTimeouts struct { Create time.Duration @@ -66,7 +62,6 @@ type Hooks struct { type Runtime struct { // Log is the logger used by the runtime. Log zerolog.Logger - // Root is the file path to the runtime directory. // Directories for containers created by the runtime // are created within this directory. @@ -77,23 +72,22 @@ type Runtime struct { // Path for lxc monitor cgroup (lxc specific feature) // similar to /etc/crio/crio.conf#conmon_cgroup MonitorCgroup string - - Executables RuntimeExecutables - Timeouts RuntimeTimeouts - Features RuntimeFeatures + // LibexecDir is the the directory that contains the runtime executables. + LibexecDir string + // Timeouts are the runtime API command timeouts. + Timeouts RuntimeTimeouts + // + Features RuntimeFeatures Hooks `json:"-"` } var DefaultRuntime = &Runtime{ Log: log.ConsoleLogger(true), - Root: DefaultRuntimeRoot, + Root: "/var/run/lxcri", SystemdCgroup: true, - Executables: RuntimeExecutables{ - Start: "lxcri-start", - Init: "lxcri-init", - Hook: "lxcri-hook", - }, + LibexecDir: "/usr/libexec/lxcri", + Timeouts: RuntimeTimeouts{ Create: time.Second * 60, Start: time.Second * 30, @@ -108,6 +102,10 @@ var DefaultRuntime = &Runtime{ }, } +func (rt *Runtime) libexec(name string) string { + return filepath.Join(rt.LibexecDir, name) +} + // CheckSystem is a wrapper around DefaultRuntime.CheckSystem func CheckSystem() error { return DefaultRuntime.CheckSystem() @@ -167,7 +165,7 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // #nosec - cmd := exec.Command(rt.Executables.Start, c.linuxcontainer.Name(), rt.Root, c.ConfigFilePath()) + cmd := exec.Command(rt.libexec(ExecStart), c.linuxcontainer.Name(), rt.Root, c.ConfigFilePath()) cmd.Env = []string{} cmd.Dir = c.RuntimePath() From d11f95f1d7be4bc4fc9cf7953739fafbf413790a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 14:16:37 +0100 Subject: [PATCH 230/373] Add note about systemd encoded cgroup path. Signed-off-by: Ruben Jenster --- cgroup.go | 1 + cmd/lxcri/cli.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cgroup.go b/cgroup.go index 54d69663..dee53a09 100644 --- a/cgroup.go +++ b/cgroup.go @@ -229,6 +229,7 @@ func configureCPUController(clxc *Runtime, slinux *specs.LinuxCPU) error { // kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod87f8bc68_7c18_4a1d_af9f_54eff815f688.slice // kubepods-burstable-pod9da3b2a14682e1fb23be3c2492753207.slice:crio:fe018d944f87b227b3b7f86226962639020e99eac8991463bf7126ef8e929589 // https://github.com/cri-o/cri-o/issues/2632 +// TODO Where is the systemd cgroup path encoding officially documented? func parseSystemdCgroupPath(s string) string { parts := strings.Split(s, ":") diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index d47ecbbb..aaf7c148 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -132,7 +132,7 @@ func main() { }, &cli.BoolFlag{ Name: "systemd-cgroup", - Usage: "enable systemd cgroup", + Usage: "enable support for systemd encoded cgroup path", Destination: &clxc.SystemdCgroup, }, &cli.StringFlag{ From 4bf747190831e341573fd1e8fb6ee5fc85514702 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 16:27:21 +0100 Subject: [PATCH 231/373] Remove unused ContainerConfig.SpecPath Signed-off-by: Ruben Jenster --- README.md | 2 -- cmd/lxcri/cli.go | 1 - container.go | 12 +++++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b7d415f8..687a7755 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,6 @@ The process environment contains the following variables: * `RUNTIME_CMD` the runtime command which executed the runtime hook * `RUNTIME_PATH` the path to the container runtime directory * `BUNDLE_PATH` the absolute path to the container bundle -* `SPEC_PATH` the absolute path to the the JSON runtime spec * `LOG_FILE` the path to the log file * `RUNTIME_ERROR` (optional) the error message if the runtime cmd return with error @@ -184,7 +183,6 @@ OUT=$LOGDIR/$CONTAINER_ID # backup container runtime directory to log directory cp -r $RUNTIME_PATH $OUT # copy OCI runtime spec to container runtime directory -cp $SPEC_PATH $OUT/spec.json # remove non `grep` friendly runtime files (symlinks, binaries, fifos) rm $OUT/.lxcri/cwd diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index aaf7c148..3d79b573 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -331,7 +331,6 @@ func runCreateHook(err error) { "RUNTIME_CMD=" + clxc.command, "RUNTIME_PATH=" + clxc.containerConfig.RuntimePath(), "BUNDLE_PATH=" + clxc.containerConfig.BundlePath, - "SPEC_PATH=" + clxc.containerConfig.SpecPath, "LOG_FILE=" + clxc.logConfig.FilePath, } if err != nil { diff --git a/container.go b/container.go index de1b8fec..8ec16051 100644 --- a/container.go +++ b/container.go @@ -20,8 +20,6 @@ import ( type ContainerConfig struct { *specs.Spec - SpecPath string - RuntimeDir string ContainerID string @@ -76,9 +74,13 @@ func (cfg ContainerConfig) Pid() (int, error) { } func (c *ContainerConfig) LoadSpecJson(p string) error { - c.SpecPath = p - c.Spec = &specs.Spec{} - return decodeFileJSON(c.Spec, p) + spec := &specs.Spec{} + if err := decodeFileJSON(spec, p); err != nil { + return err + } + c.Spec = spec + return nil + } // Container is the runtime state of a container instance. From abe6220b12bb31bcfcfc5460c6a06e8e40c4a07a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 25 Mar 2021 16:27:53 +0100 Subject: [PATCH 232/373] Update godoc Signed-off-by: Ruben Jenster --- container.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/container.go b/container.go index 8ec16051..a589815c 100644 --- a/container.go +++ b/container.go @@ -28,16 +28,19 @@ type ContainerConfig struct { BundlePath string ConsoleSocket string `json:",omitempty"` - // PidFile is the absolute path to the PID file of the container monitor process (lxcri-start) + // PidFile is the absolute PID file path + // for the container monitor process (ExecStart) PidFile string MonitorCgroupDir string CgroupDir string - // lxc log file and level + // LogFile is the liblxc log file path + LogFile string + // LogLevel is the liblxc log level LogLevel string - LogFile string + // Log is the container Logger Log zerolog.Logger `json:"-"` Hooks `json:"-"` @@ -51,7 +54,7 @@ func (cfg ContainerConfig) syncFifoPath() string { return cfg.RuntimePath(initDir, "syncfifo") } -// RuntimePath returns the absolute path witin the container root +// RuntimePath returns the absolute path within the container root. func (cfg ContainerConfig) RuntimePath(subPath ...string) string { return filepath.Join(cfg.RuntimeDir, filepath.Join(subPath...)) } From ef8df6306baaddc6d906fc41b2483d6466b88c44 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 11:48:26 +0100 Subject: [PATCH 233/373] Improve Dockerfile and installation script. Signed-off-by: Ruben Jenster --- Dockerfile | 33 ++++ deployment/install-lxcri.sh | 25 --- deployment/install-node.sh | 162 ---------------- deployment/old.sh | 11 ++ deployment/ubuntu-install-lxc.sh | 41 ---- deployment/utils.sh | 62 ------- install.sh | 310 +++++++++++++++++++++++++++++++ 7 files changed, 354 insertions(+), 290 deletions(-) create mode 100644 Dockerfile delete mode 100755 deployment/install-lxcri.sh delete mode 100755 deployment/install-node.sh create mode 100644 deployment/old.sh delete mode 100755 deployment/ubuntu-install-lxc.sh delete mode 100755 deployment/utils.sh create mode 100755 install.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..c4ad7043 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +FROM ubuntu:latest +ARG installcmd=install_all + +#ENV PKGS="psmisc util-linux" + +ENV GOLANG_SRC=https://golang.org/dl/go1.16.2.linux-amd64.tar.gz +ENV GOLANG_CHECKSUM=542e936b19542e62679766194364f45141fde55169db2d8d01046555ca9eb4b8 + +ENV CNI_PLUGINS_GIT_REPO=https://github.com/containernetworking/plugins.git +ENV CNI_PLUGINS_GIT_VERSION=v0.9.1 + +ENV CONMON_GIT_REPO=https://github.com/containers/conmon.git +ENV CONMON_GIT_VERSION=v2.0.27 + +ENV CRIO_GIT_REPO=https://github.com/cri-o/cri-o.git +ENV CRIO_GIT_VERSION=v1.20.1 + +ENV CRICTL_CHECKSUM=44d5f550ef3f41f9b53155906e0229ffdbee4b19452b4df540265e29572b899c +ENV CRICTL_URL="https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.20.0/crictl-v1.20.0-linux-amd64.tar.gz" + +# see https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md +ENV K8S_CHECKSUM=37738bc8430b0832f32c6d13cdd68c376417270568cd9b31a1ff37e96cfebcc1e2970c72bed588f626e35ed8273671c77200f0d164e67809b5626a2a99e3c5f5 +ENV K8S_URL="https://dl.k8s.io/v1.20.4/kubernetes-server-linux-amd64.tar.gz" + +## development +ENV LXC_GIT_REPO=https://github.com/lxc/lxc.git +ENV LXC_GIT_VERSION=master + +ENV LXCRI_GIT_REPO=https://github.com/drachenfels-de/lxcri.git +ENV LXCRI_GIT_VERSION=main + +COPY install.sh / +RUN /install.sh ${installcmd} diff --git a/deployment/install-lxcri.sh b/deployment/install-lxcri.sh deleted file mode 100755 index 4f68bf70..00000000 --- a/deployment/install-lxcri.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -eux - -. $(dirname $(readlink -f $0))/utils.sh - -LXCRI_GIT_REPO="${LXCRI_GIT_REPO:-https://github.com/drachenfels-de/lxcri.git}" -LXCRI_GIT_VERSION="${LXCRI_GIT_VERSION:-master}" -LXCRI_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" - -install_crio_lxc() { - local tmpdir=/tmp/lxc - git clone $LXCRI_GIT_REPO $tmpdir - cd $tmpdir - git reset --hard $LXCRI_GIT_VERSION - # lxc installed from source with default installation prefix is prefered - export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH - make install - cd - rm -rf $tmpdir -} - -apt_install $LXCRI_BUILD_DEPS -install_golang -install_crio_lxc -uninstall_golang -apt_clean $LXCRI_BUILD_DEPS diff --git a/deployment/install-node.sh b/deployment/install-node.sh deleted file mode 100755 index f5f441c8..00000000 --- a/deployment/install-node.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh -# enable debug logging -set -x -# abort if subshell command exits non-zero -set -e - -. $(dirname $(readlink -f $0))/utils.sh -CRIO_LXC_BUILD_DEPS="musl musl-tools libc6-dev pkg-config git wget make ca-certificates" - -install_cni() { - local repo="${CNI_PLUGINS_GIT_REPO:-https://github.com/containernetworking/plugins.git}" - local version="${CNI_PLUGINS_GIT_VERSION:-v0.9.1}" - local tmpdir=/tmp/cni-plugins - - git clone $repo $tmpdir - cd $tmpdir - git reset --hard $version - - ./build_linux.sh - export CNI_PLUGIN_DIR=/usr/local/cni/bin - mkdir -p $CNI_PLUGIN_DIR - cp bin/* $CNI_PLUGIN_DIR - - cd / - rm -rf $tmpdir -} - -install_conmon() { - local repo="${CONMON_GIT_REPO:-https://github.com/containers/conmon.git}" - local version="${CONMON_GIT_VERSION:-v2.0.27}" - local tmpdir=/tmp/conmon - - git clone $repo $tmpdir - cd $tmpdir - git reset --hard $version - - make clean - make install - - cd / - rm -rf $tmpdir -} - -install_crio() { - local repo="${CRIO_GIT_REPO:-https://github.com/cri-o/cri-o.git}" - local version="${CRIO_GIT_VERSION:-v1.20.1}" - - local tmpdir=/tmp/cri-o - git clone $repo $tmpdir - cd $tmpdir - git reset --hard $version - - make install - - cd / - rm -rf $tmpdir - - # configure cri-o - PREFIX=/usr/local - CRIO_LXC_ROOT=/run/lxcri - # environment for `crio config` - export CONTAINER_CONMON=${PREFIX}/bin/conmon - export CONTAINER_PINNS_PATH=${PREFIX}/bin/pinns - export CONTAINER_DEFAULT_RUNTIME=lxcri - export CONTAINER_RUNTIMES=lxcri:${PREFIX}/bin/lxcri:$CRIO_LXC_ROOT - export CONTAINER_CNI_PLUGIN_DIR=$CNI_PLUGIN_DIR - - crio config >/etc/crio/crio.conf - - # Modify systemd service file to run with full privileges. - # This is required for the runtime to set cgroupv2 device controller eBPF. - sed -i 's/ExecStart=\//ExecStart=+\//' /usr/local/lib/systemd/system/crio.service -} - -install_cri_tools() { - local release="${CRI_TOOLS_RELEASE:-v1.20.0}" - local checksum="${CRI_TOOLS_CHECKSUM:-44d5f550ef3f41f9b53155906e0229ffdbee4b19452b4df540265e29572b899c}" - local arch="linux-amd64" - local archive="crictl-${release}-${arch}.tar.gz" - local url="https://github.com/kubernetes-sigs/cri-tools/releases/download/$release/$archive" - local destdir="/usr/local/bin" - - cd /tmp - wget --quiet $url - echo "$checksum $archive" | sha256sum -c - tar -x -z -f $archive -C $destdir - rm $archive -} - -install_kubernetes() { - # see https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md - local checksum="${K8S_CHECKSUM:-37738bc8430b0832f32c6d13cdd68c376417270568cd9b31a1ff37e96cfebcc1e2970c72bed588f626e35ed8273671c77200f0d164e67809b5626a2a99e3c5f5}" - local release="${K8S_RELEASE:-v1.20.4}" - local arch="linux-amd64" - # TODO maybe make arch a global variable ${GOHOSTOS}-${GOHOSTARCH} - local archive="kubernetes-server-$arch.tar.gz" - local url="https://dl.k8s.io/${release}/${archive}" - local destdir="/usr/local/bin" - - cd /tmp - wget --quiet $url - echo "$checksum $archive" | sha512sum -c - tar -x -z -f $archive -C $destdir --strip-components=3 \ - kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet - rm $archive - - cat >/etc/systemd/system/kubelet.service <<-EOF - [Unit] - Description=kubelet: The Kubernetes Node Agent - Documentation=http://kubernetes.io/docs/ - - [Service] - ExecStart=$destdir/kubelet - Restart=always - StartLimitInterval=0 - RestartSec=10 - - [Install] - WantedBy=multi-user.target - EOF - - mkdir -p /etc/systemd/system/kubelet.service.d - cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<-EOF - [Service] - Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" - Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" - # This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically - EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env - # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use - # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. - EnvironmentFile=-/etc/default/kubelet - ExecStart= - ExecStart=$destdir/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS - EOF - - #systemctl daemon-reload - systemctl enable kubelet.service -} - -# TODO let install functions append build dependencies and runtime dependencies -BUILD_DEPS_CONMON="libglib2.0-dev" -BUILD_DEPS_CRIO="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev" -BUILD_DEPS="wget git build-essential libtool make automake pkg-config" -BUILD_DEPS="${BUILD_DEPS} ${BUILD_DEPS_CONMON} ${BUILD_DEPS_CRIO}" - -DEPS_CONMON="libglib2.0-0" -DEPS_CRIO="tzdata ca-certificates" -DEPS_K8S="ebtables ethtool socat conntrack iproute2 iptables" -DEPS="$DEPS_CONMON $DEPS_CRIO $DEPS_K8S" -DEPS="$DEPS systemd" - -PKGS="$DEPS $BUILD_DEPS" - -apt_install $PKGS -install_golang -install_cni -install_conmon -install_cri_tools -install_crio -install_kubernetes -uninstall_golang -apt_clean $BUILD_DEPS diff --git a/deployment/old.sh b/deployment/old.sh new file mode 100644 index 00000000..11d1f271 --- /dev/null +++ b/deployment/old.sh @@ -0,0 +1,11 @@ +LXC_PPA=${LXC_PPA:-http://ppa.launchpad.net/ubuntu-lxc/lxc-git-master/ubuntu} +LXC_PPA_KEY=${LXC_PPA_KEY:-93763AC528C8C52568951BE0D5495F657635B973} +LXC_PPA_KEYURL="${LXC_PPA_KEYURL:-http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$LXC_PPA_KEY}" +LXC_PPA_DEPS="curl gnupg2 ca-certificates" + +install_lxc_ppa() { + curl -sSL "$LXC_PPA_KEYURL" | apt-key add - >/dev/null + echo "deb $LXC_PPA $UBUNTU_CODENAME main" >/etc/apt/sources.list.d/lxc-git-master.list + apt-get update + apt_install lxc +} diff --git a/deployment/ubuntu-install-lxc.sh b/deployment/ubuntu-install-lxc.sh deleted file mode 100755 index 4be4bad9..00000000 --- a/deployment/ubuntu-install-lxc.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh -eux - -# see `man 5 os-release` and http://0pointer.de/blog/projects/os-release -. /etc/os-release - -. $(dirname $(readlink -f $0))/utils.sh - -LXC_PPA=${LXC_PPA:-http://ppa.launchpad.net/ubuntu-lxc/lxc-git-master/ubuntu} -LXC_PPA_KEY=${LXC_PPA_KEY:-93763AC528C8C52568951BE0D5495F657635B973} -LXC_PPA_KEYURL="${LXC_PPA_KEYURL:-http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$LXC_PPA_KEY}" -LXC_PPA_DEPS="curl gnupg2 ca-certificates" - -install_lxc_ppa() { - curl -sSL "$LXC_PPA_KEYURL" | apt-key add - >/dev/null - echo "deb $LXC_PPA $UBUNTU_CODENAME main" >/etc/apt/sources.list.d/lxc-git-master.list - apt-get update - apt_install lxc -} - -LXC_BUILD_TOOLS="build-essential libtool automake pkg-config git ca-certificates" -LXC_BUILD_LIBS="libseccomp-dev libapparmor-dev libbtrfs-dev libdevmapper-dev libcap-dev libc6-dev libglib2.0-dev" -LXC_BUILD_DEPS="$LXC_BUILD_TOOLS $LXC_BUILD_LIBS" -LXC_RUNTIME_DEPS="libseccomp2 libapparmor1 libbtrfs0 libdevmapper1.02.1 libcap2" - -case $LXC_INSTALL_FROM in -"git") - apt_install $LXC_BUILD_DEPS $LXC_RUNTIME_DEPS - install_lxc_git - apt_clean $LXC_BUILD_DEPS - ;; -"ppa") - apt_install $LXC_PPA_DEPS - install_lxc_ppa - apt_clean $LXC_PPA_DEPS - ;; -*) - echo "Installation method 'LXC_INSTALL_FROM=$LXC_INSTALL_FROM' is unsupported" >&2 - echo "Supported installation methods are: 'git' and 'ppa'" >&2 - exit 1 - ;; -esac diff --git a/deployment/utils.sh b/deployment/utils.sh deleted file mode 100755 index 68f98c0a..00000000 --- a/deployment/utils.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -export DEBIAN_FRONTEND=noninteractive - -apt_install() { - apt-get update - apt-get install --no-install-recommends --yes $@ -} - -apt_clean() { - apt-get purge --yes $@ - apt-get autoremove --yes - apt-get clean - rm -rf /var/lib/apt/lists/* -} - -GOLANG_SRC="${GOLANG_SRC:-https://golang.org/dl/go1.16.1.linux-amd64.tar.gz}" -GOLANG_CHECKSUM="${GOLANG_CHECKSUM:-3edc22f8332231c3ba8be246f184b736b8d28f06ce24f08168d8ecf052549769}" - -install_golang() { - local archive="$(basename $GOLANG_SRC)" - local destdir="/tmp" - - cd $destdir - wget --quiet $GOLANG_SRC - echo "$GOLANG_CHECKSUM $archive" | sha256sum -c - tar -xzf $archive - export PATH=$destdir/go/bin:$PATH - rm $destdir/$archive -} - -uninstall_golang() { - rm -rf $(go env GOPATH) - rm -rf $(go env GOCACHE) - rm -rf $(go env GOROOT) -} - -LXC_GIT_REPO="${LXC_GIT_REPO:-https://github.com/lxc/lxc.git}" -LXC_GIT_VERSION="${LXC_GIT_VERSION:-master}" - -LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} -LXC_INSTALL_COMMANDS=${LXC_INSTALL_COMMANDS:-no} -LXC_INSTALL_DOC=${LXC_INSTALL_DOC:-no} -LXC_INSTALL_API_DOCS=${LXC_INSTALL_API_DOCS:-no} - -install_lxc_git() { - local tmpdir=/tmp/lxc - git clone $LXC_GIT_REPO $tmpdir - cd $tmpdir - git reset --hard $LXC_GIT_VERSION - ./autogen.sh - ./configure --enable-bash=no --enable-seccomp=yes \ - --enable-capabilities=yes --enable-apparmor=yes \ - --enable-tools=$LXC_INSTALL_TOOLS --enable-commands=$LXC_INSTALL_COMMANDS \ - --enable-static=no --enable-examples=no \ - --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS - make install - git describe --tags >/usr/local/lib/liblxc.version.txt - echo /usr/local/lib >>/etc/ld.so.conf.d/local.conf - ldconfig - cd - rm -rf $tmpdir -} diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..7dd01a21 --- /dev/null +++ b/install.sh @@ -0,0 +1,310 @@ +#!/bin/sh -eux +# -e abort if subshell command exits non-zero +# -u treat undefined variables as error +# -x trace shell expansion + +# Package manager dependencies +# NOTE sort lists with: $(echo $PKGS | tr ' ' '\n' | sort | uniq | xargs) + +DISTRIBUTION="$(cat /etc/os-release | grep '^ID=' | cut -d'=' -f2 | tr -d '\n')" +INSTALL_PREFIX=${INSTALL_PREFIX:-/usr/local} +TMPDIR=${TMPDIR:-/tmp/lxcri-build} + +case "$DISTRIBUTION" in +"debian" | "ubuntu") + INSTALL_PKGS=apt_install + CLEAN_PKGS=apt_clean + + export DEBIAN_FRONTEND=noninteractive + + PKGS_BUILD="automake build-essential ca-certificates git libc6-dev libtool make musl musl-tools pkg-config wget" + PKGS_BUILD="$PKGS_BUILD libapparmor-dev libbtrfs-dev libc6-dev libcap-dev libdevmapper-dev libglib2.0-dev libseccomp-dev" + + PKGS_RUNTIME="libapparmor1 libbtrfs0 libcap2 libdevmapper1.02.1 libseccomp2" + PKGS="conntrack ebtables ethtool iproute2 iptables socat" + PKGS="$PKGS ca-certificates libglib2.0-0 systemd tzdata" + PKGS="$PKGS $PKGS_RUNTIME" + ;; +"arch") + INSTALL_PKGS=pacman_install + CLEAN_PKGS=pacman_clean + + BUILD_PKGS="" + BUILD_PKGS="$PKGS_PKGS " + + PKGS_RUNTIME="" + PKGS="" + PKGS="$PKGS " + PKGS="$PKGS $PKGS_RUNTIME" + ;; +*) + echo "unsupported distribution '$DISTRIBUTION'" + exit 1 + ;; +esac + +mkdir -p $TMPDIR +export PATH=${INSTALL_PREFIX}/go/bin:$PATH + +setup() { + $INSTALL_PKGS $@ + add_golang +} + +clean() { + $CLEAN_PKGS $PKGS_BUILD + remove_golang + rm -rf $TMPDIR +} + +apt_install() { + apt-get update + apt-get install -qq --no-install-recommends --yes $@ +} + +apt_clean() { + apt-get purge -qq --yes $@ + apt-get autoremove -qq --yes + apt-get clean -qq + rm -rf /var/lib/apt/lists/* +} + +pacman_install() { + echo "not implemented" + exit 1 +} + +pacman_clean() { + echo "not implemented" + exit 1 +} + +add_golang() { + local src=$GOLANG_SRC + local checksum=$GOLANG_CHECKSUM + local archive="$(basename $src)" + + cd ${INSTALL_PREFIX} + wget --quiet $src + echo "$checksum $archive" | sha256sum -c + tar -xzf $archive + rm ${INSTALL_PREFIX}/$archive +} + +remove_golang() { + rm -rf $(go env GOPATH) + rm -rf $(go env GOCACHE) + rm -rf $(go env GOROOT) +} + +git_clone() { + local tmpdir=$1 + local repo=$2 + local version=$3 + + git clone $repo $tmpdir + cd $tmpdir + git reset --hard $version +} + +add_cni() { + local repo=$CNI_PLUGINS_GIT_REPO + local version=$CNI_PLUGINS_GIT_VERSION + local tmpdir=${TMPDIR}/cni-plugins + + git_clone $tmpdir $repo $version + + ./build_linux.sh + export CNI_PLUGIN_DIR=$INSTALL_PREFIX/cni/bin + mkdir -p $CNI_PLUGIN_DIR + cp bin/* $CNI_PLUGIN_DIR + + cd / + rm -rf $tmpdir +} + +add_conmon() { + local repo=$CONMON_GIT_REPO + local version=$CONMON_GIT_VERSION + local tmpdir=${TMPDIR}/conmon + + git_clone $tmpdir $repo $version + + make clean + make install + + cd / + rm -rf $tmpdir +} + +add_crio() { + local repo=$CRIO_GIT_REPO + local version=$CRIO_GIT_VERSION + local tmpdir=${TMPDIR}/cri-o + + git_clone $tmpdir $repo $version + + make install + + cd / + rm -rf $tmpdir + + # Modify systemd service file to run with full privileges. + # This is required for the runtime to set cgroupv2 device controller eBPF. + sed -i 's/ExecStart=\//ExecStart=+\//' ${INSTALL_PREFIX}/lib/systemd/system/crio.service + + # TODO modify defaults file +} + +add_crictl() { + local checksum=$CRICTL_CHECKSUM + local url=$CRICTL_URL + local archive="$(basename $CRICTL_URL)" + + cd ${TMPDIR} + wget --quiet $url + echo "$checksum $archive" | sha256sum -c + tar -x -z -f $archive -C ${INSTALL_PREFIX}/bin + rm $archive +} + +add_kubernetes() { + local checksum=$K8S_CHECKSUM + local url=$K8S_URL + local archive=$(basename $K8S_URL) + + cd ${TMPDIR} + wget --quiet $url + echo "$checksum $archive" | sha512sum -c + tar -x -z -f $archive -C $INSTALL_PREFIX/bin --strip-components=3 \ + kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet + rm $archive + + cat >/etc/systemd/system/kubelet.service <<-EOF + [Unit] + Description=kubelet: The Kubernetes Node Agent + Documentation=http://kubernetes.io/docs/ + + [Service] + ExecStart=${INSTALL_PREFIX}/kubelet + Restart=always + StartLimitInterval=0 + RestartSec=10 + + [Install] + WantedBy=multi-user.target + EOF + + mkdir -p /etc/systemd/system/kubelet.service.d + cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<-EOF + [Service] + Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" + Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" + # This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically + EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env + # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use + # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. + EnvironmentFile=-/etc/default/kubelet + ExecStart= + ExecStart=${INSTALL_PREFIX}/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS + EOF + + #systemctl daemon-reload + systemctl enable kubelet.service +} + +LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} +LXC_INSTALL_COMMANDS=${LXC_INSTALL_COMMANDS:-no} +LXC_INSTALL_DOC=${LXC_INSTALL_DOC:-no} +LXC_INSTALL_API_DOCS=${LXC_INSTALL_API_DOCS:-no} + +add_lxc() { + local repo=$LXC_GIT_REPO + local version=$LXC_GIT_VERSION + local tmpdir=${TMPDIR}/lxc + + git_clone $tmpdir $repo $version + + ./autogen.sh + ./configure --enable-bash=no --enable-seccomp=yes \ + --enable-capabilities=yes --enable-apparmor=yes \ + --enable-tools=$LXC_INSTALL_TOOLS --enable-commands=$LXC_INSTALL_COMMANDS \ + --enable-static=no --enable-examples=no \ + --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS + make install + git describe --tags >${INSTALL_PREFIX}/lib/liblxc.version.txt + echo ${INSTALL_PREFIX}/lib >>/etc/ld.so.conf.d/local.conf + ldconfig + + cd + rm -rf $tmpdir +} + +add_lxcri() { + local repo=$LXCRI_GIT_REPO + local version=$LXCRI_GIT_VERSION + local tmpdir=${TMPDIR}/lxcri + + git_clone $tmpdir $repo $version + + # lxc installed from source with default installation prefix is prefered + export PKG_CONFIG_PATH=${INSTALL_PREFIX}/lib/pkgconfig + make install + + cd + rm -rf $tmpdir +} + +configure_runtime() { + # TODO configure runtime using 'lxcri {flags} config' + CRIO_LXC_ROOT=/run/lxcri + # configure cri-o + # environment for `crio config` + export CONTAINER_CONMON=${INSTALL_PREFIX}/bin/conmon + export CONTAINER_PINNS_PATH=${INSTALL_PREFIX}/bin/pinns + export CONTAINER_DEFAULT_RUNTIME=lxcri + export CONTAINER_RUNTIMES=lxcri:${INSTALL_PREFIX}/bin/lxcri:$CRIO_LXC_ROOT + export CONTAINER_CNI_PLUGIN_DIR=$CNI_PLUGIN_DIR + + crio config >/etc/crio/crio.conf +} + +install_all_noclean() { + setup $PKGS_BUILD $PKGS + add_crictl + add_kubernetes + add_cni + add_conmon + add_crio + add_lxc + add_lxcri +} + +install_all() { + install_all_noclean + clean +} + +install_runtime_noclean() { + setup $PKGS_BUILD $PKGS_RUNTIME + add_lxc + add_lxcri +} + +install_runtime() { + install_runtime_noclean + clean +} + +update_runtime() { + add_lxc + add_lxcri + clean +} + +update_lxcri() { + add_lxcri + clean +} + +$@ From 0e72fe4713ffd7e3eb5d90d09964f5342073e89f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 16:44:47 +0100 Subject: [PATCH 234/373] cli: Fix nil pointer in delete cmd Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 3d79b573..102621a2 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -467,6 +467,9 @@ func doDelete(ctx *cli.Context) error { clxc.Log.Info().Msg("container does not exist") return nil } + if err != nil { + return err + } return clxc.Delete(context.Background(), c, ctx.Bool("force")) } From c94411624b1d82c9e764aadd3900622f975d3224 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 23:47:51 +0100 Subject: [PATCH 235/373] Fix checksum format for busybox sha*sum Signed-off-by: Ruben Jenster --- install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 7dd01a21..3f789498 100755 --- a/install.sh +++ b/install.sh @@ -86,7 +86,7 @@ add_golang() { cd ${INSTALL_PREFIX} wget --quiet $src - echo "$checksum $archive" | sha256sum -c + echo "$checksum $archive" | sha256sum -c tar -xzf $archive rm ${INSTALL_PREFIX}/$archive } @@ -163,7 +163,7 @@ add_crictl() { cd ${TMPDIR} wget --quiet $url - echo "$checksum $archive" | sha256sum -c + echo "$checksum $archive" | sha256sum -c tar -x -z -f $archive -C ${INSTALL_PREFIX}/bin rm $archive } @@ -175,7 +175,7 @@ add_kubernetes() { cd ${TMPDIR} wget --quiet $url - echo "$checksum $archive" | sha512sum -c + echo "$checksum $archive" | sha512sum -c tar -x -z -f $archive -C $INSTALL_PREFIX/bin --strip-components=3 \ kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet rm $archive From 4c1b3ac3f439335c1711eab7b2c6d6c9da149148 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 23:49:32 +0100 Subject: [PATCH 236/373] Remove crio/kubelet configuration from installation script. Signed-off-by: Ruben Jenster --- install.sh | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/install.sh b/install.sh index 3f789498..2475700a 100755 --- a/install.sh +++ b/install.sh @@ -179,38 +179,6 @@ add_kubernetes() { tar -x -z -f $archive -C $INSTALL_PREFIX/bin --strip-components=3 \ kubernetes/server/bin/kubectl kubernetes/server/bin/kubeadm kubernetes/server/bin/kubelet rm $archive - - cat >/etc/systemd/system/kubelet.service <<-EOF - [Unit] - Description=kubelet: The Kubernetes Node Agent - Documentation=http://kubernetes.io/docs/ - - [Service] - ExecStart=${INSTALL_PREFIX}/kubelet - Restart=always - StartLimitInterval=0 - RestartSec=10 - - [Install] - WantedBy=multi-user.target - EOF - - mkdir -p /etc/systemd/system/kubelet.service.d - cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<-EOF - [Service] - Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" - Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" - # This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically - EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env - # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use - # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. - EnvironmentFile=-/etc/default/kubelet - ExecStart= - ExecStart=${INSTALL_PREFIX}/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS - EOF - - #systemctl daemon-reload - systemctl enable kubelet.service } LXC_INSTALL_TOOLS=${LXC_INSTALL_TOOLS:-no} @@ -255,20 +223,6 @@ add_lxcri() { rm -rf $tmpdir } -configure_runtime() { - # TODO configure runtime using 'lxcri {flags} config' - CRIO_LXC_ROOT=/run/lxcri - # configure cri-o - # environment for `crio config` - export CONTAINER_CONMON=${INSTALL_PREFIX}/bin/conmon - export CONTAINER_PINNS_PATH=${INSTALL_PREFIX}/bin/pinns - export CONTAINER_DEFAULT_RUNTIME=lxcri - export CONTAINER_RUNTIMES=lxcri:${INSTALL_PREFIX}/bin/lxcri:$CRIO_LXC_ROOT - export CONTAINER_CNI_PLUGIN_DIR=$CNI_PLUGIN_DIR - - crio config >/etc/crio/crio.conf -} - install_all_noclean() { setup $PKGS_BUILD $PKGS add_crictl From 1af54ad119ef91367a8c7539357a0aad7dd67dd3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 23:50:01 +0100 Subject: [PATCH 237/373] Add basic alpine linux support. Signed-off-by: Ruben Jenster --- install.sh | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 2475700a..1193774f 100755 --- a/install.sh +++ b/install.sh @@ -37,6 +37,20 @@ case "$DISTRIBUTION" in PKGS="$PKGS " PKGS="$PKGS $PKGS_RUNTIME" ;; +"alpine") + INSTALL_PKGS=apk_install + CLEAN_PKGS=apk_clean + + PKGS_BUILD="build-base wget git libtool m4 automake autoconf" + PKGS_BUILD="$PKGS_BUILD btrfs-progs-dev glib-dev libseccomp-dev libcap-dev libapparmor-dev" + + PKGS_RUNTIME="libapparmor btrfs-progs libcap lvm2-dev libseccomp libc6-compat libgcc" + PKGS="conntrack-tools ebtables ethtool iproute2 iptables ip6tables socat" + PKGS="$PKGS ca-certificates glib runit tzdata" + PKGS="$PKGS $PKGS_RUNTIME" + + export MUSL_CC="cc" + ;; *) echo "unsupported distribution '$DISTRIBUTION'" exit 1 @@ -79,6 +93,27 @@ pacman_clean() { exit 1 } +apk_install() { + echo http://nl.alpinelinux.org/alpine/edge/testing >>/etc/apk/repositories + echo http://nl.alpinelinux.org/alpine/edge/community >>/etc/apk/repositories + apk add --no-cache --update $@ +} + +apk_clean() { + apk del $@ +} + +ldconfig_add() { + if $(which ldconfig 1>/dev/null 2>&1); then + echo $1 >>/etc/ld.so.conf.d/local.conf + ldconfig + fi + # alpine uses musl libc + # /etc/ld-musl-x86_64.path (shared library search path, with components delimited by newlines or colons) + # default "/lib:/usr/local/lib:/usr/lib" + # see musl-libc.org/doc/1.0.0/manual.html +} + add_golang() { local src=$GOLANG_SRC local checksum=$GOLANG_CHECKSUM @@ -201,9 +236,8 @@ add_lxc() { --enable-doc=$LXC_INSTALL_DOC --enable-api-docs=$LXC_INSTALL_API_DOCS make install git describe --tags >${INSTALL_PREFIX}/lib/liblxc.version.txt - echo ${INSTALL_PREFIX}/lib >>/etc/ld.so.conf.d/local.conf - ldconfig + ldconfig_add ${INSTALL_PREFIX}/lib cd rm -rf $tmpdir } From 6cb87b8be6e5aa17e26be0b7a224cba003541842 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 27 Mar 2021 23:51:13 +0100 Subject: [PATCH 238/373] Build lxc and lxcri first to fail fast. Signed-off-by: Ruben Jenster --- install.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/install.sh b/install.sh index 1193774f..b8e70ff4 100755 --- a/install.sh +++ b/install.sh @@ -259,13 +259,13 @@ add_lxcri() { install_all_noclean() { setup $PKGS_BUILD $PKGS - add_crictl - add_kubernetes - add_cni - add_conmon - add_crio add_lxc add_lxcri + add_conmon + add_crio + add_cni + add_crictl + add_kubernetes } install_all() { @@ -291,6 +291,12 @@ update_runtime() { } update_lxcri() { + setup $PKGS_BUILD $PKGS_RUNTIME + add_lxcri + clean +} + +update_lxcri_dev() { add_lxcri clean } From a96efaf197b95e4cdbdc4e41da7786811c584a2a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 28 Mar 2021 10:25:46 +0200 Subject: [PATCH 239/373] Move runStartCmdConsole back to runtime.go Signed-off-by: Ruben Jenster --- create.go | 46 ---------------------------------------------- runtime.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/create.go b/create.go index 87c44913..cdd45304 100644 --- a/create.go +++ b/create.go @@ -3,15 +3,11 @@ package lxcri import ( "context" "fmt" - "net" "os" - "os/exec" "path/filepath" "strings" - "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/sys/unix" "gopkg.in/lxc/go-lxc.v2" ) @@ -324,45 +320,3 @@ func writeMasked(dst string, c *Container) error { } return f.Close() } - -func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string) error { - dialer := net.Dialer{} - c, err := dialer.DialContext(ctx, "unix", consoleSocket) - if err != nil { - return fmt.Errorf("connecting to console socket failed: %w", err) - } - defer c.Close() - - conn, ok := c.(*net.UnixConn) - if !ok { - return fmt.Errorf("expected a unix connection but was %T", conn) - } - - if deadline, ok := ctx.Deadline(); ok { - err = conn.SetDeadline(deadline) - if err != nil { - return fmt.Errorf("failed to set connection deadline: %w", err) - } - } - - sockFile, err := conn.File() - if err != nil { - return fmt.Errorf("failed to get file from unix connection: %w", err) - } - ptmx, err := pty.Start(cmd) - if err != nil { - return fmt.Errorf("failed to start with pty: %w", err) - } - - // Send the pty file descriptor over the console socket (to the 'conmon' process) - // For technical backgrounds see: - // * `man sendmsg 2`, `man unix 3`, `man cmsg 1` - // * https://blog.cloudflare.com/know-your-scm_rights/ - oob := unix.UnixRights(int(ptmx.Fd())) - // Don't know whether 'terminal' is the right data to send, but conmon doesn't care anyway. - err = unix.Sendmsg(int(sockFile.Fd()), []byte("terminal"), oob, nil, 0) - if err != nil { - return fmt.Errorf("failed to send console fd: %w", err) - } - return ptmx.Close() -} diff --git a/runtime.go b/runtime.go index 9d9663f6..b2749251 100644 --- a/runtime.go +++ b/runtime.go @@ -3,11 +3,13 @@ package lxcri import ( "context" "fmt" + "net" "os" "os/exec" "path/filepath" "time" + "github.com/creack/pty" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" @@ -218,6 +220,48 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { return CreatePidFile(c.PidFile, cmd.Process.Pid) } +func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string) error { + dialer := net.Dialer{} + c, err := dialer.DialContext(ctx, "unix", consoleSocket) + if err != nil { + return fmt.Errorf("connecting to console socket failed: %w", err) + } + defer c.Close() + + conn, ok := c.(*net.UnixConn) + if !ok { + return fmt.Errorf("expected a unix connection but was %T", conn) + } + + if deadline, ok := ctx.Deadline(); ok { + err = conn.SetDeadline(deadline) + if err != nil { + return fmt.Errorf("failed to set connection deadline: %w", err) + } + } + + sockFile, err := conn.File() + if err != nil { + return fmt.Errorf("failed to get file from unix connection: %w", err) + } + ptmx, err := pty.Start(cmd) + if err != nil { + return fmt.Errorf("failed to start with pty: %w", err) + } + + // Send the pty file descriptor over the console socket (to the 'conmon' process) + // For technical backgrounds see: + // * `man sendmsg 2`, `man unix 3`, `man cmsg 1` + // * https://blog.cloudflare.com/know-your-scm_rights/ + oob := unix.UnixRights(int(ptmx.Fd())) + // Don't know whether 'terminal' is the right data to send, but conmon doesn't care anyway. + err = unix.Sendmsg(int(sockFile.Fd()), []byte("terminal"), oob, nil, 0) + if err != nil { + return fmt.Errorf("failed to send console fd: %w", err) + } + return ptmx.Close() +} + func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) error { ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Kill) defer cancel() From 1c8f9ebafab6bd65f7255411089e536a58a07e7d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 28 Mar 2021 11:28:01 +0200 Subject: [PATCH 240/373] Serialize container monitor process PID. Moved pidfile handling from runtime to cli. Pidfile is managed/monitored by conmon and only required for the cli. Save PID of lxcri-start (liblxc monitor) process to Container on Create and serialize Container along with the ContainerConfig. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 16 +++++--- cmd/lxcri/utils.go | 36 ++++++++++++++++++ container.go | 95 ++++++++++++++++++++-------------------------- create.go | 4 +- runtime.go | 27 +++++++------ utils.go | 25 ------------ 6 files changed, 107 insertions(+), 96 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 102621a2..444edb09 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -279,9 +279,8 @@ var createCmd = cli.Command{ Destination: &clxc.containerConfig.ConsoleSocket, }, &cli.StringFlag{ - Name: "pid-file", - Usage: "path to write container PID", - Destination: &clxc.containerConfig.PidFile, + Name: "pid-file", + Usage: "path to write container PID", }, &cli.DurationFlag{ Name: "timeout", @@ -307,7 +306,7 @@ var createCmd = cli.Command{ }, } -func doCreate(unused *cli.Context) error { +func doCreate(ctx *cli.Context) error { if err := clxc.CheckSystem(); err != nil { return err } @@ -316,10 +315,17 @@ func doCreate(unused *cli.Context) error { if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } + pidFile := ctx.String("pid-file") c, err := clxc.Create(context.Background(), &clxc.containerConfig) if err == nil { defer c.Release() } + if err == nil && pidFile != "" { + err = createPidFile(pidFile, c.Pid) + if err != nil { + return err + } + } runCreateHook(err) return err } @@ -553,7 +559,7 @@ func doExec(ctx *cli.Context) error { return err } if pidFile != "" { - return lxcri.CreatePidFile(pidFile, pid) + return createPidFile(pidFile, pid) } } else { status, err := c.Exec(args, procSpec) diff --git a/cmd/lxcri/utils.go b/cmd/lxcri/utils.go index 8239aadd..ffff6797 100644 --- a/cmd/lxcri/utils.go +++ b/cmd/lxcri/utils.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "strconv" "strings" @@ -95,3 +96,38 @@ func logEnv(log *zerolog.Log) } */ + +// createPidFile atomically creates a pid file for the given pid at the given path +func createPidFile(path string, pid int) error { + tmpDir := filepath.Dir(path) + tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) + + // #nosec + f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0600) + if err != nil { + return fmt.Errorf("failed to create temporary PID file %q: %w", tmpName, err) + } + _, err = fmt.Fprintf(f, "%d", pid) + if err != nil { + return fmt.Errorf("failed to write to temporary PID file %q: %w", tmpName, err) + } + err = f.Close() + if err != nil { + return fmt.Errorf("failed to close temporary PID file %q: %w", tmpName, err) + } + err = os.Rename(tmpName, path) + if err != nil { + return fmt.Errorf("failed to rename temporary PID file %q to %q: %w", tmpName, path, err) + } + return nil +} + +func readPidFile(path string) (int, error) { + // #nosec + data, err := ioutil.ReadFile(path) + if err != nil { + return 0, err + } + s := strings.TrimSpace(string(data)) + return strconv.Atoi(s) +} diff --git a/container.go b/container.go index a589815c..98cf7450 100644 --- a/container.go +++ b/container.go @@ -23,14 +23,12 @@ type ContainerConfig struct { RuntimeDir string ContainerID string - CreatedAt time.Time BundlePath string ConsoleSocket string `json:",omitempty"` // PidFile is the absolute PID file path // for the container monitor process (ExecStart) - PidFile string MonitorCgroupDir string CgroupDir string @@ -66,16 +64,6 @@ func (cfg ContainerConfig) runtimeDirExists() bool { return false } -func (cfg ContainerConfig) Pid() (int, error) { - // #nosec - data, err := ioutil.ReadFile(cfg.PidFile) - if err != nil { - return 0, err - } - s := strings.TrimSpace(string(data)) - return strconv.Atoi(s) -} - func (c *ContainerConfig) LoadSpecJson(p string) error { spec := &specs.Spec{} if err := decodeFileJSON(spec, p); err != nil { @@ -90,6 +78,9 @@ func (c *ContainerConfig) LoadSpecJson(p string) error { type Container struct { linuxcontainer *lxc.Container `json:"-"` *ContainerConfig + + CreatedAt time.Time + Pid int } func (c *Container) create() error { @@ -124,7 +115,7 @@ func (c *Container) load() error { return ErrNotExist } - err := decodeFileJSON(&c.ContainerConfig, c.RuntimePath("container.json")) + err := decodeFileJSON(c, c.RuntimePath("container.json")) if err != nil { return fmt.Errorf("failed to load container config: %w", err) } @@ -199,11 +190,6 @@ func (c *Container) wait(ctx context.Context, state lxc.State) bool { } func (c *Container) State() (*specs.State, error) { - pid, err := c.Pid() - if err != nil { - return nil, errorf("failed to load pidfile: %w", err) - } - status, err := c.ContainerState() if err != nil { return nil, errorf("failed go get container status: %w", err) @@ -213,7 +199,7 @@ func (c *Container) State() (*specs.State, error) { Version: specs.Version, ID: c.ContainerID, Bundle: c.BundlePath, - Pid: pid, + Pid: c.Pid, Annotations: c.Annotations, Status: status, } @@ -263,44 +249,48 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { func (c *Container) kill(ctx context.Context, signum unix.Signal) error { c.Log.Info().Int("signum", int(signum)).Msg("killing container process") if signum == unix.SIGKILL || signum == unix.SIGTERM { - if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { - return err - } - if err := c.linuxcontainer.Stop(); err != nil { - return err - } - - if !c.wait(ctx, lxc.STOPPED) { - c.Log.Warn().Msg("failed to stop lxc container") + return c.stop(ctx, signum) + } + + // Send non-terminating signals to monitor process. + // The monitor process propagates the signal to all container process. + // FIXME revise this, it may be prone to race-conditions, + /// the monitor process PID could have been recycled + // Maybe use c.lxccontainer.InitPidFd() ? + if c.Pid > 1 { + c.Log.Info().Int("pid", c.Pid).Int("signal", int(signum)).Msg("sending signal") + if err := unix.Kill(c.Pid, 0); err == nil { + err := unix.Kill(c.Pid, signum) + if err != unix.ESRCH { + return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, c.Pid, err) + } } + } + return nil +} - // draining the cgroup is required to catch processes that escaped from - // 'kill' e.g a bash for loop that spawns a new child immediately. - start := time.Now() - err := drainCgroup(ctx, c.CgroupDir, signum) - if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") - } else { - c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") - } +func (c *Container) stop(ctx context.Context, signum unix.Signal) error { + if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { + return err + } + if err := c.linuxcontainer.Stop(); err != nil { return err } - // send non-terminating signals to monitor process - pid, err := c.Pid() - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load pidfile: %w", err) + if !c.wait(ctx, lxc.STOPPED) { + c.Log.Warn().Msg("failed to stop lxc container") } - if pid > 1 { - c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - if err := unix.Kill(pid, 0); err == nil { - err := unix.Kill(pid, signum) - if err != unix.ESRCH { - return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) - } - } + + // draining the cgroup is required to catch processes that escaped from + // 'kill' e.g a bash for loop that spawns a new child immediately. + start := time.Now() + err := drainCgroup(ctx, c.CgroupDir, signum) + if err != nil && !os.IsNotExist(err) { + c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") + } else { + c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") } - return nil + return err } // SaveConfig creates and atomically enables the lxc config file. @@ -325,10 +315,7 @@ func (c *Container) saveConfig() error { if err := os.Rename(tmpFile, cfgFile); err != nil { return fmt.Errorf("failed to rename config file: %w", err) } - - p := c.RuntimePath("container.json") - c.CreatedAt = time.Now() - return encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + return nil } func (c *Container) GetConfigItem(key string) string { diff --git a/create.go b/create.go index cdd45304..c3663aa4 100644 --- a/create.go +++ b/create.go @@ -45,7 +45,9 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to run container process: %w", err) } - return c, nil + p := c.RuntimePath("container.json") + err := encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + return c, err } // CheckSystem checks the hosts system configuration. diff --git a/runtime.go b/runtime.go index b2749251..f7b5f0fc 100644 --- a/runtime.go +++ b/runtime.go @@ -200,16 +200,18 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { ctx, cancel := context.WithCancel(ctx) defer cancel() - go func() { - // NOTE this goroutine may leak until lxcri-start is terminated - ps, err := cmd.Process.Wait() - if err != nil { - rt.Log.Error().Err(err).Msg("failed to wait for start process") - } else { - rt.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") - } - cancel() - }() + /* + go func() { + // NOTE this goroutine may leak until lxcri-start is terminated + ps, err := cmd.Process.Wait() + if err != nil { + rt.Log.Error().Err(err).Msg("failed to wait for start process") + } else { + rt.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") + } + cancel() + }() + */ rt.Log.Debug().Msg("waiting for init") if err := c.waitCreated(ctx); err != nil { @@ -217,7 +219,10 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { } rt.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") - return CreatePidFile(c.PidFile, cmd.Process.Pid) + // FIXME set PID to container config ? + c.CreatedAt = time.Now() + c.Pid = cmd.Process.Pid + return nil } func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string) error { diff --git a/utils.go b/utils.go index f6cf02ff..a109ea9c 100644 --- a/utils.go +++ b/utils.go @@ -12,31 +12,6 @@ import ( "golang.org/x/sys/unix" ) -// createPidFile atomically creates a pid file for the given pid at the given path -func CreatePidFile(path string, pid int) error { - tmpDir := filepath.Dir(path) - tmpName := filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path))) - - // #nosec - f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0600) - if err != nil { - return fmt.Errorf("failed to create temporary PID file %q: %w", tmpName, err) - } - _, err = fmt.Fprintf(f, "%d", pid) - if err != nil { - return fmt.Errorf("failed to write to temporary PID file %q: %w", tmpName, err) - } - err = f.Close() - if err != nil { - return fmt.Errorf("failed to close temporary PID file %q: %w", tmpName, err) - } - err = os.Rename(tmpName, path) - if err != nil { - return fmt.Errorf("failed to rename temporary PID file %q to %q: %w", tmpName, path, err) - } - return nil -} - func canExecute(cmds ...string) error { for _, c := range cmds { if err := unix.Access(c, unix.X_OK); err != nil { From 219d3117ec82f137c237b0b470d464ee7f10732f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 28 Mar 2021 17:22:28 +0200 Subject: [PATCH 241/373] Export lxc.Container again. Signed-off-by: Ruben Jenster --- container.go | 38 +++++++++++++++++++------------------- runtime.go | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/container.go b/container.go index 98cf7450..f8aafaab 100644 --- a/container.go +++ b/container.go @@ -76,7 +76,7 @@ func (c *ContainerConfig) LoadSpecJson(p string) error { // Container is the runtime state of a container instance. type Container struct { - linuxcontainer *lxc.Container `json:"-"` + LinuxContainer *lxc.Container `json:"-"` *ContainerConfig CreatedAt time.Time @@ -102,7 +102,7 @@ func (c *Container) create() error { return fmt.Errorf("failed to close empty config tmpfile: %w", err) } - c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) if err != nil { return err } @@ -124,12 +124,12 @@ func (c *Container) load() error { if err != nil { return fmt.Errorf("failed to load lxc config file: %w", err) } - c.linuxcontainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) if err != nil { return fmt.Errorf("failed to create lxc container: %w", err) } - err = c.linuxcontainer.LoadConfigFile(c.ConfigFilePath()) + err = c.LinuxContainer.LoadConfigFile(c.ConfigFilePath()) if err != nil { return fmt.Errorf("failed to load config file: %w", err) } @@ -142,7 +142,7 @@ func (c *Container) waitCreated(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() default: - state := c.linuxcontainer.State() + state := c.LinuxContainer.State() if !(state == lxc.RUNNING) { c.Log.Debug().Stringer("state", state).Msg("wait for state lxc.RUNNING") time.Sleep(time.Millisecond * 100) @@ -181,7 +181,7 @@ func (c *Container) wait(ctx context.Context, state lxc.State) bool { case <-ctx.Done(): return false default: - if c.linuxcontainer.State() == state { + if c.LinuxContainer.State() == state { return true } time.Sleep(time.Millisecond * 100) @@ -207,7 +207,7 @@ func (c *Container) State() (*specs.State, error) { } func (c *Container) ContainerState() (specs.ContainerState, error) { - state := c.linuxcontainer.State() + state := c.LinuxContainer.State() switch state { case lxc.STOPPED: return specs.StateStopped, nil @@ -224,7 +224,7 @@ func (c *Container) ContainerState() (specs.ContainerState, error) { // This should be called if the container is in state lxc.RUNNING. // On error the caller should call getContainerState() again func (c *Container) getContainerInitState() (specs.ContainerState, error) { - initPid := c.linuxcontainer.InitPid() + initPid := c.LinuxContainer.InitPid() if initPid < 1 { return specs.StateStopped, nil } @@ -273,7 +273,7 @@ func (c *Container) stop(ctx context.Context, signum unix.Signal) error { if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { return err } - if err := c.linuxcontainer.Stop(); err != nil { + if err := c.LinuxContainer.Stop(); err != nil { return err } @@ -308,7 +308,7 @@ func (c *Container) saveConfig() error { if _, err := os.Stat(cfgFile); err == nil { return fmt.Errorf("config file %s already exists", cfgFile) } - err := c.linuxcontainer.SaveConfigFile(tmpFile) + err := c.LinuxContainer.SaveConfigFile(tmpFile) if err != nil { return fmt.Errorf("failed to save config file to %q: %w", tmpFile, err) } @@ -319,7 +319,7 @@ func (c *Container) saveConfig() error { } func (c *Container) GetConfigItem(key string) string { - vals := c.linuxcontainer.ConfigItem(key) + vals := c.LinuxContainer.ConfigItem(key) if len(vals) > 0 { first := vals[0] // some lxc config values are set to '(null)' if unset @@ -332,7 +332,7 @@ func (c *Container) GetConfigItem(key string) string { } func (c *Container) SetConfigItem(key, value string) error { - err := c.linuxcontainer.SetConfigItem(key, value) + err := c.LinuxContainer.SetConfigItem(key, value) if err != nil { return fmt.Errorf("failed to set config item '%s=%s': %w", key, value, err) } @@ -356,7 +356,7 @@ func (c *Container) SupportsConfigItem(keys ...string) bool { } func (c *Container) Release() error { - return c.linuxcontainer.Release() + return c.LinuxContainer.Release() } // "Note that resources associated with the container, @@ -364,7 +364,7 @@ func (c *Container) Release() error { // TODO - because we set rootfs.managed=0, Destroy() doesn't // delete the /var/lib/lxc/$containerID/config file: func (c *Container) destroy() error { - if err := c.linuxcontainer.Destroy(); err != nil { + if err := c.LinuxContainer.Destroy(); err != nil { return fmt.Errorf("failed to destroy container: %w", err) } if c.CgroupDir != "" { @@ -428,7 +428,7 @@ func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, e Int("uid", opts.UID).Int("gid", opts.GID). Ints("groups", opts.Groups).Msg("execute cmd") - pid, err = c.linuxcontainer.RunCommandNoWait(args, opts) + pid, err = c.LinuxContainer.RunCommandNoWait(args, opts) if err != nil { return pid, errorf("failed to run exec cmd detached: %w", err) } @@ -440,7 +440,7 @@ func (c *Container) Exec(args []string, proc *specs.Process) (exitStatus int, er if err != nil { return 0, errorf("failed to create attach options: %w", err) } - exitStatus, err = c.linuxcontainer.RunCommandStatus(args, opts) + exitStatus, err = c.LinuxContainer.RunCommandStatus(args, opts) if err != nil { return exitStatus, errorf("failed to run exec cmd: %w", err) } @@ -481,13 +481,13 @@ func attachOptions(procSpec *specs.Process, ns []specs.LinuxNamespace) (lxc.Atta func setLog(c *Container) error { // Never let lxc write to stdout, stdout belongs to the container init process. // Explicitly disable it - allthough it is currently the default. - c.linuxcontainer.SetVerbosity(lxc.Quiet) + c.LinuxContainer.SetVerbosity(lxc.Quiet) // The log level for a running container is set, and may change, per runtime call. - err := c.linuxcontainer.SetLogLevel(parseContainerLogLevel(c.LogLevel)) + err := c.LinuxContainer.SetLogLevel(parseContainerLogLevel(c.LogLevel)) if err != nil { return fmt.Errorf("failed to set container loglevel: %w", err) } - if err := c.linuxcontainer.SetLogFile(c.LogFile); err != nil { + if err := c.LinuxContainer.SetLogFile(c.LogFile); err != nil { return fmt.Errorf("failed to set container log file: %w", err) } return nil diff --git a/runtime.go b/runtime.go index f7b5f0fc..70000750 100644 --- a/runtime.go +++ b/runtime.go @@ -167,7 +167,7 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // #nosec - cmd := exec.Command(rt.libexec(ExecStart), c.linuxcontainer.Name(), rt.Root, c.ConfigFilePath()) + cmd := exec.Command(rt.libexec(ExecStart), c.LinuxContainer.Name(), rt.Root, c.ConfigFilePath()) cmd.Env = []string{} cmd.Dir = c.RuntimePath() From 0f6a1566a136d57789d00f460679ebb4ec89a1ac Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 29 Mar 2021 13:49:33 +0200 Subject: [PATCH 242/373] Remove Timeouts from Runtime. API caller should have full controll over the timeout with the passed context. It's confusing if the API itself sets another timeout. Furthermore its not possible to use a single context with timeout properly through multiple API calls. Use uint(seconds) as flag parameter for timeout flags instead of time.Duration, since it's not useful to use another unit than second for the timeout. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 119 ++++++++++++++++++++++++++--------------------- create.go | 3 -- runtime.go | 25 ---------- 3 files changed, 66 insertions(+), 81 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 444edb09..2d9c0e28 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -35,9 +35,8 @@ type app struct { Timestamp string } - command string - createHook string - createHookTimeout time.Duration + command string + createHook string } var clxc = app{} @@ -282,31 +281,28 @@ var createCmd = cli.Command{ Name: "pid-file", Usage: "path to write container PID", }, - &cli.DurationFlag{ - Name: "timeout", - Usage: "maximum duration for create to complete", - EnvVars: []string{"LXCRI_CREATE_TIMEOUT"}, - Value: time.Second * 60, - Destination: &clxc.Timeouts.Create, + &cli.UintFlag{ + Name: "timeout", + Usage: "maximum duration in seconds for create to complete", + EnvVars: []string{"LXCRI_CREATE_TIMEOUT"}, + Value: 60, }, - // TODO implement OCI hooks and move to Runtime.Hooks &cli.StringFlag{ Name: "create-hook", - Usage: "absolute path to executable to run after create", + Usage: "path to executable to run after create (runs even if create fails)", EnvVars: []string{"LXCRI_CREATE_HOOK"}, Destination: &clxc.createHook, }, - &cli.DurationFlag{ - Name: "hook-timeout", - Usage: "maximum duration for hook to complete", - EnvVars: []string{"LXCRI_CREATE_HOOK_TIMEOUT"}, - Value: time.Second * 5, - Destination: &clxc.createHookTimeout, + &cli.UintFlag{ + Name: "hook-timeout", + Usage: "maximum duration in seconds for hook to complete", + EnvVars: []string{"LXCRI_CREATE_HOOK_TIMEOUT"}, + Value: 5, }, }, } -func doCreate(ctx *cli.Context) error { +func doCreate(ctxcli *cli.Context) error { if err := clxc.CheckSystem(); err != nil { return err } @@ -315,8 +311,13 @@ func doCreate(ctx *cli.Context) error { if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } - pidFile := ctx.String("pid-file") - c, err := clxc.Create(context.Background(), &clxc.containerConfig) + pidFile := ctxcli.String("pid-file") + + timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + c, err := clxc.Create(ctx, &clxc.containerConfig) if err == nil { defer c.Release() } @@ -326,11 +327,11 @@ func doCreate(ctx *cli.Context) error { return err } } - runCreateHook(err) + runCreateHook(ctxcli, err) return err } -func runCreateHook(err error) { +func runCreateHook(ctxcli *cli.Context, err error) { env := []string{ "CONTAINER_ID=" + clxc.containerConfig.ContainerID, "LXC_CONFIG=" + clxc.containerConfig.ConfigFilePath(), @@ -342,8 +343,10 @@ func runCreateHook(err error) { if err != nil { env = append(env, "RUNTIME_ERROR="+err.Error()) } - ctx, cancel := context.WithTimeout(context.Background(), clxc.createHookTimeout) + timeout := time.Duration(ctxcli.Uint("hook-timeout")) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() + cmd := exec.CommandContext(ctx, clxc.createHook) cmd.Env = env @@ -362,23 +365,26 @@ var startCmd = cli.Command{ starts `, Flags: []cli.Flag{ - &cli.DurationFlag{ - Name: "timeout", - Usage: "start timeout", - EnvVars: []string{"LXCRI_START_TIMEOUT"}, - Value: time.Second * 30, - Destination: &clxc.Timeouts.Start, + &cli.UintFlag{ + Name: "timeout", + Usage: "maximum duration in seconds for start to complete", + EnvVars: []string{"LXCRI_START_TIMEOUT"}, + Value: 30, }, }, } -func doStart(unused *cli.Context) error { +func doStart(ctxcli *cli.Context) error { c, err := clxc.Load(&clxc.containerConfig) if err != nil { return fmt.Errorf("failed to load container: %w", err) } - return clxc.Start(context.Background(), c) + timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + return clxc.Start(ctx, c) } var stateCmd = cli.Command{ @@ -420,18 +426,17 @@ var killCmd = cli.Command{ [signal] signal name or numerical value (e.g [9|kill|KILL|sigkill|SIGKILL]) `, Flags: []cli.Flag{ - &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for killing all processes in container cgroup", - EnvVars: []string{"LXCRI_KILL_TIMEOUT"}, - Value: time.Second * 10, - Destination: &clxc.Timeouts.Kill, + &cli.UintFlag{ + Name: "timeout", + Usage: "timeout for killing all processes in container cgroup", + EnvVars: []string{"LXCRI_KILL_TIMEOUT"}, + Value: 10, }, }, } -func doKill(ctx *cli.Context) error { - sig := ctx.Args().Get(1) +func doKill(ctxcli *cli.Context) error { + sig := ctxcli.Args().Get(1) signum := parseSignal(sig) if signum == 0 { return fmt.Errorf("invalid signal param %q", sig) @@ -441,7 +446,12 @@ func doKill(ctx *cli.Context) error { if err != nil { return fmt.Errorf("failed to load container: %w", err) } - return clxc.Kill(context.Background(), c, signum) + + timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + return clxc.Kill(ctx, c, signum) } var deleteCmd = cli.Command{ @@ -458,16 +468,15 @@ var deleteCmd = cli.Command{ Usage: "force deletion", }, &cli.DurationFlag{ - Name: "timeout", - Usage: "timeout for deleting container", - EnvVars: []string{"LXCRI_DELETE_TIMEOUT"}, - Value: time.Second * 10, - Destination: &clxc.Timeouts.Delete, + Name: "timeout", + Usage: "maximum duration in seconds for delete to complete", + EnvVars: []string{"LXCRI_DELETE_TIMEOUT"}, + Value: 10, }, }, } -func doDelete(ctx *cli.Context) error { +func doDelete(ctxcli *cli.Context) error { c, err := clxc.Load(&clxc.containerConfig) if err == lxcri.ErrNotExist { clxc.Log.Info().Msg("container does not exist") @@ -477,7 +486,11 @@ func doDelete(ctx *cli.Context) error { return err } - return clxc.Delete(context.Background(), c, ctx.Bool("force")) + timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + return clxc.Delete(ctx, c, ctxcli.Bool("force")) } var execCmd = cli.Command{ @@ -527,20 +540,20 @@ func (e execError) Error() string { } } -func doExec(ctx *cli.Context) error { +func doExec(ctxcli *cli.Context) error { var args []string - if ctx.Args().Len() > 1 { - args = ctx.Args().Slice()[1:] + if ctxcli.Args().Len() > 1 { + args = ctxcli.Args().Slice()[1:] } - pidFile := ctx.String("pid-file") - detach := ctx.Bool("detach") + pidFile := ctxcli.String("pid-file") + detach := ctxcli.Bool("detach") if detach && pidFile == "" { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := lxcri.ReadSpecProcessJSON(ctx.String("process")) + procSpec, err := lxcri.ReadSpecProcessJSON(ctxcli.String("process")) if err != nil { return err } diff --git a/create.go b/create.go index c3663aa4..a456f9d0 100644 --- a/create.go +++ b/create.go @@ -16,9 +16,6 @@ import ( // You may have to call Runtime.Delete to cleanup container runtime state, // if Create returns with an error. func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { - ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Create) - defer cancel() - if err := rt.checkConfig(cfg); err != nil { return nil, err } diff --git a/runtime.go b/runtime.go index 70000750..26c97519 100644 --- a/runtime.go +++ b/runtime.go @@ -32,14 +32,6 @@ var ( ErrExist = fmt.Errorf("container already exists") ) -// RuntimeTimeouts are timeouts for Runtime API calls. -type RuntimeTimeouts struct { - Create time.Duration - Start time.Duration - Kill time.Duration - Delete time.Duration -} - // RuntimeFeatures are (security) features supported by the Runtime. // The supported features are enabled on any Container instance // created by Runtime.Create. @@ -76,8 +68,6 @@ type Runtime struct { MonitorCgroup string // LibexecDir is the the directory that contains the runtime executables. LibexecDir string - // Timeouts are the runtime API command timeouts. - Timeouts RuntimeTimeouts // Features RuntimeFeatures @@ -90,12 +80,6 @@ var DefaultRuntime = &Runtime{ SystemdCgroup: true, LibexecDir: "/usr/libexec/lxcri", - Timeouts: RuntimeTimeouts{ - Create: time.Second * 60, - Start: time.Second * 30, - Kill: time.Second * 30, - Delete: time.Second * 60, - }, Features: RuntimeFeatures{ Seccomp: true, Capabilities: true, @@ -149,9 +133,6 @@ func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { } func (rt *Runtime) Start(ctx context.Context, c *Container) error { - ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Start) - defer cancel() - rt.Log.Info().Msg("notify init to start container process") state, err := c.State() @@ -268,9 +249,6 @@ func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string } func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) error { - ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Kill) - defer cancel() - state, err := c.ContainerState() if err != nil { return err @@ -282,9 +260,6 @@ func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) e } func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { - ctx, cancel := context.WithTimeout(ctx, rt.Timeouts.Delete) - defer cancel() - rt.Log.Info().Bool("force", force).Msg("delete container") state, err := c.ContainerState() if err != nil { From fa5f0bfbb5afe19a6f93bd89a2bd0d24288b7567 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 29 Mar 2021 21:45:15 +0200 Subject: [PATCH 243/373] Do not serialize Runtime.Log. Signed-off-by: Ruben Jenster --- runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.go b/runtime.go index 26c97519..b8b5a064 100644 --- a/runtime.go +++ b/runtime.go @@ -55,7 +55,7 @@ type Hooks struct { type Runtime struct { // Log is the logger used by the runtime. - Log zerolog.Logger + Log zerolog.Logger `json:"-"` // Root is the file path to the runtime directory. // Directories for containers created by the runtime // are created within this directory. From fa4115e52d9064fe0331b3845e72f39ad57a3eba Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 30 Mar 2021 18:32:03 +0200 Subject: [PATCH 244/373] Update godoc. Signed-off-by: Ruben Jenster --- container.go | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/container.go b/container.go index f8aafaab..2b7e94c8 100644 --- a/container.go +++ b/container.go @@ -206,6 +206,8 @@ func (c *Container) State() (*specs.State, error) { return state, nil } +// ContainerState returns the current state of the container process, +// as defined by the OCI runtime spec. func (c *Container) ContainerState() (specs.ContainerState, error) { state := c.LinuxContainer.State() switch state { @@ -318,12 +320,14 @@ func (c *Container) saveConfig() error { return nil } +// GetConfigItem is a wrapper function and returns the +// first value returned by *lxc.Container.ConfigItem func (c *Container) GetConfigItem(key string) string { vals := c.LinuxContainer.ConfigItem(key) if len(vals) > 0 { first := vals[0] - // some lxc config values are set to '(null)' if unset - // eg. lxc.cgroup.dir + // some lxc config values are set to '(null)' if unset eg. lxc.cgroup.dir + // TODO check if this is already fixed if first != "(null)" { return first } @@ -331,6 +335,8 @@ func (c *Container) GetConfigItem(key string) string { return "" } +// SetConfigItem is a wrapper for *lxc.Container.SetConfigItem. +// and only adds additional logging. func (c *Container) SetConfigItem(key, value string) error { err := c.LinuxContainer.SetConfigItem(key, value) if err != nil { @@ -340,6 +346,7 @@ func (c *Container) SetConfigItem(key, value string) error { return nil } +// SupportsConfigItem is a wrapper for *lxc.Container.IsSupportedConfig item. func (c *Container) SupportsConfigItem(keys ...string) bool { canCheck := lxc.VersionAtLeast(4, 0, 6) if !canCheck { @@ -355,14 +362,16 @@ func (c *Container) SupportsConfigItem(keys ...string) bool { return true } +// Release releases resources allocated by the container. func (c *Container) Release() error { return c.LinuxContainer.Release() } -// "Note that resources associated with the container, -// but not created by this container, MUST NOT be deleted." -// TODO - because we set rootfs.managed=0, Destroy() doesn't -// delete the /var/lib/lxc/$containerID/config file: +// From OCI runtime spec +// "Note that resources associated with the container, but not +// created by this container, MUST NOT be deleted." +// The *lxc.Container is created with `rootfs.managed=0`, +// so calling *lxc.Container.Destroy will not delete container resources. func (c *Container) destroy() error { if err := c.LinuxContainer.Destroy(); err != nil { return fmt.Errorf("failed to destroy container: %w", err) @@ -418,6 +427,10 @@ func (c *Container) readFifo() error { return nil } +// ExecDetached executes the given process spec within the container. +// The given process is started and the process PID is returned. +// It's up to the caller to wait for the process to exit using the returned PID. +// The container state must be either specs.StateCreated or specs.StateRunning func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { opts, err := attachOptions(proc, c.Linux.Namespaces) if err != nil { @@ -435,6 +448,9 @@ func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, e return pid, nil } +// Exec executes the given process spec within the container. +// It waits for the process to exit and returns its exit code. +// The container state must either be specs.StateCreated or specs.StateRunning func (c *Container) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { opts, err := attachOptions(proc, c.Linux.Namespaces) if err != nil { From 33809048ddf6271f6dbf9c1718d47202e1d4a687 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 30 Mar 2021 18:51:07 +0200 Subject: [PATCH 245/373] Convert Container.ReadSpecJson to static ReadSpecJSON function. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 3 ++- container.go | 10 ---------- runtime.go | 12 ++++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 2d9c0e28..c1d9fb3c 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -307,10 +307,11 @@ func doCreate(ctxcli *cli.Context) error { return err } specPath := filepath.Join(clxc.containerConfig.BundlePath, "config.json") - err := clxc.containerConfig.LoadSpecJson(specPath) + spec, err := lxcri.ReadSpecJSON(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } + clxc.containerConfig.Spec = spec pidFile := ctxcli.String("pid-file") timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second diff --git a/container.go b/container.go index 2b7e94c8..845a9a1f 100644 --- a/container.go +++ b/container.go @@ -64,16 +64,6 @@ func (cfg ContainerConfig) runtimeDirExists() bool { return false } -func (c *ContainerConfig) LoadSpecJson(p string) error { - spec := &specs.Spec{} - if err := decodeFileJSON(spec, p); err != nil { - return err - } - c.Spec = spec - return nil - -} - // Container is the runtime state of a container instance. type Container struct { LinuxContainer *lxc.Container `json:"-"` diff --git a/runtime.go b/runtime.go index b8b5a064..5e81b35b 100644 --- a/runtime.go +++ b/runtime.go @@ -279,8 +279,20 @@ func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { return nil } +// ReadSpecSpecJSON reads the JSON encoded OCI +// spec process definition from the given path. +// This is a convenience function for the cli. func ReadSpecProcessJSON(src string) (*specs.Process, error) { proc := new(specs.Process) err := decodeFileJSON(proc, src) return proc, err } + +// ReadSpecJSON reads the JSON encoded OCI +// spec from the given path. +// This is a convenience function for the cli. +func ReadSpecJSON(p string) (*specs.Spec, error) { + spec := &specs.Spec{} + err := decodeFileJSON(spec, p) + return spec, err +} From 41096fbfe25418e838129b0d73edc564996311fa Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 30 Mar 2021 18:51:59 +0200 Subject: [PATCH 246/373] Update godoc Signed-off-by: Ruben Jenster --- container.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/container.go b/container.go index 845a9a1f..1e7de347 100644 --- a/container.go +++ b/container.go @@ -44,6 +44,7 @@ type ContainerConfig struct { Hooks `json:"-"` } +// ConfigFilePath returns the path to the liblxc config file. func (cfg ContainerConfig) ConfigFilePath() string { return cfg.RuntimePath("config") } @@ -52,7 +53,8 @@ func (cfg ContainerConfig) syncFifoPath() string { return cfg.RuntimePath(initDir, "syncfifo") } -// RuntimePath returns the absolute path within the container root. +// RuntimePath returns the absolute path to the given sub path +// within the container root. func (cfg ContainerConfig) RuntimePath(subPath ...string) string { return filepath.Join(cfg.RuntimeDir, filepath.Join(subPath...)) } From 6a0afb226e7e402f2ff03a4c89068bd726bc22db Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 30 Mar 2021 20:27:54 +0200 Subject: [PATCH 247/373] Unexport namespace definitions. Update godoc. Signed-off-by: Ruben Jenster --- container.go | 3 +++ namespaces.go | 41 ++++++++++++++++++++++------------------- runtime.go | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/container.go b/container.go index 1e7de347..d296b4e1 100644 --- a/container.go +++ b/container.go @@ -181,6 +181,9 @@ func (c *Container) wait(ctx context.Context, state lxc.State) bool { } } +// State returns the OCI specs.State value for the containers process. +// The State.Pid value is the PID of the liblxc +// container monitor process (lxcri-start). func (c *Container) State() (*specs.State, error) { status, err := c.ContainerState() if err != nil { diff --git a/namespaces.go b/namespaces.go index 4aee4088..44dd7f96 100644 --- a/namespaces.go +++ b/namespaces.go @@ -11,30 +11,33 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -type Namespace struct { +// namespace is a mapping from the namespace name +// as used in /proc/{pid}/ns and the namespace clone flag, +// as defined in `man 2 clone`. +type namespace struct { Name string CloneFlag int } var ( - CgroupNamespace = Namespace{"cgroup", unix.CLONE_NEWCGROUP} - IPCNamespace = Namespace{"ipc", unix.CLONE_NEWIPC} - MountNamespace = Namespace{"mnt", unix.CLONE_NEWNS} - NetworkNamespace = Namespace{"net", unix.CLONE_NEWNET} - PIDNamespace = Namespace{"pid", unix.CLONE_NEWPID} - TimeNamespace = Namespace{"time", unix.CLONE_NEWTIME} - UserNamespace = Namespace{"user", unix.CLONE_NEWUSER} - UTSNamespace = Namespace{"uts", unix.CLONE_NEWUTS} - - namespaceMap = map[specs.LinuxNamespaceType]Namespace{ - specs.CgroupNamespace: CgroupNamespace, - specs.IPCNamespace: IPCNamespace, - specs.MountNamespace: MountNamespace, - specs.NetworkNamespace: NetworkNamespace, - specs.PIDNamespace: PIDNamespace, - // specs.TimeNamespace: TimeNamespace, - specs.UserNamespace: UserNamespace, - specs.UTSNamespace: UTSNamespace, + cgroupNamespace = namespace{"cgroup", unix.CLONE_NEWCGROUP} + ipcNamespace = namespace{"ipc", unix.CLONE_NEWIPC} + mountNamespace = namespace{"mnt", unix.CLONE_NEWNS} + networkNamespace = namespace{"net", unix.CLONE_NEWNET} + pidNamespace = namespace{"pid", unix.CLONE_NEWPID} + timeNamespace = namespace{"time", unix.CLONE_NEWTIME} + userNamespace = namespace{"user", unix.CLONE_NEWUSER} + utsNamespace = namespace{"uts", unix.CLONE_NEWUTS} + + namespaceMap = map[specs.LinuxNamespaceType]namespace{ + specs.CgroupNamespace: cgroupNamespace, + specs.IPCNamespace: ipcNamespace, + specs.MountNamespace: mountNamespace, + specs.NetworkNamespace: networkNamespace, + specs.PIDNamespace: pidNamespace, + // specs.timeNamespace: timeNamespace, + specs.UserNamespace: userNamespace, + specs.UTSNamespace: utsNamespace, } ) diff --git a/runtime.go b/runtime.go index 5e81b35b..2d36d2d9 100644 --- a/runtime.go +++ b/runtime.go @@ -28,8 +28,12 @@ const ( ) var ( + // ErrExist is an error returned by Runtime.Create + // if a container with the same ContainerID already exists. + ErrExist = fmt.Errorf("container already exists") + // ErrNotExist is an error returned by all runtime functions + // that exected functions if a container does not exist. ErrNotExist = fmt.Errorf("container does not exist") - ErrExist = fmt.Errorf("container already exists") ) // RuntimeFeatures are (security) features supported by the Runtime. @@ -49,10 +53,14 @@ type Hooks struct { // OnCreate is called right after creation of container runtime directory // and descriptor, but before the liblxc 'config' file is written. // At this point it's possible to add files to the container runtime directory - // and modify the ContainerConfig. + // and modify the ContainerConfig accordingly. OnCreate RuntimeHook } +// Runtime is a factory for creating and managing containers. +// The exported methods of Runtime are required to implement the +// OCI container runtime interface spec (CRI). +// It shares the common settings type Runtime struct { // Log is the logger used by the runtime. Log zerolog.Logger `json:"-"` @@ -63,14 +71,18 @@ type Runtime struct { // Use systemd encoded cgroup path (from crio-o/conmon) // is true if /etc/crio/crio.conf#cgroup_manager = "systemd" SystemdCgroup bool - // Path for lxc monitor cgroup (lxc specific feature) - // similar to /etc/crio/crio.conf#conmon_cgroup + // Path for lxc monitor cgroup (lxc specific feature). + // This is the cgroup where the liblxc monitor process (lxcri-start) + // will be placed in. It's similar to /etc/crio/crio.conf#conmon_cgroup MonitorCgroup string // LibexecDir is the the directory that contains the runtime executables. LibexecDir string - // + // Featuress are runtime (security) features that apply to all containers + // created by the runtime. Features RuntimeFeatures - + // Hooks contains all callback functions supported by the runtime. + // These hooks are different from the hooks that are + // defined within the OCI runtime spec. Hooks `json:"-"` } @@ -279,15 +291,6 @@ func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { return nil } -// ReadSpecSpecJSON reads the JSON encoded OCI -// spec process definition from the given path. -// This is a convenience function for the cli. -func ReadSpecProcessJSON(src string) (*specs.Process, error) { - proc := new(specs.Process) - err := decodeFileJSON(proc, src) - return proc, err -} - // ReadSpecJSON reads the JSON encoded OCI // spec from the given path. // This is a convenience function for the cli. @@ -296,3 +299,12 @@ func ReadSpecJSON(p string) (*specs.Spec, error) { err := decodeFileJSON(spec, p) return spec, err } + +// ReadProcessSpecJSON reads the JSON encoded OCI +// spec process definition from the given path. +// This is a convenience function for the cli. +func ReadSpecProcessJSON(src string) (*specs.Process, error) { + proc := new(specs.Process) + err := decodeFileJSON(proc, src) + return proc, err +} From e39babc8254f001b8e0c9e5401c83159f5c54fcd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 30 Mar 2021 20:43:03 +0200 Subject: [PATCH 248/373] Update godoc. Rename RuntimeHook to HookFunc. Signed-off-by: Ruben Jenster --- runtime.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/runtime.go b/runtime.go index 2d36d2d9..129d5bc4 100644 --- a/runtime.go +++ b/runtime.go @@ -46,15 +46,17 @@ type RuntimeFeatures struct { CgroupDevices bool } -type RuntimeHook func(ctx context.Context, c *Container) error +// HookFunc defines the function type that must be implemented +// by runtime and container (non-OCI) callback hooks. +type HookFunc func(ctx context.Context, c *Container) error -// RuntimeHooks are callback functions executed within the container lifecycle. +// Hooks are callback functions executed within the container lifecycle. type Hooks struct { // OnCreate is called right after creation of container runtime directory // and descriptor, but before the liblxc 'config' file is written. // At this point it's possible to add files to the container runtime directory // and modify the ContainerConfig accordingly. - OnCreate RuntimeHook + OnCreate HookFunc } // Runtime is a factory for creating and managing containers. @@ -86,6 +88,8 @@ type Runtime struct { Hooks `json:"-"` } +// DefaultRuntime is the default runtime instance +// used by all static wrapper functions. var DefaultRuntime = &Runtime{ Log: log.ConsoleLogger(true), Root: "/var/run/lxcri", @@ -100,10 +104,6 @@ var DefaultRuntime = &Runtime{ }, } -func (rt *Runtime) libexec(name string) string { - return filepath.Join(rt.LibexecDir, name) -} - // CheckSystem is a wrapper around DefaultRuntime.CheckSystem func CheckSystem() error { return DefaultRuntime.CheckSystem() @@ -134,6 +134,10 @@ func Delete(ctx context.Context, c *Container, force bool) error { return DefaultRuntime.Delete(ctx, c, force) } +func (rt *Runtime) libexec(name string) string { + return filepath.Join(rt.LibexecDir, name) +} + func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { c := &Container{ContainerConfig: cfg} c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) @@ -300,7 +304,7 @@ func ReadSpecJSON(p string) (*specs.Spec, error) { return spec, err } -// ReadProcessSpecJSON reads the JSON encoded OCI +// ReadSpecProcessJSON reads the JSON encoded OCI // spec process definition from the given path. // This is a convenience function for the cli. func ReadSpecProcessJSON(src string) (*specs.Process, error) { From 4a305977997b5816933b87ed480caa83e1eede75 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 09:28:49 +0200 Subject: [PATCH 249/373] Use only the container ID to load a container. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 10 +++++----- runtime.go | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index c1d9fb3c..3fdd90bc 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -376,7 +376,7 @@ starts } func doStart(ctxcli *cli.Context) error { - c, err := clxc.Load(&clxc.containerConfig) + c, err := clxc.Load(clxc.containerConfig.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -400,7 +400,7 @@ var stateCmd = cli.Command{ } func doState(unused *cli.Context) error { - c, err := clxc.Load(&clxc.containerConfig) + c, err := clxc.Load(clxc.containerConfig.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -443,7 +443,7 @@ func doKill(ctxcli *cli.Context) error { return fmt.Errorf("invalid signal param %q", sig) } - c, err := clxc.Load(&clxc.containerConfig) + c, err := clxc.Load(clxc.containerConfig.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -478,7 +478,7 @@ var deleteCmd = cli.Command{ } func doDelete(ctxcli *cli.Context) error { - c, err := clxc.Load(&clxc.containerConfig) + c, err := clxc.Load(clxc.containerConfig.ContainerID) if err == lxcri.ErrNotExist { clxc.Log.Info().Msg("container does not exist") return nil @@ -562,7 +562,7 @@ func doExec(ctxcli *cli.Context) error { args = procSpec.Args } - c, err := clxc.Load(&clxc.containerConfig) + c, err := clxc.Load(clxc.containerConfig.ContainerID) if err != nil { return err } diff --git a/runtime.go b/runtime.go index 129d5bc4..9b80d10a 100644 --- a/runtime.go +++ b/runtime.go @@ -115,8 +115,8 @@ func Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { } // Load is a wrapper around DefaultRuntime.Load -func Load(cfg *ContainerConfig) (*Container, error) { - return DefaultRuntime.Load(cfg) +func Load(containerID string) (*Container, error) { + return DefaultRuntime.Load(containerID) } // Start is a wrapper around DefaultRuntime.Start @@ -138,9 +138,10 @@ func (rt *Runtime) libexec(name string) string { return filepath.Join(rt.LibexecDir, name) } -func (rt *Runtime) Load(cfg *ContainerConfig) (*Container, error) { - c := &Container{ContainerConfig: cfg} - c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) +// Load loads a container from the runtime directory. +func (rt *Runtime) Load(containerID string) (*Container, error) { + c := &Container{ContainerConfig: &ContainerConfig{}} + c.RuntimeDir = filepath.Join(rt.Root, containerID) if err := c.load(); err != nil { return nil, err From 08fea02a2e6bc59f07857d7982c5dbabdbfae59c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 09:30:48 +0200 Subject: [PATCH 250/373] Use shorter variable for ContainerConfig in cli. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 3fdd90bc..0a867e62 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -26,7 +26,7 @@ var ( type app struct { lxcri.Runtime - containerConfig lxcri.ContainerConfig + cfg lxcri.ContainerConfig logConfig struct { File *os.File @@ -54,8 +54,8 @@ func (app *app) configureLogger() error { return fmt.Errorf("failed to parse log level: %w", err) } logCtx := log.NewLogger(app.logConfig.File, level) - app.Runtime.Log = logCtx.Str("cmd", app.command).Str("cid", app.containerConfig.ContainerID).Logger() - app.containerConfig.Log = app.Runtime.Log + app.Runtime.Log = logCtx.Str("cmd", app.command).Str("cid", app.cfg.ContainerID).Logger() + app.cfg.Log = app.Runtime.Log return nil } @@ -113,14 +113,14 @@ func main() { Usage: "set the container process (liblxc) log level (trace|debug|info|notice|warn|error|crit|alert|fatal)", EnvVars: []string{"LXCRI_CONTAINER_LOG_LEVEL"}, Value: "warn", - Destination: &clxc.containerConfig.LogLevel, + Destination: &clxc.cfg.LogLevel, }, &cli.StringFlag{ Name: "container-log-file", Usage: "path to the log file for runtime and container output", EnvVars: []string{"LXCRI_CONTAINER_LOG_FILE"}, Value: defaultLogFile, - Destination: &clxc.containerConfig.LogFile, + Destination: &clxc.cfg.LogFile, }, &cli.StringFlag{ Name: "root", @@ -222,7 +222,7 @@ func main() { if len(containerID) == 0 { return fmt.Errorf("missing container ID") } - clxc.containerConfig.ContainerID = containerID + clxc.cfg.ContainerID = containerID if err := clxc.configureLogger(); err != nil { return fmt.Errorf("failed to configure logger: %w", err) @@ -270,12 +270,12 @@ var createCmd = cli.Command{ Name: "bundle", Usage: "set bundle directory", Value: ".", - Destination: &clxc.containerConfig.BundlePath, + Destination: &clxc.cfg.BundlePath, }, &cli.StringFlag{ Name: "console-socket", Usage: "send container pty master fd to this socket path", - Destination: &clxc.containerConfig.ConsoleSocket, + Destination: &clxc.cfg.ConsoleSocket, }, &cli.StringFlag{ Name: "pid-file", @@ -306,19 +306,19 @@ func doCreate(ctxcli *cli.Context) error { if err := clxc.CheckSystem(); err != nil { return err } - specPath := filepath.Join(clxc.containerConfig.BundlePath, "config.json") + specPath := filepath.Join(clxc.cfg.BundlePath, "config.json") spec, err := lxcri.ReadSpecJSON(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } - clxc.containerConfig.Spec = spec + clxc.cfg.Spec = spec pidFile := ctxcli.String("pid-file") timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - c, err := clxc.Create(ctx, &clxc.containerConfig) + c, err := clxc.Create(ctx, &clxc.cfg) if err == nil { defer c.Release() } @@ -334,11 +334,11 @@ func doCreate(ctxcli *cli.Context) error { func runCreateHook(ctxcli *cli.Context, err error) { env := []string{ - "CONTAINER_ID=" + clxc.containerConfig.ContainerID, - "LXC_CONFIG=" + clxc.containerConfig.ConfigFilePath(), + "CONTAINER_ID=" + clxc.cfg.ContainerID, + "LXC_CONFIG=" + clxc.cfg.ConfigFilePath(), "RUNTIME_CMD=" + clxc.command, - "RUNTIME_PATH=" + clxc.containerConfig.RuntimePath(), - "BUNDLE_PATH=" + clxc.containerConfig.BundlePath, + "RUNTIME_PATH=" + clxc.cfg.RuntimePath(), + "BUNDLE_PATH=" + clxc.cfg.BundlePath, "LOG_FILE=" + clxc.logConfig.FilePath, } if err != nil { @@ -376,7 +376,7 @@ starts } func doStart(ctxcli *cli.Context) error { - c, err := clxc.Load(clxc.containerConfig.ContainerID) + c, err := clxc.Load(clxc.cfg.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -400,7 +400,7 @@ var stateCmd = cli.Command{ } func doState(unused *cli.Context) error { - c, err := clxc.Load(clxc.containerConfig.ContainerID) + c, err := clxc.Load(clxc.cfg.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -443,7 +443,7 @@ func doKill(ctxcli *cli.Context) error { return fmt.Errorf("invalid signal param %q", sig) } - c, err := clxc.Load(clxc.containerConfig.ContainerID) + c, err := clxc.Load(clxc.cfg.ContainerID) if err != nil { return fmt.Errorf("failed to load container: %w", err) } @@ -478,7 +478,7 @@ var deleteCmd = cli.Command{ } func doDelete(ctxcli *cli.Context) error { - c, err := clxc.Load(clxc.containerConfig.ContainerID) + c, err := clxc.Load(clxc.cfg.ContainerID) if err == lxcri.ErrNotExist { clxc.Log.Info().Msg("container does not exist") return nil @@ -562,7 +562,7 @@ func doExec(ctxcli *cli.Context) error { args = procSpec.Args } - c, err := clxc.Load(clxc.containerConfig.ContainerID) + c, err := clxc.Load(clxc.cfg.ContainerID) if err != nil { return err } From 9a6d938be9709a42dc714d7fa1b2f98a50b42459 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 10:37:30 +0200 Subject: [PATCH 251/373] Update godoc. Signed-off-by: Ruben Jenster --- create.go | 3 ++- runtime.go | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/create.go b/create.go index a456f9d0..637c4c21 100644 --- a/create.go +++ b/create.go @@ -49,7 +49,8 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container // CheckSystem checks the hosts system configuration. // Unsupported runtime features are disabled and a warning message is logged. -// CheckSystem should be called (once) before using the Runtime. +// CheckSystem is not called internally, but it recommended to +// call it once for a runtime instance before calling any other method. func (rt *Runtime) CheckSystem() error { err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) if err != nil { diff --git a/runtime.go b/runtime.go index 9b80d10a..bed91db9 100644 --- a/runtime.go +++ b/runtime.go @@ -139,6 +139,7 @@ func (rt *Runtime) libexec(name string) string { } // Load loads a container from the runtime directory. +// The container must have been created with Runtime.Create. func (rt *Runtime) Load(containerID string) (*Container, error) { c := &Container{ContainerConfig: &ContainerConfig{}} c.RuntimeDir = filepath.Join(rt.Root, containerID) @@ -149,6 +150,10 @@ func (rt *Runtime) Load(containerID string) (*Container, error) { return c, nil } +// Start starts the given container. +// Start simply unblocks the container init process `lxcri-init`, +// which then executes the actuall container process. +// The given container must have been created with Runtime.Create. func (rt *Runtime) Start(ctx context.Context, c *Container) error { rt.Log.Info().Msg("notify init to start container process") @@ -265,6 +270,9 @@ func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string return ptmx.Close() } +// Kill sends the signal signum to the given container. +// The signal is send to the container monitor process `lxcri-start` who +// will propagate the signal to the container process. func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) error { state, err := c.ContainerState() if err != nil { @@ -276,6 +284,10 @@ func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) e return c.kill(ctx, signum) } +// Delete removes the container from the runtime directory. +// The container must be stopped or force must be set to true. +// If the container is not stopped but force is set to true, +// the container will be killed with unix.SIGKILL. func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { rt.Log.Info().Bool("force", force).Msg("delete container") state, err := c.ContainerState() From 2e663920a4b1b96bc067392562dda6d0fc158c8f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 10:46:39 +0200 Subject: [PATCH 252/373] Require go 1.16 and remove deprecated io/ioutil import. Signed-off-by: Ruben Jenster --- cgroup.go | 7 +++---- cmd/lxcri/utils.go | 5 ++--- container.go | 3 +-- go.mod | 2 +- mount_test.go | 9 ++++----- utils/cgfix.go | 5 ++--- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/cgroup.go b/cgroup.go index dee53a09..f1c4721c 100644 --- a/cgroup.go +++ b/cgroup.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -256,7 +255,7 @@ type cgroupInfo struct { func (cg *cgroupInfo) loadProcs() error { cgroupProcsPath := filepath.Join(cgroupRoot, cg.Name, "cgroup.procs") // #nosec - procsData, err := ioutil.ReadFile(cgroupProcsPath) + procsData, err := os.ReadFile(cgroupProcsPath) if err != nil { return fmt.Errorf("failed to read cgroup.procs: %w", err) } @@ -402,7 +401,7 @@ func createCgroup(cg string, controllers string) error { for _, elem := range strings.Split(cg, "/") { base = filepath.Join(base, elem) c := filepath.Join(base, "cgroup.subtree_control") - err := ioutil.WriteFile(c, []byte(strings.TrimSpace(controllers)+"\n"), 0) + err := os.WriteFile(c, []byte(strings.TrimSpace(controllers)+"\n"), 0) if err != nil { return fmt.Errorf("failed to enable cgroup controllers: %w", err) } @@ -412,7 +411,7 @@ func createCgroup(cg string, controllers string) error { func getControllers(cg string) (string, error) { // enable all available controllers in the scope - data, err := ioutil.ReadFile(filepath.Join(cgroupRoot, cg, "group.controllers")) + data, err := os.ReadFile(filepath.Join(cgroupRoot, cg, "group.controllers")) if err != nil { return "", fmt.Errorf("failed to read cgroup.controllers: %w", err) } diff --git a/cmd/lxcri/utils.go b/cmd/lxcri/utils.go index ffff6797..9e232b9c 100644 --- a/cmd/lxcri/utils.go +++ b/cmd/lxcri/utils.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -30,7 +29,7 @@ func loadEnvFile(envFile string) (map[string]string, error) { } // #nosec - data, err := ioutil.ReadFile(envFile) + data, err := os.ReadFile(envFile) if err != nil { return nil, err } @@ -124,7 +123,7 @@ func createPidFile(path string, pid int) error { func readPidFile(path string) (int, error) { // #nosec - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } diff --git a/container.go b/container.go index d296b4e1..a9533126 100644 --- a/container.go +++ b/container.go @@ -3,7 +3,6 @@ package lxcri import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -226,7 +225,7 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { return specs.StateStopped, nil } cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) - cmdline, err := ioutil.ReadFile(cmdlinePath) + cmdline, err := os.ReadFile(cmdlinePath) if os.IsNotExist(err) { // init process died or returned return specs.StateStopped, nil diff --git a/go.mod b/go.mod index fb4d1434..be406972 100644 --- a/go.mod +++ b/go.mod @@ -18,4 +18,4 @@ replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20201221181555-eec23a3 replace golang.org/x/text => golang.org/x/text v0.3.3 -go 1.13 +go 1.16 diff --git a/mount_test.go b/mount_test.go index 5e2097df..473082a5 100644 --- a/mount_test.go +++ b/mount_test.go @@ -1,7 +1,6 @@ package lxcri import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -11,7 +10,7 @@ import ( ) func TestResolveMountDestination_absolute(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "golang.test") + tmpdir, err := os.MkdirTemp("", "golang.test") require.NoError(t, err) defer os.RemoveAll(tmpdir) err = os.MkdirAll(filepath.Join(tmpdir, "folder1"), 0750) @@ -24,7 +23,7 @@ func TestResolveMountDestination_absolute(t *testing.T) { require.NoError(t, err) err = os.Symlink("/folder3", filepath.Join(tmpdir, "folder2", "f3")) require.NoError(t, err) - err = ioutil.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) + err = os.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) require.NoError(t, err) p, err := resolveMountDestination(tmpdir, "/folder1/f2/f3/test.txt") @@ -41,7 +40,7 @@ func TestResolveMountDestination_absolute(t *testing.T) { } func TestResolveMountDestination_relative(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "golang.test") + tmpdir, err := os.MkdirTemp("", "golang.test") require.NoError(t, err) defer os.RemoveAll(tmpdir) err = os.MkdirAll(filepath.Join(tmpdir, "folder1"), 0750) @@ -54,7 +53,7 @@ func TestResolveMountDestination_relative(t *testing.T) { require.NoError(t, err) err = os.Symlink("../folder3", filepath.Join(tmpdir, "folder2", "f3")) require.NoError(t, err) - err = ioutil.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) + err = os.WriteFile(filepath.Join(tmpdir, "folder3", "test.txt"), []byte("hello"), 0640) require.NoError(t, err) //err = os.Symlink("../../folder2", filepath.Join(tmpdir, "folder1", "f2")) diff --git a/utils/cgfix.go b/utils/cgfix.go index a503ac36..c71017ec 100644 --- a/utils/cgfix.go +++ b/utils/cgfix.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -29,7 +28,7 @@ func main() { } if !info.IsDir() && info.Name() == "cgroup.subtree_control" { println(path) - if err := ioutil.WriteFile(path, []byte(subtreeControl), 0); err != nil { + if err := os.WriteFile(path, []byte(subtreeControl), 0); err != nil { return err } } @@ -57,7 +56,7 @@ func fmtControllers(controllers ...string) string { func loadControllers(cgroupPath string) ([]string, error) { // #nosec - data, err := ioutil.ReadFile(filepath.Join(cgroupPath, "cgroup.controllers")) + data, err := os.ReadFile(filepath.Join(cgroupPath, "cgroup.controllers")) if err != nil { return nil, fmt.Errorf("failed to read cgroup.controllers: %s", err) } From 69918357365432db052443572d6918e7b69ebd74 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 11:34:11 +0200 Subject: [PATCH 253/373] Remove create-hook. Will be replaced with OCI runtime hooks instead. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 51 +++++------------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 0a867e62..160f70df 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "os" - "os/exec" "path/filepath" "time" @@ -287,18 +286,6 @@ var createCmd = cli.Command{ EnvVars: []string{"LXCRI_CREATE_TIMEOUT"}, Value: 60, }, - &cli.StringFlag{ - Name: "create-hook", - Usage: "path to executable to run after create (runs even if create fails)", - EnvVars: []string{"LXCRI_CREATE_HOOK"}, - Destination: &clxc.createHook, - }, - &cli.UintFlag{ - Name: "hook-timeout", - Usage: "maximum duration in seconds for hook to complete", - EnvVars: []string{"LXCRI_CREATE_HOOK_TIMEOUT"}, - Value: 5, - }, }, } @@ -319,42 +306,14 @@ func doCreate(ctxcli *cli.Context) error { defer cancel() c, err := clxc.Create(ctx, &clxc.cfg) - if err == nil { - defer c.Release() - } - if err == nil && pidFile != "" { - err = createPidFile(pidFile, c.Pid) - if err != nil { - return err - } - } - runCreateHook(ctxcli, err) - return err -} - -func runCreateHook(ctxcli *cli.Context, err error) { - env := []string{ - "CONTAINER_ID=" + clxc.cfg.ContainerID, - "LXC_CONFIG=" + clxc.cfg.ConfigFilePath(), - "RUNTIME_CMD=" + clxc.command, - "RUNTIME_PATH=" + clxc.cfg.RuntimePath(), - "BUNDLE_PATH=" + clxc.cfg.BundlePath, - "LOG_FILE=" + clxc.logConfig.FilePath, - } if err != nil { - env = append(env, "RUNTIME_ERROR="+err.Error()) + return err } - timeout := time.Duration(ctxcli.Uint("hook-timeout")) * time.Second - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - cmd := exec.CommandContext(ctx, clxc.createHook) - cmd.Env = env - - clxc.Log.Debug().Str("file", clxc.createHook).Msg("execute create hook") - if err := cmd.Run(); err != nil { - clxc.Log.Error().Err(err).Str("file", clxc.createHook).Msg("failed to execute create hook") + defer c.Release() + if pidFile != "" { + return createPidFile(pidFile, c.Pid) } + return nil } var startCmd = cli.Command{ From d77c874f498744f2c4019e8737dc28082e0c5eee Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 31 Mar 2021 15:46:00 +0200 Subject: [PATCH 254/373] Do not rebuild binaries if test files change. Signed-off-by: Ruben Jenster --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ba9b3dfd..9f8b50f0 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ LDFLAGS=-X main.version=$(COMMIT) -X main.libexecDir=$(LIBEXEC_DIR) CC ?= cc MUSL_CC ?= musl-gcc SHELL_SCRIPTS = $(shell find . -name \*.sh) -GO_SRC = $(shell find . -name \*.go) +GO_SRC = $(shell find . -name \*.go | grep -v _test.go) all: fmt test build From 97ff3776835c26c7e79abae07e23cba26fa7945d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 12:08:35 +0200 Subject: [PATCH 255/373] Fix PKG_CONFIG_PATH visibility in lxcri-start build target. Signed-off-by: Ruben Jenster --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9f8b50f0..19a05589 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ LIBEXEC_BINS := lxcri-start lxcri-init lxcri-hook # Installation prefix for BINS PREFIX ?= /usr/local LIBEXEC_DIR = $(PREFIX)/libexec/lxcri +PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig # Note: The default pkg-config directory is search after PKG_CONFIG_PATH -PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig +# Note: (Exported) environment variables are NOT visible in the environment of the $(shell ...) function. export PKG_CONFIG_PATH -LIBLXC_LDFLAGS = $(shell pkg-config --libs --cflags lxc) LDFLAGS=-X main.version=$(COMMIT) -X main.libexecDir=$(LIBEXEC_DIR) CC ?= cc MUSL_CC ?= musl-gcc @@ -37,7 +37,7 @@ lxcri: go.mod $(GO_SRC) go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri lxcri-start: cmd/lxcri-start/lxcri-start.c - $(CC) -Werror -Wpedantic -o $@ $? $(LIBLXC_LDFLAGS) + $(CC) -Werror -Wpedantic -o $@ $? $$(pkg-config --libs --cflags lxc) lxcri-init: cmd/lxcri-init/lxcri-init.c $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? From c2adbf6aed0df4473be4edc9a13771dc68d0d7b6 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 13:07:35 +0200 Subject: [PATCH 256/373] Unexport Container.RuntimeDir. Container.runtimeDir should only be set by the Runtime instance. This should be done either on creation or when the container is loaded from the runtime directory. It should never be serialized, since this makes it impossible to move a container between runtime directories. Signed-off-by: Ruben Jenster --- container.go | 26 +++++++++++++------------- create.go | 2 +- runtime.go | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/container.go b/container.go index a9533126..1461c047 100644 --- a/container.go +++ b/container.go @@ -19,8 +19,6 @@ import ( type ContainerConfig struct { *specs.Spec - RuntimeDir string - ContainerID string BundlePath string @@ -44,22 +42,22 @@ type ContainerConfig struct { } // ConfigFilePath returns the path to the liblxc config file. -func (cfg ContainerConfig) ConfigFilePath() string { - return cfg.RuntimePath("config") +func (c Container) ConfigFilePath() string { + return c.RuntimePath("config") } -func (cfg ContainerConfig) syncFifoPath() string { - return cfg.RuntimePath(initDir, "syncfifo") +func (c Container) syncFifoPath() string { + return c.RuntimePath(initDir, "syncfifo") } // RuntimePath returns the absolute path to the given sub path // within the container root. -func (cfg ContainerConfig) RuntimePath(subPath ...string) string { - return filepath.Join(cfg.RuntimeDir, filepath.Join(subPath...)) +func (c Container) RuntimePath(subPath ...string) string { + return filepath.Join(c.runtimeDir, filepath.Join(subPath...)) } -func (cfg ContainerConfig) runtimeDirExists() bool { - if _, err := os.Stat(cfg.RuntimeDir); err == nil { +func (c Container) runtimeDirExists() bool { + if _, err := os.Stat(c.runtimeDir); err == nil { return true } return false @@ -72,13 +70,15 @@ type Container struct { CreatedAt time.Time Pid int + + runtimeDir string } func (c *Container) create() error { if c.runtimeDirExists() { return ErrExist } - if err := os.MkdirAll(c.RuntimeDir, 0700); err != nil { + if err := os.MkdirAll(c.runtimeDir, 0700); err != nil { return fmt.Errorf("failed to create container dir: %w", err) } @@ -93,7 +93,7 @@ func (c *Container) create() error { return fmt.Errorf("failed to close empty config tmpfile: %w", err) } - c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.runtimeDir)) if err != nil { return err } @@ -115,7 +115,7 @@ func (c *Container) load() error { if err != nil { return fmt.Errorf("failed to load lxc config file: %w", err) } - c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.RuntimeDir)) + c.LinuxContainer, err = lxc.NewContainer(c.ContainerID, filepath.Dir(c.runtimeDir)) if err != nil { return fmt.Errorf("failed to create lxc container: %w", err) } diff --git a/create.go b/create.go index 637c4c21..7c526e71 100644 --- a/create.go +++ b/create.go @@ -21,7 +21,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container } c := &Container{ContainerConfig: cfg} - c.RuntimeDir = filepath.Join(rt.Root, c.ContainerID) + c.runtimeDir = filepath.Join(rt.Root, c.ContainerID) if err := c.create(); err != nil { return c, errorf("failed to create container: %w", err) diff --git a/runtime.go b/runtime.go index bed91db9..083b4da2 100644 --- a/runtime.go +++ b/runtime.go @@ -142,7 +142,7 @@ func (rt *Runtime) libexec(name string) string { // The container must have been created with Runtime.Create. func (rt *Runtime) Load(containerID string) (*Container, error) { c := &Container{ContainerConfig: &ContainerConfig{}} - c.RuntimeDir = filepath.Join(rt.Root, containerID) + c.runtimeDir = filepath.Join(rt.Root, containerID) if err := c.load(); err != nil { return nil, err From 6ac19609dec0905d206871b51e8fc159985853ad Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 19:34:54 +0200 Subject: [PATCH 257/373] Refactor Container.kill to always send the signal to container init. The kernel itself terminates all children if the init process of a pid namespace dies. Drainig the cgroup is removed too, since it might cause issues when multiple containers share a cgroup. Signed-off-by: Ruben Jenster --- container.go | 68 ++++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/container.go b/container.go index 1461c047..ffa4b12d 100644 --- a/container.go +++ b/container.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "path/filepath" - "strconv" "strings" "time" @@ -244,49 +243,40 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { func (c *Container) kill(ctx context.Context, signum unix.Signal) error { c.Log.Info().Int("signum", int(signum)).Msg("killing container process") - if signum == unix.SIGKILL || signum == unix.SIGTERM { - return c.stop(ctx, signum) - } - - // Send non-terminating signals to monitor process. - // The monitor process propagates the signal to all container process. - // FIXME revise this, it may be prone to race-conditions, - /// the monitor process PID could have been recycled - // Maybe use c.lxccontainer.InitPidFd() ? - if c.Pid > 1 { - c.Log.Info().Int("pid", c.Pid).Int("signal", int(signum)).Msg("sending signal") - if err := unix.Kill(c.Pid, 0); err == nil { - err := unix.Kill(c.Pid, signum) - if err != unix.ESRCH { - return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, c.Pid, err) - } - } - } - return nil -} -func (c *Container) stop(ctx context.Context, signum unix.Signal) error { - if err := c.SetConfigItem("lxc.signal.stop", strconv.Itoa(int(signum))); err != nil { - return err - } - if err := c.LinuxContainer.Stop(); err != nil { - return err + // TODO(race condition) check whether it is save to signal InitPid() + // To avoid that the PID of the init process is recycled we aquire the pidfd of it. + // The container init process may have already died here and if the PID is already recycled, + // the wrong process will be signaled. If the kernel is recent enough. + // to support pidfd_send_signal (only kernel > 5.6 ?) + pidfd, err := c.LinuxContainer.InitPidFd() + if err != nil { + // since this is best-effort we won't return an error + c.Log.Warn().Msgf("failed to get init pidfd: %s", err) + } else { + defer pidfd.Close() } - if !c.wait(ctx, lxc.STOPPED) { - c.Log.Warn().Msg("failed to stop lxc container") + // From `man pid_namespaces`: If the "init" process of a PID namespace terminates, the kernel + // terminates all of the processes in the namespace via a SIGKILL signal. + // So there is nothing more to do here than signaling the init process. + // NOTE: The liblxc monitor process `lxcri-start` doesn't propagate all signals to the init process, + // but handles some signals on its own. E.g SIGHUP tells the monitor process to hang up the terminal + // and terminate the init process with SIGTERM. + pid := c.LinuxContainer.InitPid() + if pid <= 1 { + return nil } - - // draining the cgroup is required to catch processes that escaped from - // 'kill' e.g a bash for loop that spawns a new child immediately. - start := time.Now() - err := drainCgroup(ctx, c.CgroupDir, signum) - if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to drain cgroup") - } else { - c.Log.Info().Dur("duration", time.Since(start)).Str("file", c.CgroupDir).Msg("cgroup drained") + c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") + err = unix.Kill(pid, signum) + if err == unix.ESRCH { + // init already died before sending the signal - not an error + return nil } - return err + if err != nil { + return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) + } + return nil } // SaveConfig creates and atomically enables the lxc config file. From 1d42541e0078c84862847a9d2beacd3c0b9670bd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:01:35 +0200 Subject: [PATCH 258/373] Avoid sharing the hosts mount and PID namespace with the container. Signed-off-by: Ruben Jenster --- create.go | 11 +++++++++++ namespaces.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/create.go b/create.go index 7c526e71..ee76eebd 100644 --- a/create.go +++ b/create.go @@ -96,6 +96,17 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { rt.Log.Info().Msg("configs.Process.Cwd is unset defaulting to '/'") config.Process.Cwd = "/" } + + mustNotShareHostNamespaces := []specs.LinuxNamespaceType{specs.PIDNamespace, specs.MountNamespace} + for _, n := range mustNotShareHostNamespaces { + yes, err := isHostNamespaceShared(config.Linux.Namespaces, n) + if err != nil { + return err + } + if yes { + return fmt.Errorf("container wants to share the hosts %q namespace", n) + } + } return nil } diff --git a/namespaces.go b/namespaces.go index 44dd7f96..24fe9509 100644 --- a/namespaces.go +++ b/namespaces.go @@ -91,6 +91,43 @@ func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool return false } +// isHostNamespaceUsed returns true if a container created with the given list of +// namespaces will use the host namespace of the given namespace type. +func isHostNamespaceShared(namespaces []specs.LinuxNamespace, nsType specs.LinuxNamespaceType) (bool, error) { + ns := getNamespace(nsType, namespaces) + // no namespace with this name defined in list + if ns == nil { + return true, nil + } + // namespaces without a target path are cloned + if ns.Path == "" { + return false, nil + } + + // from `man namespaces` The /proc/[pid]/ns/ directory [...] + // In Linux 3.7 and earlier, these files were visible as hard links. + // If two processes are in the same namespace, then the device IDs and inode numbers + // of their /proc/[pid]/ns/xxx symbolic links will be the same; + // anapplication can check this using the stat.st_dev and stat.st_ino + // fields returned by stat(2). + // e.g `strace /usr/bin/stat -L /proc/1/ns/pid` + + var stat unix.Stat_t + err := unix.Stat(ns.Path, &stat) + if err != nil { + return false, err + } + + var stat1 unix.Stat_t + err = unix.Stat("/proc/1/ns/pid", &stat1) + if err != nil { + return false, err + } + + sameNS := (stat.Dev == stat1.Dev) && (stat.Ino == stat1.Ino) + return sameNS, nil +} + func getNamespace(nsType specs.LinuxNamespaceType, namespaces []specs.LinuxNamespace) *specs.LinuxNamespace { for _, n := range namespaces { if n.Type == nsType { From cb6c1303fc19761f65aa2c5a336fbb195e096b2f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:04:03 +0200 Subject: [PATCH 259/373] Abort creation if container ID or Root are empty. Signed-off-by: Ruben Jenster --- create.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/create.go b/create.go index ee76eebd..29c211e0 100644 --- a/create.go +++ b/create.go @@ -76,6 +76,17 @@ func (rt *Runtime) CheckSystem() error { } func (rt *Runtime) checkConfig(config *ContainerConfig) error { + if len(config.ContainerID) == 0 { + return fmt.Errorf("missing container ID") + } + + if config.Root == nil { + return fmt.Errorf("config.Root is nil") + } + if len(config.Root.Path) == 0 { + return fmt.Errorf("empty config.Root.Path") + } + if config.Linux.Resources == nil { config.Linux.Resources = &specs.LinuxResources{} } From 52bca7a1c6080682f926c5bcfb78c12ccdd7f975 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:08:21 +0200 Subject: [PATCH 260/373] Disable systemd cgroup path decoding in DefaultRuntime. Signed-off-by: Ruben Jenster --- runtime.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime.go b/runtime.go index 083b4da2..cada4407 100644 --- a/runtime.go +++ b/runtime.go @@ -91,10 +91,9 @@ type Runtime struct { // DefaultRuntime is the default runtime instance // used by all static wrapper functions. var DefaultRuntime = &Runtime{ - Log: log.ConsoleLogger(true), - Root: "/var/run/lxcri", - SystemdCgroup: true, - LibexecDir: "/usr/libexec/lxcri", + Log: log.ConsoleLogger(true), + Root: "/var/run/lxcri", + LibexecDir: "/usr/libexec/lxcri", Features: RuntimeFeatures{ Seccomp: true, From f82bab1755d3aa8c9f0fccca7fbd8f072baa114e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:09:12 +0200 Subject: [PATCH 261/373] Document Container.ContainerID Signed-off-by: Ruben Jenster --- container.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/container.go b/container.go index ffa4b12d..fc1a6fef 100644 --- a/container.go +++ b/container.go @@ -18,6 +18,10 @@ import ( type ContainerConfig struct { *specs.Spec + // ContainerID is the identifier of the container. + // The ContainerID is used as name for the containers runtime directory. + // The ContainerID must be unique at least through all containers of a runtime. + // The ContainerID should match the following pattern `[a-z][a-z0-9-_]+` ContainerID string BundlePath string From 7082b19fd1a7562297b351eb4cd9eab4326784bd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:09:39 +0200 Subject: [PATCH 262/373] Remove unused code Signed-off-by: Ruben Jenster --- runtime.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/runtime.go b/runtime.go index cada4407..bc7a092f 100644 --- a/runtime.go +++ b/runtime.go @@ -202,26 +202,12 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { ctx, cancel := context.WithCancel(ctx) defer cancel() - /* - go func() { - // NOTE this goroutine may leak until lxcri-start is terminated - ps, err := cmd.Process.Wait() - if err != nil { - rt.Log.Error().Err(err).Msg("failed to wait for start process") - } else { - rt.Log.Warn().Int("pid", cmd.Process.Pid).Stringer("status", ps).Msg("start process terminated") - } - cancel() - }() - */ - rt.Log.Debug().Msg("waiting for init") if err := c.waitCreated(ctx); err != nil { return err } rt.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") - // FIXME set PID to container config ? c.CreatedAt = time.Now() c.Pid = cmd.Process.Pid return nil From 4c12a97442b166eb1307ea022f4f671931aea4c9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:40:59 +0200 Subject: [PATCH 263/373] Add NewSpec and NewSpecProcess API methods. NewSpec returns a minimal specs.Spec instance containing everything that is required to create a new container. It can be used to quickly create containers for testing. Signed-off-by: Ruben Jenster --- create.go | 8 -------- devices.go | 32 ++++++++++++++------------------ runtime.go | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/create.go b/create.go index 29c211e0..bc054f87 100644 --- a/create.go +++ b/create.go @@ -87,14 +87,6 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { return fmt.Errorf("empty config.Root.Path") } - if config.Linux.Resources == nil { - config.Linux.Resources = &specs.LinuxResources{} - } - - if config.Linux.Devices == nil { - config.Linux.Devices = make([]specs.LinuxDevice, 0, 20) - } - if config.Process == nil { return fmt.Errorf("config.Process is nil") } diff --git a/devices.go b/devices.go index 918812d3..cba55c17 100644 --- a/devices.go +++ b/devices.go @@ -7,6 +7,19 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) +var defaultDevices = []specs.LinuxDevice{ + specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, + specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, + specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, + specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, + specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, + specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, + // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? + // `man 2 mount` | devpts + // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. + // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` +} + func isDeviceEnabled(c *Container, dev specs.LinuxDevice) bool { for _, specDev := range c.Linux.Devices { if specDev.Path == dev.Path { @@ -39,31 +52,14 @@ func ensureDefaultDevices(c *Container) error { mode := os.FileMode(0666) var uid, gid uint32 = c.Process.User.UID, c.Process.User.GID - devices := []specs.LinuxDevice{ - specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, - specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, - specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, - specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, - specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, - specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, - // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? - // `man 2 mount` | devpts - // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. - // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` - } - ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} addDevicePerms(c, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} addDevicePerms(c, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] - if c.Linux.Resources == nil { - c.Linux.Resources = &specs.LinuxResources{} - } - // add missing default devices - for _, dev := range devices { + for _, dev := range defaultDevices { if !isDeviceEnabled(c, dev) { addDevice(c, dev, mode, uid, gid, "rwm") } diff --git a/runtime.go b/runtime.go index bc7a092f..4df5f5a0 100644 --- a/runtime.go +++ b/runtime.go @@ -297,7 +297,7 @@ func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { // spec from the given path. // This is a convenience function for the cli. func ReadSpecJSON(p string) (*specs.Spec, error) { - spec := &specs.Spec{} + spec := new(specs.Spec) err := decodeFileJSON(spec, p) return spec, err } @@ -310,3 +310,47 @@ func ReadSpecProcessJSON(src string) (*specs.Process, error) { err := decodeFileJSON(proc, src) return proc, err } + +// NewSpec returns a minimal spec.Spec instance, which is +// required to run the given process within a container +// using the given rootfs. +// NOTE /proc and /dev folders must be present within the given rootfs. +func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { + proc := NewSpecProcess(cmd, args...) + + return &specs.Spec{ + Linux: &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + // isolate all namespaces by default + specs.LinuxNamespace{Type: specs.PIDNamespace}, + specs.LinuxNamespace{Type: specs.MountNamespace}, + specs.LinuxNamespace{Type: specs.IPCNamespace}, + specs.LinuxNamespace{Type: specs.UTSNamespace}, + specs.LinuxNamespace{Type: specs.CgroupNamespace}, + specs.LinuxNamespace{Type: specs.NetworkNamespace}, + }, + Resources: &specs.LinuxResources{}, + Devices: defaultDevices, + }, + Mounts: []specs.Mount{ + specs.Mount{Destination: "/proc", Source: "proc", Type: "proc", + Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, + }, + specs.Mount{Destination: "/dev", Source: "tmpfs", Type: "tmpfs", + Options: []string{"rw", "nosuid", "noexec", "relatime"}, + }, + }, + Process: proc, + Root: &specs.Root{Path: rootfs}, + } +} + +// NewSpecProcess creates a specs.Process instance +// from the given command cmd and the command arguments args. +func NewSpecProcess(cmd string, args ...string) *specs.Process { + proc := new(specs.Process) + proc.Args = append(proc.Args, cmd) + proc.Args = append(proc.Args, args...) + proc.Cwd = "/" + return proc +} From 4772736ed0e85bded8f2f18b61008578f0a9bcc9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 20:52:18 +0200 Subject: [PATCH 264/373] Add runtime tests. Signed-off-by: Ruben Jenster --- .gitignore | 1 + Makefile | 9 +- cmd/lxcri-start/lxcri-start.c | 3 +- cmd/lxcri-test/main.go | 29 ++++++ runtime_test.go | 160 ++++++++++++++++++++++++++++++++++ 5 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 cmd/lxcri-test/main.go create mode 100644 runtime_test.go diff --git a/.gitignore b/.gitignore index 72a57242..f23531e8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /lxcri-start /lxcri-init /lxcri-hook +/lxcri-test .stacker/ diff --git a/Makefile b/Makefile index 19a05589..750e0fa7 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ MUSL_CC ?= musl-gcc SHELL_SCRIPTS = $(shell find . -name \*.sh) GO_SRC = $(shell find . -name \*.go | grep -v _test.go) -all: fmt test build +all: fmt test update-tools: GO111MODULE=off go get -u mvdan.cc/sh/v3/cmd/shfmt @@ -28,12 +28,13 @@ fmt: go mod tidy .PHONY: test -test: - go test -v ./... +test: build + go build ./cmd/lxcri-test + go test --count 1 -v ./... build: $(BINS) $(LIBEXEC_BINS) -lxcri: go.mod $(GO_SRC) +lxcri: go.mod $(GO_SRC) Makefile go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri lxcri-start: cmd/lxcri-start/lxcri-start.c diff --git a/cmd/lxcri-start/lxcri-start.c b/cmd/lxcri-start/lxcri-start.c index 25abacd9..34078370 100644 --- a/cmd/lxcri-start/lxcri-start.c +++ b/cmd/lxcri-start/lxcri-start.c @@ -67,8 +67,9 @@ int main(int argc, char **argv) if (!c->start(c, ENABLE_LXCINIT, NULL)) ERROR("failed to start container\n"); + /* Try to die with the same signal the task did. */ + /* FIXME error_num is zero if init was killed with SIGHUP */ if (WIFSIGNALED(c->error_num)) - /* Try to die with the same signal the task did. */ kill(0, WTERMSIG(c->error_num)); if (WIFEXITED(c->error_num)) diff --git a/cmd/lxcri-test/main.go b/cmd/lxcri-test/main.go new file mode 100644 index 00000000..561b0af5 --- /dev/null +++ b/cmd/lxcri-test/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "os" + "os/signal" + "syscall" + "time" +) + +func main() { + + sigs := make(chan os.Signal, 1) + + // SIGHUP by default terminates the process, if the process does not catch it. + // `nohup` can be used ignore it. + // see https://en.wikipedia.org/wiki/SIGHUP + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1) + + go func() { + sig := <-sigs + fmt.Println() + fmt.Println("received signal:", sig) + }() + + fmt.Printf("%#v\n", os.Args) + println("sleeping for 30 seconds") + time.Sleep(time.Second * 30) +} diff --git a/runtime_test.go b/runtime_test.go new file mode 100644 index 00000000..af843212 --- /dev/null +++ b/runtime_test.go @@ -0,0 +1,160 @@ +package lxcri + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" +) + +// Create a package test ? test.NewRuntime() + +func newRuntime(t *testing.T) *Runtime { + runtimeRoot, err := os.MkdirTemp("", "lxcri-test") + require.NoError(t, err) + t.Logf("runtime root: %s", runtimeRoot) + + return &Runtime{ + Log: DefaultRuntime.Log, + Root: runtimeRoot, + LibexecDir: "/usr/local/libexec/lxcri", + Features: DefaultRuntime.Features, + } +} + +func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { + rootfs, err := os.MkdirTemp("", "lxcri-test") + require.NoError(t, err) + t.Logf("container rootfs: %s", rootfs) + + // copy binary to rootfs + err = exec.Command("cp", cmd, rootfs).Run() + require.NoError(t, err) + // create /proc and /dev in rootfs + err = os.MkdirAll(filepath.Join(rootfs, "dev"), 0755) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(rootfs, "proc"), 0755) + require.NoError(t, err) + + spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) + id := filepath.Base(rootfs) + cfg := ContainerConfig{ContainerID: id, Spec: spec} + cfg.LogFile = "/dev/stderr" + cfg.LogLevel = "info" + return &cfg +} + +func TestRuntimeNamespaceCheck(t *testing.T) { + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Root.Path) + + // Clearing all namespaces should not work. + // At least PID and MOUNT must not be shared with the host. + cfg.Linux.Namespaces = cfg.Linux.Namespaces[0:0] + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + c, err := rt.Create(ctx, cfg) + require.Error(t, err) + require.Nil(t, c) + + pidns := specs.LinuxNamespace{ + Type: specs.PIDNamespace, + Path: fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()), + } + cfg.Linux.Namespaces = append(cfg.Linux.Namespaces, pidns) + + c, err = rt.Create(ctx, cfg) + require.Error(t, err) + require.Nil(t, c) +} + +func TestRuntimeKill(t *testing.T) { + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Root.Path) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + c, err := rt.Create(ctx, cfg) + require.NoError(t, err) + require.NotNil(t, c) + + state, err := c.State() + require.NoError(t, err) + require.Equal(t, specs.StateCreated, state.Status) + + err = rt.Start(ctx, c) + require.NoError(t, err) + + state, err = c.State() + require.NoError(t, err) + require.Equal(t, specs.StateRunning, state.Status) + + // Must wait otherwise init process signal handlers may not + // yet be established and then sending SIGHUP will kill the container + // + err = rt.Kill(ctx, c, unix.SIGUSR1) + require.NoError(t, err) + + state, err = c.State() + require.NoError(t, err) + require.Equal(t, specs.StateRunning, state.Status) + + // SIGHUP by default terminates a process if it is not ignored or catched by + // a signal handler + err = rt.Kill(ctx, c, unix.SIGKILL) + require.NoError(t, err) + + time.Sleep(time.Millisecond * 50) + + state, err = c.State() + require.NoError(t, err) + require.Equal(t, specs.StateStopped, state.Status) + + err = rt.Delete(ctx, c, false) + require.NoError(t, err) + + state, err = c.State() + require.NoError(t, err) + require.Equal(t, specs.StateStopped, state.Status) + + t.Log("done") + + err = c.Release() + require.NoError(t, err) + + /* + p, err := os.FindProcess(c.Pid) + require.NoError(t, err) + pstate, err := p.Wait() + require.NoError(t, err) + // The exit code should be non-zero because the process was terminated + // by a signal + fmt.Printf("monitor process exited %T: %s code:%d\n", pstate, pstate, pstate.ExitCode()) + */ + + // manpage for 'wait4' suggests to use waitpid or waitid instead, but + // golang/x/sys/unix only implements 'Wait4'. See https://github.com/golang/go/issues/9176 + var ws unix.WaitStatus + _, err = unix.Wait4(c.Pid, &ws, 0, nil) + require.NoError(t, err) + fmt.Printf("ws:0x%x exited:%t exit_status:%d signaled:%t signal:%d\n", ws, ws.Exited(), ws.ExitStatus(), ws.Signaled(), ws.Signal()) + + // NOTE it seems that the go test framework reaps all remaining children. + // It's reasonable that no process started from the tests will survive the test run. +} From 3662396af8eb873e02da4a57bf3114e39507c918 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 21:00:08 +0200 Subject: [PATCH 265/373] Added missing godoc and disarm golint workflow step. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 1 - log/log.go | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a018e9e9..7f53063d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,6 @@ jobs: run: | GO111MODULE=off go get -u golang.org/x/lint/golint golint -set_exit_status ./... - continue-on-error: true - name: Install dependencies run: | diff --git a/log/log.go b/log/log.go index 6f77e533..001ad006 100644 --- a/log/log.go +++ b/log/log.go @@ -12,8 +12,6 @@ import ( "github.com/rs/zerolog" ) -// TODO log to systemd journal ? - func init() { zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" @@ -25,13 +23,14 @@ func init() { return time.Now().UTC() } - // TODO only log caller information in debug and trace level zerolog.CallerFieldName = "c" zerolog.CallerMarshalFunc = func(file string, line int) string { return filepath.Base(file) + ":" + strconv.Itoa(line) } } +// OpenFile opens a new or appends to an existing log file. +// The parent directory is created if it does not exist. func OpenFile(name string, mode os.FileMode) (*os.File, error) { logDir := filepath.Dir(name) err := os.MkdirAll(logDir, 0750) @@ -41,10 +40,13 @@ func OpenFile(name string, mode os.FileMode) (*os.File, error) { return os.OpenFile(name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, mode) } +// ParseLevel is a wrapper for zerolog.ParseLevel func ParseLevel(level string) (zerolog.Level, error) { return zerolog.ParseLevel(strings.ToLower(level)) } +// NewLogger creates a new zerlog.Context from the given arguments. +// The returned context is configured to log with timestamp and caller information. func NewLogger(out io.Writer, level zerolog.Level) zerolog.Context { // NOTE Unfortunately it's not possible change the possition of the timestamp. // The ttimestamp is appended to the to the log output because it is dynamically rendered @@ -52,6 +54,7 @@ func NewLogger(out io.Writer, level zerolog.Level) zerolog.Context { return zerolog.New(out).Level(level).With().Timestamp().Caller() } +// ConsoleLogger returns a new zerlog.Logger suited for console usage (e.g unit tests) func ConsoleLogger(color bool) zerolog.Logger { return zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: !color}).Level(zerolog.DebugLevel).With().Timestamp().Caller().Logger() } From e403f8ec6efaef1eb2f4ee7af5ddc104a84af245 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 22:57:37 +0200 Subject: [PATCH 266/373] Add missing Log to container. Signed-off-by: Ruben Jenster --- runtime_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_test.go b/runtime_test.go index af843212..ade32a08 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -45,7 +45,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) - cfg := ContainerConfig{ContainerID: id, Spec: spec} + cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: DefaultRuntime.Log} cfg.LogFile = "/dev/stderr" cfg.LogLevel = "info" return &cfg From c64df9ce926c2a96e359c88c53b0c2d35d9068c7 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 1 Apr 2021 22:58:05 +0200 Subject: [PATCH 267/373] Allow sharing PID namespace again, but warn about it. Signed-off-by: Ruben Jenster --- create.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/create.go b/create.go index bc054f87..c2e3b020 100644 --- a/create.go +++ b/create.go @@ -100,15 +100,22 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { config.Process.Cwd = "/" } - mustNotShareHostNamespaces := []specs.LinuxNamespaceType{specs.PIDNamespace, specs.MountNamespace} - for _, n := range mustNotShareHostNamespaces { - yes, err := isHostNamespaceShared(config.Linux.Namespaces, n) - if err != nil { - return err - } - if yes { - return fmt.Errorf("container wants to share the hosts %q namespace", n) - } + yes, err := isHostNamespaceShared(config.Linux.Namespaces, specs.MountNamespace) + if err != nil { + return err + } + if yes { + return fmt.Errorf("container wants to share the hosts mount namespace") + } + + // It should be best practise not to do so, but there are containers that + // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set + yes, err = isHostNamespaceShared(config.Linux.Namespaces, specs.PIDNamespace) + if err != nil { + return err + } + if yes { + rt.Log.Info().Msg("container wil share the hosts PID namespace") } return nil } From b6528a06abd927752eabd9da31f716dc0e093c48 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 3 Apr 2021 22:17:55 +0200 Subject: [PATCH 268/373] github workflow: Use sudo to run install and test step. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f53063d..9f48e52a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,4 +41,6 @@ jobs: run: make build - name: Run tests - run: make test + run: | + sudo make install + sudo make test From c611b9b37340acdf8997fd4c865909002f1fe955 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 3 Apr 2021 22:32:07 +0200 Subject: [PATCH 269/373] Add caller information to errors. Qualify pass-through errors and use errorf to add caller information to errors returned from the top of the call stack. Signed-off-by: Ruben Jenster --- create.go | 20 ++++++++++---------- init.go | 22 ++++++++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/create.go b/create.go index c2e3b020..e1268a81 100644 --- a/create.go +++ b/create.go @@ -77,22 +77,22 @@ func (rt *Runtime) CheckSystem() error { func (rt *Runtime) checkConfig(config *ContainerConfig) error { if len(config.ContainerID) == 0 { - return fmt.Errorf("missing container ID") + return errorf("missing container ID") } if config.Root == nil { - return fmt.Errorf("config.Root is nil") + return errorf("config.Root is nil") } if len(config.Root.Path) == 0 { - return fmt.Errorf("empty config.Root.Path") + return errorf("empty config.Root.Path") } if config.Process == nil { - return fmt.Errorf("config.Process is nil") + return errorf("config.Process is nil") } if len(config.Process.Args) == 0 { - return fmt.Errorf("configs.Process.Args is empty") + return errorf("configs.Process.Args is empty") } if config.Process.Cwd == "" { @@ -105,7 +105,7 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { return err } if yes { - return fmt.Errorf("container wants to share the hosts mount namespace") + return errorf("container wants to share the hosts mount namespace") } // It should be best practise not to do so, but there are containers that @@ -135,19 +135,19 @@ func configureContainer(rt *Runtime, c *Container) error { } if err := configureRootfs(c); err != nil { - return err + return fmt.Errorf("failed to configure rootfs: %w", err) } if err := configureInit(rt, c); err != nil { - return err + return fmt.Errorf("failed to configure init: %w", err) } if err := configureMounts(rt, c); err != nil { - return err + return fmt.Errorf("failed to configure mounts: %w", err) } if err := configureReadonlyPaths(c); err != nil { - return err + return fmt.Errorf("failed to configure read-only paths: %w", err) } if err := configureNamespaces(c); err != nil { diff --git a/init.go b/init.go index a2459e2a..ce85da9a 100644 --- a/init.go +++ b/init.go @@ -19,9 +19,12 @@ const ( func createFifo(dst string, uid int, gid int, mode uint32) error { if err := unix.Mkfifo(dst, mode); err != nil { - return err + return fmt.Errorf("mkfifo dst:%s mode:%o failed: %w", dst, mode, err) + } + if err := unix.Chown(dst, uid, gid); err != nil { + return fmt.Errorf("chown uid:%d gid:%d dst:%s failed: %w", uid, gid, dst, err) } - return unix.Chown(dst, uid, gid) + return nil } func configureInit(rt *Runtime, c *Container) error { @@ -109,28 +112,31 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err // #nosec f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) if err != nil { - return err + return errorf("failed to create %s: %w", dst, err) } for _, arg := range entries { _, err := f.WriteString(arg) if err != nil { f.Close() - return err + return errorf("failed to write to %s: %w", dst, err) } _, err = f.Write([]byte{'\000'}) if err != nil { f.Close() - return err + return errorf("failed to write to %s: %w", dst, err) } } if err := f.Close(); err != nil { - return err + return errorf("failed to close %s: %w", dst, err) } if err := unix.Chown(dst, uid, gid); err != nil { - return err + return errorf("failed to chown %s uid:%d gid:%d :%w", dst, uid, gid, err) } - return unix.Chmod(dst, mode) + if err := unix.Chmod(dst, mode); err != nil { + return errorf("failed to chmod %s mode:%o : %w", dst, mode, err) + } + return nil } func configureInitUser(c *Container) error { From 7527e4f3a8e06b7a1b191ac61784b55d78bb02ac Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 16:27:11 +0200 Subject: [PATCH 270/373] unprivileged fixes Signed-off-by: Ruben Jenster --- Makefile | 2 ++ cgroup.go | 34 +++++++++++++------ cmd/lxcri/cli.go | 2 +- container.go | 29 +++++++++-------- create.go | 69 ++++++++++++++++++++++++++++++++------- devices.go | 4 +-- init.go | 47 +++++++++++++++----------- mount.go | 14 ++++---- mount_test.go | 6 ++-- runtime.go | 77 +++++++++++++++---------------------------- runtime_test.go | 85 ++++++++++++++++++++++++++++++++++++++++-------- utils.go | 1 + 12 files changed, 239 insertions(+), 131 deletions(-) diff --git a/Makefile b/Makefile index 750e0fa7..9c0c2784 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,9 @@ BINS := lxcri LIBEXEC_BINS := lxcri-start lxcri-init lxcri-hook # Installation prefix for BINS PREFIX ?= /usr/local +export PREFIX LIBEXEC_DIR = $(PREFIX)/libexec/lxcri +export LIBEXEC_DIR PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig # Note: The default pkg-config directory is search after PKG_CONFIG_PATH # Note: (Exported) environment variables are NOT visible in the environment of the $(shell ...) function. diff --git a/cgroup.go b/cgroup.go index f1c4721c..f50addae 100644 --- a/cgroup.go +++ b/cgroup.go @@ -17,9 +17,24 @@ import ( const ( allControllers = "+cpuset +cpu +io +memory +hugetlb +pids +rdma" - cgroupRoot = "/sys/fs/cgroup" ) +var cgroupRoot string + +func detectCgroupRoot() string { + if err := isFilesystem("/sys/fs/cgroup", "cgroup2"); err == nil { + return "/sys/fs/cgroup" + } + if err := isFilesystem("/sys/fs/cgroup/unified", "cgroup2"); err == nil { + return "/sys/fs/cgroup/unified" + } + return "" +} + +func init() { + cgroupRoot = detectCgroupRoot() +} + // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md // TODO New spec will contain a property Unified for cgroupv2 properties // https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#unified @@ -69,10 +84,7 @@ func configureCgroup(rt *Runtime, c *Container) error { } func configureCgroupPath(rt *Runtime, c *Container) error { - if c.Linux.CgroupsPath == "" { - //return fmt.Errorf("empty cgroups path in spec") - c.Linux.CgroupsPath = "foo.slice" - } + if rt.SystemdCgroup { c.CgroupDir = parseSystemdCgroupPath(c.Linux.CgroupsPath) } else { @@ -81,9 +93,11 @@ func configureCgroupPath(rt *Runtime, c *Container) error { c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") - if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { - return err - } + /* + if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { + return err + } + */ if err := c.SetConfigItem("lxc.cgroup.relative", "0"); err != nil { return err @@ -94,8 +108,8 @@ func configureCgroupPath(rt *Runtime, c *Container) error { } /* - if c.supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { + if c.SupportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroupDir); err != nil { return err } } diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 160f70df..074485aa 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -290,7 +290,7 @@ var createCmd = cli.Command{ } func doCreate(ctxcli *cli.Context) error { - if err := clxc.CheckSystem(); err != nil { + if err := clxc.Init(); err != nil { return err } specPath := filepath.Join(clxc.cfg.BundlePath, "config.json") diff --git a/container.go b/container.go index fc1a6fef..102e5e02 100644 --- a/container.go +++ b/container.go @@ -81,14 +81,19 @@ func (c *Container) create() error { if c.runtimeDirExists() { return ErrExist } - if err := os.MkdirAll(c.runtimeDir, 0700); err != nil { + + if err := os.MkdirAll(c.runtimeDir, 0777); err != nil { return fmt.Errorf("failed to create container dir: %w", err) } + if err := os.Chmod(c.runtimeDir, 0777); err != nil { + return errorf("failed to chmod %s: %w", err) + } + // An empty tmpfile is created to ensure that createContainer can only succeed once. // The config file is atomically activated in SaveConfig. // #nosec - f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0666) if err != nil { return err } @@ -288,22 +293,18 @@ func (c *Container) kill(ctx context.Context, signum unix.Signal) error { // Any config changes via clxc.setConfigItem must be done before calling SaveConfig. // FIXME revise the config file mechanism func (c *Container) saveConfig() error { - // createContainer creates the tmpfile - tmpFile := c.RuntimePath(".config") - if _, err := os.Stat(tmpFile); err != nil { - return fmt.Errorf("failed to stat config tmpfile: %w", err) - } // Don't overwrite an existing config. cfgFile := c.ConfigFilePath() - if _, err := os.Stat(cfgFile); err == nil { - return fmt.Errorf("config file %s already exists", cfgFile) - } - err := c.LinuxContainer.SaveConfigFile(tmpFile) + + f, err := os.OpenFile(cfgFile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0640) if err != nil { - return fmt.Errorf("failed to save config file to %q: %w", tmpFile, err) + return errorf("failed to create config file %q: %w", cfgFile, err) } - if err := os.Rename(tmpFile, cfgFile); err != nil { - return fmt.Errorf("failed to rename config file: %w", err) + f.Close() + + err = c.LinuxContainer.SaveConfigFile(cfgFile) + if err != nil { + return errorf("failed to save config file to %q: %w", cfgFile, err) } return nil } diff --git a/create.go b/create.go index e1268a81..9292aaa2 100644 --- a/create.go +++ b/create.go @@ -16,6 +16,7 @@ import ( // You may have to call Runtime.Delete to cleanup container runtime state, // if Create returns with an error. func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { + if err := rt.checkConfig(cfg); err != nil { return nil, err } @@ -47,11 +48,22 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, err } -// CheckSystem checks the hosts system configuration. +// Init initializes the runtime instance. +// It creates required directories and checks the hosts system configuration. // Unsupported runtime features are disabled and a warning message is logged. -// CheckSystem is not called internally, but it recommended to -// call it once for a runtime instance before calling any other method. -func (rt *Runtime) CheckSystem() error { +// Init must be called once for a runtime instance before calling any other method. +func (rt *Runtime) Init() error { + + rt.rootfsMount = filepath.Join(rt.Root, ".rootfs") + if err := os.MkdirAll(rt.rootfsMount, 0777); err != nil { + return errorf("failed to create directory for rootfs mount %s: %w", rt.rootfsMount, err) + } + if err := os.Chmod(rt.rootfsMount, 0777); err != nil { + return errorf("failed to 'chmod 0777 %s': %w", err) + } + + rt.privileged = os.Getuid() == 0 + err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) if err != nil { return errorf("access check failed: %w", err) @@ -134,7 +146,7 @@ func configureContainer(rt *Runtime, c *Container) error { } } - if err := configureRootfs(c); err != nil { + if err := configureRootfs(rt, c); err != nil { return fmt.Errorf("failed to configure rootfs: %w", err) } @@ -150,6 +162,15 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure read-only paths: %w", err) } + if !rt.privileged { + // ensure user namespace is enabled + if !isNamespaceEnabled(c.Spec, specs.UserNamespace) { + rt.Log.Warn().Msg("unprivileged runtime - enabling user namespace") + c.Linux.Namespaces = append(c.Linux.Namespaces, + specs.LinuxNamespace{Type: specs.UserNamespace}, + ) + } + } if err := configureNamespaces(c); err != nil { return fmt.Errorf("failed to configure namespaces: %w", err) } @@ -200,12 +221,33 @@ func configureContainer(rt *Runtime, c *Container) error { if err := c.SetConfigItem("lxc.autodev", "0"); err != nil { return err } - if err := ensureDefaultDevices(c); err != nil { - return fmt.Errorf("failed to add default devices: %w", err) - } - if err := writeDevices(c.RuntimePath("devices.txt"), c); err != nil { - return fmt.Errorf("failed to create devices.txt: %w", err) + ensureDefaultDevices(c) + + if rt.privileged { + // devices are created with mknod in lxcri-hook + if err := writeDevices(c.RuntimePath("devices.txt"), c); err != nil { + return fmt.Errorf("failed to create devices.txt: %w", err) + } + + } else { + // if running as non-root bind mount devices, because user can not execute mknod + newMounts := make([]specs.Mount, 0, len(c.Mounts)+len(c.Linux.Devices)) + for _, m := range c.Mounts { + if m.Destination == "/dev" { + rt.Log.Info().Msg("unprivileged runtime - removing /dev mount") + continue + } + newMounts = append(newMounts, m) + } + rt.Log.Info().Msg("unprivileged runtime - bind mount devices") + for _, device := range c.Linux.Devices { + newMounts = append(newMounts, + specs.Mount{Destination: device.Path, Source: device.Path, Type: "bind", Options: []string{"bind", "create=file"}}, + ) + } + + c.Mounts = newMounts } if err := writeMasked(c.RuntimePath("masked.txt"), c); err != nil { @@ -254,10 +296,15 @@ func configureContainer(rt *Runtime, c *Container) error { return nil } -func configureRootfs(c *Container) error { +func configureRootfs(rt *Runtime, c *Container) error { if err := c.SetConfigItem("lxc.rootfs.path", c.Root.Path); err != nil { return err } + + if err := c.SetConfigItem("lxc.rootfs.mount", rt.rootfsMount); err != nil { + return err + } + if err := c.SetConfigItem("lxc.rootfs.managed", "0"); err != nil { return err } diff --git a/devices.go b/devices.go index cba55c17..24ee7ff7 100644 --- a/devices.go +++ b/devices.go @@ -34,7 +34,6 @@ func addDevice(c *Container, dev specs.LinuxDevice, mode os.FileMode, uid uint32 dev.UID = &uid dev.GID = &gid c.Linux.Devices = append(c.Linux.Devices, dev) - addDevicePerms(c, dev.Type, &dev.Major, &dev.Minor, access) } @@ -48,7 +47,7 @@ func addDevicePerms(c *Container, devType string, major *int64, minor *int64, ac // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(c *Container) error { +func ensureDefaultDevices(c *Container) { mode := os.FileMode(0666) var uid, gid uint32 = c.Process.User.UID, c.Process.User.GID @@ -64,7 +63,6 @@ func ensureDefaultDevices(c *Container) error { addDevice(c, dev, mode, uid, gid, "rwm") } } - return nil } func writeDevices(dst string, c *Container) error { diff --git a/init.go b/init.go index ce85da9a..9bbf39fc 100644 --- a/init.go +++ b/init.go @@ -17,26 +17,33 @@ const ( initDir = "/.lxcri" ) -func createFifo(dst string, uid int, gid int, mode uint32) error { - if err := unix.Mkfifo(dst, mode); err != nil { - return fmt.Errorf("mkfifo dst:%s mode:%o failed: %w", dst, mode, err) - } - if err := unix.Chown(dst, uid, gid); err != nil { - return fmt.Errorf("chown uid:%d gid:%d dst:%s failed: %w", uid, gid, dst, err) +func createFifo(dst string) error { + if err := unix.Mkfifo(dst, 0666); err != nil { + return errorf("mkfifo dst:%s failed: %w", dst, err) + } + // lxcri-init must be able to write to the fifo. + // Init process UID/GID can be different from runtime process UID/GID + // liblxc changes the owner of the runtime directory to the effective container UID. + // access to the files is protected by the runtimeDir + // because umask (0022) affects unix.Mkfifo, a separate chmod is required + if err := unix.Chmod(dst, 0666); err != nil { + return errorf("chmod mkfifo failed: %w", err) } return nil } func configureInit(rt *Runtime, c *Container) error { runtimeInitDir := c.RuntimePath(initDir) - rootfsInitDir := filepath.Join(c.Root.Path, initDir) + //rootfsInitDir := filepath.Join(c.Root.Path, initDir) - err := os.MkdirAll(rootfsInitDir, 0) - if err != nil { - return fmt.Errorf("failed to create init dir in rootfs %q: %w", rootfsInitDir, err) - } + /* + err := os.MkdirAll(rootfsInitDir, 0755) + if err != nil { + return fmt.Errorf("failed to create init dir in rootfs %q: %w", rootfsInitDir, err) + } + */ // #nosec - err = os.MkdirAll(runtimeInitDir, 0755) + err := os.MkdirAll(runtimeInitDir, 0755) if err != nil { return fmt.Errorf("failed to create runtime init dir %q: %w", runtimeInitDir, err) } @@ -45,7 +52,7 @@ func configureInit(rt *Runtime, c *Container) error { Source: runtimeInitDir, Destination: strings.TrimLeft(initDir, "/"), Type: "bind", - Options: []string{"bind", "ro", "nodev", "nosuid"}, + Options: []string{"bind", "ro", "nodev", "nosuid", "create=dir"}, }) if err := c.SetConfigItem("lxc.init.cwd", initDir); err != nil { @@ -56,14 +63,14 @@ func configureInit(rt *Runtime, c *Container) error { gid := int(c.Process.User.GID) // create files required for lxcri-init - if err := createFifo(c.syncFifoPath(), uid, gid, 0600); err != nil { + if err := createFifo(c.syncFifoPath()); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, uid, gid, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, uid, gid, 0440); err != nil { return err } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, uid, gid, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, uid, gid, 0440); err != nil { return err } if err := os.Symlink(c.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { @@ -130,9 +137,11 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err if err := f.Close(); err != nil { return errorf("failed to close %s: %w", dst, err) } - if err := unix.Chown(dst, uid, gid); err != nil { - return errorf("failed to chown %s uid:%d gid:%d :%w", dst, uid, gid, err) - } + /* + if err := unix.Chown(dst, uid, gid); err != nil { + return errorf("failed to chown %s uid:%d gid:%d :%w", dst, uid, gid, err) + } + */ if err := unix.Chmod(dst, mode); err != nil { return errorf("failed to chmod %s mode:%o : %w", dst, mode, err) } diff --git a/mount.go b/mount.go index 1f49afd2..6cb53284 100644 --- a/mount.go +++ b/mount.go @@ -74,9 +74,11 @@ func configureMounts(rt *Runtime, c *Container) error { } ms.Destination = mountDest - err = createMountDestination(c, &ms) - if err != nil { - return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) + if c.Root.Readonly { + err = createMountDestination(c, &ms) + if err != nil { + return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) + } } ms.Options = filterMountOptions(rt, ms.Type, ms.Options) @@ -112,10 +114,10 @@ func createMountDestination(spec *Container, ms *specs.Mount) error { ms.Options = append(ms.Options, "create=file") // source exists and is not a directory // create a target file that can be used as target for a bind mount - if err := mkdirAll(filepath.Dir(ms.Destination), 0750, uid, gid); err != nil { + if err := mkdirAll(filepath.Dir(ms.Destination), 0755, uid, gid); err != nil { return fmt.Errorf("failed to create mount destination dir: %w", err) } - f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0) + f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0755) if err != nil { return fmt.Errorf("failed to create file mountpoint: %w", err) } @@ -124,7 +126,7 @@ func createMountDestination(spec *Container, ms *specs.Mount) error { ms.Options = append(ms.Options, "create=dir") // FIXME exclude all directories that are below other mounts // only directories / files on the readonly rootfs must be created - if err = mkdirAll(ms.Destination, 0750, uid, gid); err != nil { + if err = mkdirAll(ms.Destination, 0755, uid, gid); err != nil { return fmt.Errorf("failed to create mount target dir: %w", err) } return nil diff --git a/mount_test.go b/mount_test.go index 473082a5..92a52a49 100644 --- a/mount_test.go +++ b/mount_test.go @@ -74,10 +74,10 @@ func TestResolveMountDestination_relative(t *testing.T) { func TestFilterMountOptions(t *testing.T) { opts := strings.Split("rw,rprivate,noexec,nosuid,nodev,tmpcopyup,create=dir", ",") - - out := filterMountOptions(DefaultRuntime, "tmpfs", opts) + rt := Runtime{} + out := filterMountOptions(&rt, "tmpfs", opts) require.Equal(t, []string{"rw", "noexec", "nosuid", "nodev", "create=dir"}, out) - out = filterMountOptions(DefaultRuntime, "nosuchfs", opts) + out = filterMountOptions(&rt, "nosuchfs", opts) require.Equal(t, opts, out) } diff --git a/runtime.go b/runtime.go index 4df5f5a0..a534c9ff 100644 --- a/runtime.go +++ b/runtime.go @@ -13,12 +13,10 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" - - "github.com/drachenfels-de/lxcri/log" ) // Required runtime executables loaded from Runtime.LibexecDir -const ( +var ( // ExecStart starts the liblxc monitor process, similar to lxc-start ExecStart = "lxcri-start" // ExecHook is run as liblxc hook and creates additional devices and remounts masked paths. @@ -70,6 +68,9 @@ type Runtime struct { // Directories for containers created by the runtime // are created within this directory. Root string + // rootfsMount is the directory where liblxc recursively binds + // the container rootfs before pivoting. + rootfsMount string // Use systemd encoded cgroup path (from crio-o/conmon) // is true if /etc/crio/crio.conf#cgroup_manager = "systemd" SystemdCgroup bool @@ -86,51 +87,9 @@ type Runtime struct { // These hooks are different from the hooks that are // defined within the OCI runtime spec. Hooks `json:"-"` -} - -// DefaultRuntime is the default runtime instance -// used by all static wrapper functions. -var DefaultRuntime = &Runtime{ - Log: log.ConsoleLogger(true), - Root: "/var/run/lxcri", - LibexecDir: "/usr/libexec/lxcri", - - Features: RuntimeFeatures{ - Seccomp: true, - Capabilities: true, - Apparmor: true, - CgroupDevices: true, - }, -} -// CheckSystem is a wrapper around DefaultRuntime.CheckSystem -func CheckSystem() error { - return DefaultRuntime.CheckSystem() -} - -// Create is a wrapper around DefaultRuntime.Create -func Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { - return DefaultRuntime.Create(ctx, cfg) -} - -// Load is a wrapper around DefaultRuntime.Load -func Load(containerID string) (*Container, error) { - return DefaultRuntime.Load(containerID) -} - -// Start is a wrapper around DefaultRuntime.Start -func Start(ctx context.Context, c *Container) error { - return DefaultRuntime.Start(ctx, c) -} - -// Kill is a wrapper around DefaultRuntime.Kill -func Kill(ctx context.Context, c *Container, signum unix.Signal) error { - return DefaultRuntime.Kill(ctx, c, signum) -} - -// Delete is a wrapper around DefaultRuntime.Delete -func Delete(ctx context.Context, c *Container, force bool) error { - return DefaultRuntime.Delete(ctx, c, force) + // privileged is set by Runtime.Init if user has root privileges. + privileged bool } func (rt *Runtime) libexec(name string) string { @@ -170,7 +129,8 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // #nosec cmd := exec.Command(rt.libexec(ExecStart), c.LinuxContainer.Name(), rt.Root, c.ConfigFilePath()) - cmd.Env = []string{} + println(os.Environ()) + cmd.Env = []string{"XDG_RUNTIME_DIR=/tmp/myrun", "PATH=/usr/bin"} cmd.Dir = c.RuntimePath() if c.ConsoleSocket == "" && !c.Process.Terminal { @@ -334,10 +294,11 @@ func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { }, Mounts: []specs.Mount{ specs.Mount{Destination: "/proc", Source: "proc", Type: "proc", - Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, + Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime", "create=dir"}, }, specs.Mount{Destination: "/dev", Source: "tmpfs", Type: "tmpfs", - Options: []string{"rw", "nosuid", "noexec", "relatime"}, + Options: []string{"rw", "nosuid", "noexec", "relatime", "dev", "create=dir"}, + // devtmpfs (rw,nosuid,relatime,size=6122620k,nr_inodes=1530655,mode=755,inode64) }, }, Process: proc, @@ -351,6 +312,22 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { proc := new(specs.Process) proc.Args = append(proc.Args, cmd) proc.Args = append(proc.Args, args...) + //proc.User = currentUser() proc.Cwd = "/" return proc } + +func currentUser() specs.User { + groups, _ := os.Getgroups() + gids := make([]uint32, len(groups)) + for i, g := range groups { + gids[i] = uint32(g) + } + return specs.User{ + UID: 0, + GID: 0, + //UID: uint32(os.Getuid()), + //GID: uint32(os.Getgid()), + AdditionalGids: []uint32{uint32(os.Getgid())}, + } +} diff --git a/runtime_test.go b/runtime_test.go index ade32a08..a04ede3f 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/drachenfels-de/lxcri/log" "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/require" "golang.org/x/sys/unix" @@ -16,21 +17,42 @@ import ( // Create a package test ? test.NewRuntime() +var tmpDir string + +/* +func init() { + // /tmp has permissions 1777 + // sticky bit prevents renaming .config to /config because + // liblxc modifies permissions if user namepaces with uid/gid mappings are enabled + if os.Getuid() != 0 { + tmpDir = os.Getenv("HOME") + } +} +*/ + func newRuntime(t *testing.T) *Runtime { - runtimeRoot, err := os.MkdirTemp("", "lxcri-test") + //wd, err := os.Getwd() + //require.NoError(t, err) + runtimeRoot, err := os.MkdirTemp(tmpDir, "lxcri-test") + require.NoError(t, err) + err = unix.Chmod(runtimeRoot, 0700) require.NoError(t, err) t.Logf("runtime root: %s", runtimeRoot) - return &Runtime{ - Log: DefaultRuntime.Log, + rt := &Runtime{ + Log: log.ConsoleLogger(true), Root: runtimeRoot, - LibexecDir: "/usr/local/libexec/lxcri", - Features: DefaultRuntime.Features, + LibexecDir: os.Getenv("LIBEXEC_DIR"), } + //ExecInit = "lxcri-debug" + require.NoError(t, rt.Init()) + return rt } func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { - rootfs, err := os.MkdirTemp("", "lxcri-test") + //wd, err := os.Getwd() + //require.NoError(t, err) + rootfs, err := os.MkdirTemp(tmpDir, "lxcri-test") require.NoError(t, err) t.Logf("container rootfs: %s", rootfs) @@ -38,16 +60,49 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { err = exec.Command("cp", cmd, rootfs).Run() require.NoError(t, err) // create /proc and /dev in rootfs - err = os.MkdirAll(filepath.Join(rootfs, "dev"), 0755) - require.NoError(t, err) - err = os.MkdirAll(filepath.Join(rootfs, "proc"), 0755) - require.NoError(t, err) + /* + err = os.MkdirAll(filepath.Join(rootfs, "dev"), 0755) + require.NoError(t, err) + err = os.MkdirAll(filepath.Join(rootfs, "proc"), 0555) + require.NoError(t, err) + */ spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) - cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: DefaultRuntime.Log} + cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true)} + cfg.Linux.CgroupsPath = "" // use /proc/self/cgroup" cfg.LogFile = "/dev/stderr" - cfg.LogLevel = "info" + cfg.LogLevel = "trace" + + if os.Getuid() != 0 { + // get UID/GID mapping from /etc/subgid /etc/subuid + cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + /* + cfg.Mounts = append(cfg.Mounts, + specs.Mount{Destination: "/usr/bin/newgidmap", Source: "/usr/bin/newgidmap", Type: "bind", Options: []string{"bind", "create=file"}}, + specs.Mount{Destination: "/usr/bin/newuidmap", Source: "/usr/bin/newuidmap", Type: "bind", Options: []string{"bind", "create=file"}}, + ) + + err = os.MkdirAll(filepath.Join(rootfs, "/usr/bin"), 0755) + require.NoError(t, err) + */ + //cfg.Process.Path = " + } + + /* + cgroupns := specs.LinuxNamespace{ + Type: specs.CgroupNamespace, + } + cfg.Linux.Namespaces = append(cfg.Linux.Namespaces, cgroupns) + */ + return &cfg } @@ -82,10 +137,10 @@ func TestRuntimeNamespaceCheck(t *testing.T) { func TestRuntimeKill(t *testing.T) { rt := newRuntime(t) - defer os.RemoveAll(rt.Root) + //defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - defer os.RemoveAll(cfg.Root.Path) + //defer os.RemoveAll(cfg.Root.Path) ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() @@ -115,6 +170,8 @@ func TestRuntimeKill(t *testing.T) { require.NoError(t, err) require.Equal(t, specs.StateRunning, state.Status) + time.Sleep(time.Second * 3) + // SIGHUP by default terminates a process if it is not ignored or catched by // a signal handler err = rt.Kill(ctx, c, unix.SIGKILL) diff --git a/utils.go b/utils.go index a109ea9c..45379a9d 100644 --- a/utils.go +++ b/utils.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "os/exec" "path/filepath" "runtime" "strings" From d7f6146a15973a5c3d9f20a227d2ba2743cd96c8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 16:31:35 +0200 Subject: [PATCH 271/373] Set permissions based on mapped container process UID Signed-off-by: Ruben Jenster --- init.go | 73 +++++++++++++++++++++++++++++++++++-------------- runtime.go | 16 ----------- runtime_test.go | 67 +++++++++++++++++++++++++-------------------- 3 files changed, 91 insertions(+), 65 deletions(-) diff --git a/init.go b/init.go index 9bbf39fc..d96d3f38 100644 --- a/init.go +++ b/init.go @@ -17,8 +17,8 @@ const ( initDir = "/.lxcri" ) -func createFifo(dst string) error { - if err := unix.Mkfifo(dst, 0666); err != nil { +func createFifo(dst string, mode uint32) error { + if err := unix.Mkfifo(dst, mode); err != nil { return errorf("mkfifo dst:%s failed: %w", dst, err) } // lxcri-init must be able to write to the fifo. @@ -26,12 +26,40 @@ func createFifo(dst string) error { // liblxc changes the owner of the runtime directory to the effective container UID. // access to the files is protected by the runtimeDir // because umask (0022) affects unix.Mkfifo, a separate chmod is required - if err := unix.Chmod(dst, 0666); err != nil { + // FIXME if container UID equals os.GetUID() and spec. + if err := unix.Chmod(dst, mode); err != nil { return errorf("chmod mkfifo failed: %w", err) } return nil } +// Return true if init user is mapped to runtime user +func (c *Container) IsUserUID() bool { + cuid := uint32(os.Getuid()) + puid := c.Process.User.UID + + // no id mappings + if len(c.Linux.UIDMappings) == 0 { + return puid == cuid + } + + for _, idmap := range c.Linux.UIDMappings { + if idmap.Size < 1 { + continue + } + maxID := idmap.ContainerID + idmap.Size - 1 + println("-----> maxID: %d", maxID) + // check if c.Process.UID is contained in the mapping + if (puid >= idmap.ContainerID) && (puid <= maxID) { + offset := puid - idmap.ContainerID + hostid := idmap.HostID + offset + println("-----> hostid: %d", hostid) + return hostid == cuid + } + } + return false +} + func configureInit(rt *Runtime, c *Container) error { runtimeInitDir := c.RuntimePath(initDir) //rootfsInitDir := filepath.Join(c.Root.Path, initDir) @@ -59,20 +87,30 @@ func configureInit(rt *Runtime, c *Container) error { return err } - uid := int(c.Process.User.UID) - gid := int(c.Process.User.GID) - // create files required for lxcri-init - if err := createFifo(c.syncFifoPath()); err != nil { - return fmt.Errorf("failed to create sync fifo: %w", err) + if c.IsUserUID() { + println("-------> c.IsUserUID") + if err := createFifo(c.syncFifoPath(), 0600); err != nil { + return fmt.Errorf("failed to create sync fifo: %w", err) + } + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, 0400); err != nil { + return err + } + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, 0400); err != nil { + return err + } + } else { + if err := createFifo(c.syncFifoPath(), 0666); err != nil { + return fmt.Errorf("failed to create sync fifo: %w", err) + } + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, 0444); err != nil { + return err + } + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, 0444); err != nil { + return err + } } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, uid, gid, 0440); err != nil { - return err - } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, uid, gid, 0440); err != nil { - return err - } if err := os.Symlink(c.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { return err } @@ -115,7 +153,7 @@ func touchFile(filePath string, perm os.FileMode) error { return err } -func createList(dst string, entries []string, uid int, gid int, mode uint32) error { +func createList(dst string, entries []string, mode uint32) error { // #nosec f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) if err != nil { @@ -137,11 +175,6 @@ func createList(dst string, entries []string, uid int, gid int, mode uint32) err if err := f.Close(); err != nil { return errorf("failed to close %s: %w", dst, err) } - /* - if err := unix.Chown(dst, uid, gid); err != nil { - return errorf("failed to chown %s uid:%d gid:%d :%w", dst, uid, gid, err) - } - */ if err := unix.Chmod(dst, mode); err != nil { return errorf("failed to chmod %s mode:%o : %w", dst, mode, err) } diff --git a/runtime.go b/runtime.go index a534c9ff..b60b7105 100644 --- a/runtime.go +++ b/runtime.go @@ -312,22 +312,6 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { proc := new(specs.Process) proc.Args = append(proc.Args, cmd) proc.Args = append(proc.Args, args...) - //proc.User = currentUser() proc.Cwd = "/" return proc } - -func currentUser() specs.User { - groups, _ := os.Getgroups() - gids := make([]uint32, len(groups)) - for i, g := range groups { - gids[i] = uint32(g) - } - return specs.User{ - UID: 0, - GID: 0, - //UID: uint32(os.Getuid()), - //GID: uint32(os.Getgid()), - AdditionalGids: []uint32{uint32(os.Getgid())}, - } -} diff --git a/runtime_test.go b/runtime_test.go index a04ede3f..61a9f5f8 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -19,26 +19,23 @@ import ( var tmpDir string -/* func init() { - // /tmp has permissions 1777 - // sticky bit prevents renaming .config to /config because - // liblxc modifies permissions if user namepaces with uid/gid mappings are enabled + // /tmp has permissions 1777, never use it as runtime / rootfs parent if os.Getuid() != 0 { tmpDir = os.Getenv("HOME") } } -*/ func newRuntime(t *testing.T) *Runtime { //wd, err := os.Getwd() //require.NoError(t, err) runtimeRoot, err := os.MkdirTemp(tmpDir, "lxcri-test") require.NoError(t, err) - err = unix.Chmod(runtimeRoot, 0700) - require.NoError(t, err) t.Logf("runtime root: %s", runtimeRoot) + err = unix.Chmod(runtimeRoot, 0755) + require.NoError(t, err) + rt := &Runtime{ Log: log.ConsoleLogger(true), Root: runtimeRoot, @@ -59,13 +56,6 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { // copy binary to rootfs err = exec.Command("cp", cmd, rootfs).Run() require.NoError(t, err) - // create /proc and /dev in rootfs - /* - err = os.MkdirAll(filepath.Join(rootfs, "dev"), 0755) - require.NoError(t, err) - err = os.MkdirAll(filepath.Join(rootfs, "proc"), 0555) - require.NoError(t, err) - */ spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) @@ -75,25 +65,44 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { cfg.LogLevel = "trace" if os.Getuid() != 0 { + + // container user ID 0 is mapped to user creating the container + // --> file permissions in /.lxcri could be 0600 / 0400 + // get UID/GID mapping from /etc/subgid /etc/subuid + + /* + cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + */ + + // The container UID must have full access to the rootfs. + // If we the container UID (0) / or GID are not mapped to the owner (creator) of the rootfs + // it must be granted o+rwx. + // MkdirTemp creates with 0700 + + err = unix.Chmod(rootfs, 0777) + require.NoError(t, err) + + // Using 0755 is required if container UID is not + // the owner of runtimeRoot + + //err = unix.Chmod(runtimeRoot, 0755) + //require.NoError(t, err) + cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, } cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, } - /* - cfg.Mounts = append(cfg.Mounts, - specs.Mount{Destination: "/usr/bin/newgidmap", Source: "/usr/bin/newgidmap", Type: "bind", Options: []string{"bind", "create=file"}}, - specs.Mount{Destination: "/usr/bin/newuidmap", Source: "/usr/bin/newuidmap", Type: "bind", Options: []string{"bind", "create=file"}}, - ) - err = os.MkdirAll(filepath.Join(rootfs, "/usr/bin"), 0755) - require.NoError(t, err) - */ - //cfg.Process.Path = " } /* @@ -137,10 +146,10 @@ func TestRuntimeNamespaceCheck(t *testing.T) { func TestRuntimeKill(t *testing.T) { rt := newRuntime(t) - //defer os.RemoveAll(rt.Root) + defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - //defer os.RemoveAll(cfg.Root.Path) + defer os.RemoveAll(cfg.Root.Path) ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() From e41e1c977f4fbb1468cfc220178042b9b593bf7a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 13:20:30 +0200 Subject: [PATCH 272/373] Split runtime test into several tests. Signed-off-by: Ruben Jenster --- runtime_test.go | 159 ++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 78 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index 61a9f5f8..781c24a6 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -15,21 +15,14 @@ import ( "golang.org/x/sys/unix" ) -// Create a package test ? test.NewRuntime() - -var tmpDir string - -func init() { - // /tmp has permissions 1777, never use it as runtime / rootfs parent - if os.Getuid() != 0 { - tmpDir = os.Getenv("HOME") - } +func mkdirTemp() (string, error) { + // /tmp has permissions 1777 + // it should never be used as runtime or rootfs parent + return os.MkdirTemp(os.Getenv("HOME"), "lxcri-test") } func newRuntime(t *testing.T) *Runtime { - //wd, err := os.Getwd() - //require.NoError(t, err) - runtimeRoot, err := os.MkdirTemp(tmpDir, "lxcri-test") + runtimeRoot, err := mkdirTemp() require.NoError(t, err) t.Logf("runtime root: %s", runtimeRoot) @@ -47,13 +40,11 @@ func newRuntime(t *testing.T) *Runtime { } func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { - //wd, err := os.Getwd() - //require.NoError(t, err) - rootfs, err := os.MkdirTemp(tmpDir, "lxcri-test") + rootfs, err := mkdirTemp() require.NoError(t, err) t.Logf("container rootfs: %s", rootfs) - // copy binary to rootfs + // copy test binary to rootfs err = exec.Command("cp", cmd, rootfs).Run() require.NoError(t, err) @@ -64,66 +55,18 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { cfg.LogFile = "/dev/stderr" cfg.LogLevel = "trace" - if os.Getuid() != 0 { - - // container user ID 0 is mapped to user creating the container - // --> file permissions in /.lxcri could be 0600 / 0400 - - // get UID/GID mapping from /etc/subgid /etc/subuid - - /* - cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, - } - cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, - } - */ - - // The container UID must have full access to the rootfs. - // If we the container UID (0) / or GID are not mapped to the owner (creator) of the rootfs - // it must be granted o+rwx. - // MkdirTemp creates with 0700 - - err = unix.Chmod(rootfs, 0777) - require.NoError(t, err) - - // Using 0755 is required if container UID is not - // the owner of runtimeRoot - - //err = unix.Chmod(runtimeRoot, 0755) - //require.NoError(t, err) - - cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, - } - cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ - specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, - } - - } - - /* - cgroupns := specs.LinuxNamespace{ - Type: specs.CgroupNamespace, - } - cfg.Linux.Namespaces = append(cfg.Linux.Namespaces, cgroupns) - */ - return &cfg } -func TestRuntimeNamespaceCheck(t *testing.T) { +func TestEmptyNamespaces(t *testing.T) { rt := newRuntime(t) defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") defer os.RemoveAll(cfg.Root.Path) - // Clearing all namespaces should not work. - // At least PID and MOUNT must not be shared with the host. + // Clearing all namespaces should not work, + // since the mount namespace must never be shared with the host. cfg.Linux.Namespaces = cfg.Linux.Namespaces[0:0] ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) @@ -144,13 +87,83 @@ func TestRuntimeNamespaceCheck(t *testing.T) { require.Nil(t, c) } -func TestRuntimeKill(t *testing.T) { +func TestRuntimePrivileged(t *testing.T) { + if os.Getuid() != 0 { + t.Skipf("This tests only runs as root") + } + rt := newRuntime(t) defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") defer os.RemoveAll(cfg.Root.Path) + testRuntime(t, rt, cfg) +} + +// The following tests require the following setup: +// TODO load UID/GID mappings from /etc/subgid /etc/subuid + +// sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) +/* +[ruben@k8s-cluster8-controller lxcri]$ cat /etc/subgid +ruben:1000:1 +ruben:20000:65536 +[ruben@k8s-cluster8-controller lxcri]$ cat /etc/subuid +ruben:1000:1 +ruben:20000:65536 +*/ +func TestRuntimeUnprivileged(t *testing.T) { + + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Root.Path) + + // The container UID must have full access to the rootfs. + // MkdirTemp sets directory permissions to 0700. + // If we the container UID (0) / or GID are not mapped to the owner (creator) of the rootfs, + // then the rootfs and runtime directory permissions must be expanded. + + err := unix.Chmod(cfg.Root.Path, 0777) + require.NoError(t, err) + + err = unix.Chmod(rt.Root, 0755) + require.NoError(t, err) + + cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, + } + cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, + } + + testRuntime(t, rt, cfg) +} + +func TestRuntimeUnprivileged2(t *testing.T) { + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Root.Path) + + if os.Getuid() != 0 { + cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, + specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + } + + testRuntime(t, rt, cfg) +} + +func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() @@ -204,16 +217,6 @@ func TestRuntimeKill(t *testing.T) { err = c.Release() require.NoError(t, err) - /* - p, err := os.FindProcess(c.Pid) - require.NoError(t, err) - pstate, err := p.Wait() - require.NoError(t, err) - // The exit code should be non-zero because the process was terminated - // by a signal - fmt.Printf("monitor process exited %T: %s code:%d\n", pstate, pstate, pstate.ExitCode()) - */ - // manpage for 'wait4' suggests to use waitpid or waitid instead, but // golang/x/sys/unix only implements 'Wait4'. See https://github.com/golang/go/issues/9176 var ws unix.WaitStatus From 3d290009e0ae781ba8f087c088148dc4999bfac8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 15:56:49 +0200 Subject: [PATCH 273/373] Inline save of liblxc config file. Signed-off-by: Ruben Jenster --- container.go | 26 +------------------------- runtime.go | 7 +++++-- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/container.go b/container.go index 102e5e02..f29ab537 100644 --- a/container.go +++ b/container.go @@ -90,10 +90,7 @@ func (c *Container) create() error { return errorf("failed to chmod %s: %w", err) } - // An empty tmpfile is created to ensure that createContainer can only succeed once. - // The config file is atomically activated in SaveConfig. - // #nosec - f, err := os.OpenFile(c.RuntimePath(".config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0666) + f, err := os.OpenFile(c.RuntimePath("config"), os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) if err != nil { return err } @@ -288,27 +285,6 @@ func (c *Container) kill(ctx context.Context, signum unix.Signal) error { return nil } -// SaveConfig creates and atomically enables the lxc config file. -// It must be called only once. It is automatically called by Runtime#Create. -// Any config changes via clxc.setConfigItem must be done before calling SaveConfig. -// FIXME revise the config file mechanism -func (c *Container) saveConfig() error { - // Don't overwrite an existing config. - cfgFile := c.ConfigFilePath() - - f, err := os.OpenFile(cfgFile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0640) - if err != nil { - return errorf("failed to create config file %q: %w", cfgFile, err) - } - f.Close() - - err = c.LinuxContainer.SaveConfigFile(cfgFile) - if err != nil { - return errorf("failed to save config file to %q: %w", cfgFile, err) - } - return nil -} - // GetConfigItem is a wrapper function and returns the // first value returned by *lxc.Container.ConfigItem func (c *Container) GetConfigItem(key string) string { diff --git a/runtime.go b/runtime.go index b60b7105..2002aa57 100644 --- a/runtime.go +++ b/runtime.go @@ -144,8 +144,11 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { cmd.Stderr = os.Stderr } - if err := c.saveConfig(); err != nil { - return err + // NOTE any config change via clxc.SetConfigItem + // must be done before calling SaveConfigFile + err = c.LinuxContainer.SaveConfigFile(c.ConfigFilePath()) + if err != nil { + return errorf("failed to save config file to %q: %w", c.ConfigFilePath(), err) } rt.Log.Debug().Msg("starting lxc monitor process") From 4128fd09e6dd0024d1249cd956f586f9296dca0e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 15:59:11 +0200 Subject: [PATCH 274/373] Create bind mount directories only if rootfs is readonly. Signed-off-by: Ruben Jenster --- mount.go | 44 +++++++++++++++++++++++--------------------- utils.go | 45 --------------------------------------------- 2 files changed, 23 insertions(+), 66 deletions(-) diff --git a/mount.go b/mount.go index 6cb53284..54b0f52e 100644 --- a/mount.go +++ b/mount.go @@ -72,13 +72,11 @@ func configureMounts(rt *Runtime, c *Container) error { // refuses mount destinations that escape from rootfs return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, c.Root.Path) } + ms.Destination = mountDest - if c.Root.Readonly { - err = createMountDestination(c, &ms) - if err != nil { - return fmt.Errorf("failed to create mount target %s: %w", ms.Destination, err) - } + if err := createMountDestination(c, &ms); err != nil { + return err } ms.Options = filterMountOptions(rt, ms.Type, ms.Options) @@ -103,18 +101,28 @@ func configureMounts(rt *Runtime, c *Container) error { // https://github.com/lxc/lxc/issues/1702 func createMountDestination(spec *Container, ms *specs.Mount) error { info, err := os.Stat(ms.Source) + + // source for bind mount must exist if err != nil && ms.Type == "bind" { - // check if mountpoint is optional ? - return fmt.Errorf("failed to access source for bind mount: %w", err) + for _, o := range ms.Options { + if o == "optional" { + return nil + } + } + return errorf("failed to access bind mount source %s: %w", ms.Source, err) } - uid := int(spec.Process.User.UID) - gid := int(spec.Process.User.GID) - - if err == nil && !info.IsDir() { - ms.Options = append(ms.Options, "create=file") - // source exists and is not a directory - // create a target file that can be used as target for a bind mount - if err := mkdirAll(filepath.Dir(ms.Destination), 0755, uid, gid); err != nil { + + if err != nil || info.IsDir() { + ms.Options = append(ms.Options, "create=dir") + if spec.Root.Readonly { + return os.MkdirAll(ms.Destination, 0755) + } + return nil + } + + ms.Options = append(ms.Options, "create=file") + if spec.Root.Readonly { + if err := os.MkdirAll(filepath.Dir(ms.Destination), 0755); err != nil { return fmt.Errorf("failed to create mount destination dir: %w", err) } f, err := os.OpenFile(ms.Destination, os.O_CREATE, 0755) @@ -123,12 +131,6 @@ func createMountDestination(spec *Container, ms *specs.Mount) error { } return f.Close() } - ms.Options = append(ms.Options, "create=dir") - // FIXME exclude all directories that are below other mounts - // only directories / files on the readonly rootfs must be created - if err = mkdirAll(ms.Destination, 0755, uid, gid); err != nil { - return fmt.Errorf("failed to create mount target dir: %w", err) - } return nil } diff --git a/utils.go b/utils.go index 45379a9d..9e757e7c 100644 --- a/utils.go +++ b/utils.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "os" - "os/exec" "path/filepath" "runtime" "strings" @@ -100,50 +99,6 @@ func errorf(sfmt string, args ...interface{}) error { return fmt.Errorf(prefix+sfmt, args...) } -// Modified version of golang standard library os.MkdirAll -func mkdirAll(path string, perm os.FileMode, uid int, gid int) error { - // Fast path: if we can tell whether path is a directory or file, stop with success or error. - dir, err := os.Stat(path) - if err == nil { - if dir.IsDir() { - return nil - } - return &os.PathError{Op: "mkdir", Path: path, Err: unix.ENOTDIR} - } - - // Slow path: make sure parent exists and then call Mkdir for path. - i := len(path) - for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator. - i-- - } - - j := i - for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element. - j-- - } - - if j > 1 { - // Create parent. - err = mkdirAll(path[:j-1], perm, uid, gid) - if err != nil { - return err - } - } - - // Parent now exists; invoke Mkdir and use its result. - err = os.Mkdir(path, perm) - if err != nil { - // Handle arguments like "foo/." by - // double-checking that directory doesn't exist. - dir, err1 := os.Lstat(path) - if err1 == nil && dir.IsDir() { - return nil - } - return err - } - return unix.Chown(path, uid, gid) -} - func setenv(env []string, key, val string, overwrite bool) []string { for i, kv := range env { if strings.HasPrefix(kv, key+"=") { From 0815c712da5851daff64d6c1cf924bc385357d76 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 4 Apr 2021 11:07:18 +0200 Subject: [PATCH 275/373] Configure mounts at the end of create. This allows adding bind mounts for devices if runtime is unprivileged. Signed-off-by: Ruben Jenster --- create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/create.go b/create.go index 9292aaa2..f2576fbb 100644 --- a/create.go +++ b/create.go @@ -154,10 +154,6 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure init: %w", err) } - if err := configureMounts(rt, c); err != nil { - return fmt.Errorf("failed to configure mounts: %w", err) - } - if err := configureReadonlyPaths(c); err != nil { return fmt.Errorf("failed to configure read-only paths: %w", err) } @@ -293,6 +289,10 @@ func configureContainer(rt *Runtime, c *Container) error { return errorf("failed to configure container log: %w", err) } + if err := configureMounts(rt, c); err != nil { + return fmt.Errorf("failed to configure mounts: %w", err) + } + return nil } From d461900b830bcaeb578e73e9236f081a5c55fedc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 15:59:52 +0200 Subject: [PATCH 276/373] Fix readonly path mounts. Signed-off-by: Ruben Jenster --- create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/create.go b/create.go index f2576fbb..429b29fe 100644 --- a/create.go +++ b/create.go @@ -154,10 +154,6 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure init: %w", err) } - if err := configureReadonlyPaths(c); err != nil { - return fmt.Errorf("failed to configure read-only paths: %w", err) - } - if !rt.privileged { // ensure user namespace is enabled if !isNamespaceEnabled(c.Spec, specs.UserNamespace) { @@ -293,6 +289,10 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure mounts: %w", err) } + if err := configureReadonlyPaths(c); err != nil { + return fmt.Errorf("failed to configure read-only paths: %w", err) + } + return nil } From 806bf1c619407777ed1ac2cd182fd0aa3ca8e971 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 16:00:23 +0200 Subject: [PATCH 277/373] Remove create=dir from default spec mounts. Signed-off-by: Ruben Jenster --- runtime.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime.go b/runtime.go index 2002aa57..c00da179 100644 --- a/runtime.go +++ b/runtime.go @@ -297,10 +297,10 @@ func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { }, Mounts: []specs.Mount{ specs.Mount{Destination: "/proc", Source: "proc", Type: "proc", - Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime", "create=dir"}, + Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, }, specs.Mount{Destination: "/dev", Source: "tmpfs", Type: "tmpfs", - Options: []string{"rw", "nosuid", "noexec", "relatime", "dev", "create=dir"}, + Options: []string{"rw", "nosuid", "noexec", "relatime", "dev"}, // devtmpfs (rw,nosuid,relatime,size=6122620k,nr_inodes=1530655,mode=755,inode64) }, }, From ac8a5677dc5ad8d8e6b6d7f7117dd4ab32e0afee Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 16:48:46 +0200 Subject: [PATCH 278/373] Remove printlns. Signed-off-by: Ruben Jenster --- init.go | 3 --- runtime.go | 1 - 2 files changed, 4 deletions(-) diff --git a/init.go b/init.go index d96d3f38..8f682e19 100644 --- a/init.go +++ b/init.go @@ -48,12 +48,10 @@ func (c *Container) IsUserUID() bool { continue } maxID := idmap.ContainerID + idmap.Size - 1 - println("-----> maxID: %d", maxID) // check if c.Process.UID is contained in the mapping if (puid >= idmap.ContainerID) && (puid <= maxID) { offset := puid - idmap.ContainerID hostid := idmap.HostID + offset - println("-----> hostid: %d", hostid) return hostid == cuid } } @@ -89,7 +87,6 @@ func configureInit(rt *Runtime, c *Container) error { // create files required for lxcri-init if c.IsUserUID() { - println("-------> c.IsUserUID") if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } diff --git a/runtime.go b/runtime.go index c00da179..c61b5696 100644 --- a/runtime.go +++ b/runtime.go @@ -129,7 +129,6 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // #nosec cmd := exec.Command(rt.libexec(ExecStart), c.LinuxContainer.Name(), rt.Root, c.ConfigFilePath()) - println(os.Environ()) cmd.Env = []string{"XDG_RUNTIME_DIR=/tmp/myrun", "PATH=/usr/bin"} cmd.Dir = c.RuntimePath() From c51386d871989424c040c3d11782d7f653484ce1 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 16:49:16 +0200 Subject: [PATCH 279/373] Keep environment variables required for running liblxc unprivileged. Signed-off-by: Ruben Jenster --- create.go | 10 ++++++++++ init.go | 3 +-- runtime.go | 5 ++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/create.go b/create.go index 429b29fe..07aa0f8c 100644 --- a/create.go +++ b/create.go @@ -48,6 +48,14 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, err } +func (rt *Runtime) keepEnv(names ...string) { + for _, n := range names { + if val := os.Getenv(n); val != "" { + rt.env = append(rt.env, n+"="+val) + } + } +} + // Init initializes the runtime instance. // It creates required directories and checks the hosts system configuration. // Unsupported runtime features are disabled and a warning message is logged. @@ -64,6 +72,8 @@ func (rt *Runtime) Init() error { rt.privileged = os.Getuid() == 0 + rt.keepEnv("HOME", "XDG_RUNTIME_DIR", "PATH") + err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) if err != nil { return errorf("access check failed: %w", err) diff --git a/init.go b/init.go index 8f682e19..e7b59385 100644 --- a/init.go +++ b/init.go @@ -6,9 +6,8 @@ import ( "path/filepath" "strings" - "golang.org/x/sys/unix" - "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" ) const ( diff --git a/runtime.go b/runtime.go index c61b5696..42be22ee 100644 --- a/runtime.go +++ b/runtime.go @@ -88,6 +88,9 @@ type Runtime struct { // defined within the OCI runtime spec. Hooks `json:"-"` + // Environment passed to `lxcri-start` + env []string + // privileged is set by Runtime.Init if user has root privileges. privileged bool } @@ -129,7 +132,7 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { // #nosec cmd := exec.Command(rt.libexec(ExecStart), c.LinuxContainer.Name(), rt.Root, c.ConfigFilePath()) - cmd.Env = []string{"XDG_RUNTIME_DIR=/tmp/myrun", "PATH=/usr/bin"} + cmd.Env = rt.env cmd.Dir = c.RuntimePath() if c.ConsoleSocket == "" && !c.Process.Terminal { From 03a0f04c7a25b229fa101216fcb05731dcd4dcac Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 18:26:29 +0200 Subject: [PATCH 280/373] Fix delete if container create failed. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 11 +---------- container.go | 14 -------------- create.go | 1 - runtime.go | 28 +++++++++++++++++++--------- runtime_test.go | 2 +- 5 files changed, 21 insertions(+), 35 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 074485aa..9990f334 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -437,20 +437,11 @@ var deleteCmd = cli.Command{ } func doDelete(ctxcli *cli.Context) error { - c, err := clxc.Load(clxc.cfg.ContainerID) - if err == lxcri.ErrNotExist { - clxc.Log.Info().Msg("container does not exist") - return nil - } - if err != nil { - return err - } - timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - return clxc.Delete(ctx, c, ctxcli.Bool("force")) + return clxc.Delete(ctx, clxc.cfg.ContainerID, ctxcli.Bool("force")) } var execCmd = cli.Command{ diff --git a/container.go b/container.go index f29ab537..039afbc0 100644 --- a/container.go +++ b/container.go @@ -59,13 +59,6 @@ func (c Container) RuntimePath(subPath ...string) string { return filepath.Join(c.runtimeDir, filepath.Join(subPath...)) } -func (c Container) runtimeDirExists() bool { - if _, err := os.Stat(c.runtimeDir); err == nil { - return true - } - return false -} - // Container is the runtime state of a container instance. type Container struct { LinuxContainer *lxc.Container `json:"-"` @@ -78,10 +71,6 @@ type Container struct { } func (c *Container) create() error { - if c.runtimeDirExists() { - return ErrExist - } - if err := os.MkdirAll(c.runtimeDir, 0777); err != nil { return fmt.Errorf("failed to create container dir: %w", err) } @@ -107,9 +96,6 @@ func (c *Container) create() error { } func (c *Container) load() error { - if !c.runtimeDirExists() { - return ErrNotExist - } err := decodeFileJSON(c, c.RuntimePath("container.json")) if err != nil { diff --git a/create.go b/create.go index 07aa0f8c..a107875d 100644 --- a/create.go +++ b/create.go @@ -61,7 +61,6 @@ func (rt *Runtime) keepEnv(names ...string) { // Unsupported runtime features are disabled and a warning message is logged. // Init must be called once for a runtime instance before calling any other method. func (rt *Runtime) Init() error { - rt.rootfsMount = filepath.Join(rt.Root, ".rootfs") if err := os.MkdirAll(rt.rootfsMount, 0777); err != nil { return errorf("failed to create directory for rootfs mount %s: %w", rt.rootfsMount, err) diff --git a/runtime.go b/runtime.go index 42be22ee..b782d2d6 100644 --- a/runtime.go +++ b/runtime.go @@ -26,11 +26,7 @@ var ( ) var ( - // ErrExist is an error returned by Runtime.Create - // if a container with the same ContainerID already exists. - ErrExist = fmt.Errorf("container already exists") - // ErrNotExist is an error returned by all runtime functions - // that exected functions if a container does not exist. + // ErrNotExist is returned if the container (runtime dir) does not exist. ErrNotExist = fmt.Errorf("container does not exist") ) @@ -102,9 +98,14 @@ func (rt *Runtime) libexec(name string) string { // Load loads a container from the runtime directory. // The container must have been created with Runtime.Create. func (rt *Runtime) Load(containerID string) (*Container, error) { - c := &Container{ContainerConfig: &ContainerConfig{}} - c.runtimeDir = filepath.Join(rt.Root, containerID) - + dir := filepath.Join(rt.Root, containerID) + if _, err := os.Stat(dir); os.IsNotExist(err) { + return nil, ErrNotExist + } + c := &Container{ + ContainerConfig: &ContainerConfig{}, + runtimeDir: dir, + } if err := c.load(); err != nil { return nil, err } @@ -238,8 +239,17 @@ func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) e // The container must be stopped or force must be set to true. // If the container is not stopped but force is set to true, // the container will be killed with unix.SIGKILL. -func (rt *Runtime) Delete(ctx context.Context, c *Container, force bool) error { +func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) error { rt.Log.Info().Bool("force", force).Msg("delete container") + c, err := rt.Load(containerID) + if err == ErrNotExist { + rt.Log.Info().Msg("container does not exist") + return nil + } + if err != nil { + rt.Log.Warn().Msgf("deleting runtime dir for unloadable container: %s", err) + return os.RemoveAll(filepath.Join(rt.Root, containerID)) + } state, err := c.ContainerState() if err != nil { return err diff --git a/runtime_test.go b/runtime_test.go index 781c24a6..42d143c6 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -205,7 +205,7 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { require.NoError(t, err) require.Equal(t, specs.StateStopped, state.Status) - err = rt.Delete(ctx, c, false) + err = rt.Delete(ctx, c.ContainerID, false) require.NoError(t, err) state, err = c.State() From 003be2ad34bb30c175392d3b521cb4bc41a2d085 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 5 Apr 2021 22:06:40 +0200 Subject: [PATCH 281/373] Drain cgroup on delete. Signed-off-by: Ruben Jenster --- cgroup.go | 44 -------------------------------------------- container.go | 4 ++-- runtime.go | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/cgroup.go b/cgroup.go index f50addae..2bebb085 100644 --- a/cgroup.go +++ b/cgroup.go @@ -93,12 +93,6 @@ func configureCgroupPath(rt *Runtime, c *Container) error { c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") - /* - if err := createCgroup(filepath.Dir(c.CgroupDir), allControllers); err != nil { - return err - } - */ - if err := c.SetConfigItem("lxc.cgroup.relative", "0"); err != nil { return err } @@ -403,41 +397,3 @@ func deleteCgroup(cgroupName string) error { } return unix.Rmdir(dirName) } - -func createCgroup(cg string, controllers string) error { - // #nosec - cgPath := filepath.Join(cgroupRoot, cg) - if err := os.MkdirAll(cgPath, 755); err != nil { - return err - } - - base := cgroupRoot - for _, elem := range strings.Split(cg, "/") { - base = filepath.Join(base, elem) - c := filepath.Join(base, "cgroup.subtree_control") - err := os.WriteFile(c, []byte(strings.TrimSpace(controllers)+"\n"), 0) - if err != nil { - return fmt.Errorf("failed to enable cgroup controllers: %w", err) - } - } - return nil -} - -func getControllers(cg string) (string, error) { - // enable all available controllers in the scope - data, err := os.ReadFile(filepath.Join(cgroupRoot, cg, "group.controllers")) - if err != nil { - return "", fmt.Errorf("failed to read cgroup.controllers: %w", err) - } - controllers := strings.Split(strings.TrimSpace(string(data)), " ") - - var b strings.Builder - for i, c := range controllers { - if i > 0 { - b.WriteByte(' ') - } - b.WriteByte('+') - b.WriteString(c) - } - return b.String(), nil -} diff --git a/container.go b/container.go index 039afbc0..f0169aef 100644 --- a/container.go +++ b/container.go @@ -251,7 +251,7 @@ func (c *Container) kill(ctx context.Context, signum unix.Signal) error { // From `man pid_namespaces`: If the "init" process of a PID namespace terminates, the kernel // terminates all of the processes in the namespace via a SIGKILL signal. - // So there is nothing more to do here than signaling the init process. + // So there is nothing more to do here than to signal the init process. // NOTE: The liblxc monitor process `lxcri-start` doesn't propagate all signals to the init process, // but handles some signals on its own. E.g SIGHUP tells the monitor process to hang up the terminal // and terminate the init process with SIGTERM. @@ -330,7 +330,7 @@ func (c *Container) destroy() error { if c.CgroupDir != "" { err := deleteCgroup(c.CgroupDir) if err != nil && !os.IsNotExist(err) { - c.Log.Warn().Err(err).Str("file", c.CgroupDir).Msg("failed to remove cgroup dir") + return err } } return os.RemoveAll(c.RuntimePath()) diff --git a/runtime.go b/runtime.go index b782d2d6..66c49b28 100644 --- a/runtime.go +++ b/runtime.go @@ -221,9 +221,7 @@ func runStartCmdConsole(ctx context.Context, cmd *exec.Cmd, consoleSocket string return ptmx.Close() } -// Kill sends the signal signum to the given container. -// The signal is send to the container monitor process `lxcri-start` who -// will propagate the signal to the container process. +// Kill sends the signal signum to the container init process. func (rt *Runtime) Kill(ctx context.Context, c *Container, signum unix.Signal) error { state, err := c.ContainerState() if err != nil { @@ -262,6 +260,17 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e return errorf("failed to kill container: %w", err) } } + + if c.CgroupDir != "" { + // In rare cases processes might escape from kill. + // This could happens if the container does not use pid_namespaces. + // Since every container get's it's own cgroup, we can + // try to kill all processes within the containers cgroup tree. + if err := drainCgroup(ctx, c.CgroupDir, unix.SIGKILL); err != nil { + c.Log.Warn().Msgf("draining cgroup failed: %s", err) + } + } + if err := c.destroy(); err != nil { return errorf("failed to destroy container: %w", err) } From 659ef74711ef861b7803b1d0967decb5257c2bfd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 6 Apr 2021 06:38:41 +0200 Subject: [PATCH 282/373] Make killCgroupProces recursive Signed-off-by: Ruben Jenster --- cgroup.go | 28 +++++++++++++++++++--------- container.go | 1 + runtime.go | 3 ++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/cgroup.go b/cgroup.go index 2bebb085..5ec31e93 100644 --- a/cgroup.go +++ b/cgroup.go @@ -294,6 +294,18 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { } func killCgroupProcs(cgroupName string, sig unix.Signal) error { + + cg, err := loadCgroup(cgroupName) + if err != nil { + return fmt.Errorf("failed to load cgroup %s: %w", cgroupName, err) + } + for _, pid := range cg.Procs { + err := unix.Kill(pid, sig) + if err != nil && err != unix.ESRCH { + return fmt.Errorf("failed to kill %d: %w", pid, err) + } + } + dirName := filepath.Join(cgroupRoot, cgroupName) // #nosec dir, err := os.Open(dirName) @@ -312,27 +324,25 @@ func killCgroupProcs(cgroupName string, sig unix.Signal) error { } for _, i := range entries { if i.IsDir() && i.Name() != "." && i.Name() != ".." { - cg, err := loadCgroup(filepath.Join(cgroupName, i.Name())) + err := killCgroupProcs(filepath.Join(cgroupName, i.Name()), sig) if err != nil { - return fmt.Errorf("failed to load cgroup %s: %w", i.Name(), err) - } - for _, pid := range cg.Procs { - err := unix.Kill(pid, sig) - if err != nil && err != unix.ESRCH { - return fmt.Errorf("failed to kill %d: %w", pid, err) - } + return err } } } return nil } +// see http://morningcoffee.io/killing-a-process-and-all-of-its-descendants.html // TODO maybe use polling instead // fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} // n, err := unix.Poll(fds, timeout) func drainCgroup(ctx context.Context, cgroupName string, sig unix.Signal) error { p := filepath.Join(cgroupRoot, cgroupName, "cgroup.events") f, err := os.OpenFile(p, os.O_RDONLY, 0) + if os.IsNotExist(err) { + return nil + } if err != nil { return err } @@ -391,7 +401,7 @@ func deleteCgroup(cgroupName string) error { p := filepath.Join(dirName, i.Name()) err := unix.Rmdir(p) if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to dir %s: %w", p, err) + return fmt.Errorf("failed to rmdir %s: %w", p, err) } } } diff --git a/container.go b/container.go index f0169aef..7c29cb6d 100644 --- a/container.go +++ b/container.go @@ -259,6 +259,7 @@ func (c *Container) kill(ctx context.Context, signum unix.Signal) error { if pid <= 1 { return nil } + c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") err = unix.Kill(pid, signum) if err == unix.ESRCH { diff --git a/runtime.go b/runtime.go index 66c49b28..09c48a4c 100644 --- a/runtime.go +++ b/runtime.go @@ -267,8 +267,9 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e // Since every container get's it's own cgroup, we can // try to kill all processes within the containers cgroup tree. if err := drainCgroup(ctx, c.CgroupDir, unix.SIGKILL); err != nil { - c.Log.Warn().Msgf("draining cgroup failed: %s", err) + rt.Log.Warn().Msgf("draining cgroup failed: %s", err) } + rt.Log.Info().Msg("cgroup drained") } if err := c.destroy(); err != nil { From 7d3dd61eb8d2b21ee9781f155192a3839e8a6172 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 6 Apr 2021 06:45:26 +0200 Subject: [PATCH 283/373] Unexport isUserUID. Signed-off-by: Ruben Jenster --- container.go | 25 +++++++++++++++++++++++++ init.go | 27 +-------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/container.go b/container.go index 7c29cb6d..d508d7fb 100644 --- a/container.go +++ b/container.go @@ -70,6 +70,31 @@ type Container struct { runtimeDir string } +// Return true if init user is mapped to runtime user +func (c *Container) isUserUID() bool { + cuid := uint32(os.Getuid()) + puid := c.Process.User.UID + + // no id mappings + if len(c.Linux.UIDMappings) == 0 { + return puid == cuid + } + + for _, idmap := range c.Linux.UIDMappings { + if idmap.Size < 1 { + continue + } + maxID := idmap.ContainerID + idmap.Size - 1 + // check if c.Process.UID is contained in the mapping + if (puid >= idmap.ContainerID) && (puid <= maxID) { + offset := puid - idmap.ContainerID + hostid := idmap.HostID + offset + return hostid == cuid + } + } + return false +} + func (c *Container) create() error { if err := os.MkdirAll(c.runtimeDir, 0777); err != nil { return fmt.Errorf("failed to create container dir: %w", err) diff --git a/init.go b/init.go index e7b59385..2a1019a1 100644 --- a/init.go +++ b/init.go @@ -32,31 +32,6 @@ func createFifo(dst string, mode uint32) error { return nil } -// Return true if init user is mapped to runtime user -func (c *Container) IsUserUID() bool { - cuid := uint32(os.Getuid()) - puid := c.Process.User.UID - - // no id mappings - if len(c.Linux.UIDMappings) == 0 { - return puid == cuid - } - - for _, idmap := range c.Linux.UIDMappings { - if idmap.Size < 1 { - continue - } - maxID := idmap.ContainerID + idmap.Size - 1 - // check if c.Process.UID is contained in the mapping - if (puid >= idmap.ContainerID) && (puid <= maxID) { - offset := puid - idmap.ContainerID - hostid := idmap.HostID + offset - return hostid == cuid - } - } - return false -} - func configureInit(rt *Runtime, c *Container) error { runtimeInitDir := c.RuntimePath(initDir) //rootfsInitDir := filepath.Join(c.Root.Path, initDir) @@ -85,7 +60,7 @@ func configureInit(rt *Runtime, c *Container) error { } // create files required for lxcri-init - if c.IsUserUID() { + if c.isUserUID() { if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } From c9b327032cfe924fa30b52eae19b516d77d009d6 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 6 Apr 2021 07:25:36 +0200 Subject: [PATCH 284/373] actions: Keep PATH when running tests with sudo. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 6 ++++-- Makefile | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f48e52a..f6152f29 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,5 +42,7 @@ jobs: - name: Run tests run: | - sudo make install - sudo make test + # keep PATH to use go installed through actions/setup-go@v2 + # and not the system version (which is currently go 1.15.x) + sudo -E "PATH=$PATH" make install + sudo -E "PATH=$PATH" make test diff --git a/Makefile b/Makefile index 9c0c2784..7cf0ff61 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ fmt: .PHONY: test test: build - go build ./cmd/lxcri-test + go build -a ./cmd/lxcri-test go test --count 1 -v ./... build: $(BINS) $(LIBEXEC_BINS) From 3918265f3ed7948aa8065980699f849a52b8a0be Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 6 Apr 2021 09:52:00 +0200 Subject: [PATCH 285/373] actions: Run tests as user and root. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6152f29..d2082269 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,9 +38,22 @@ jobs: sudo apt-get install -qq lxc-dev musl musl-tools libc6-dev pkg-config make - name: Build - run: make build + run: | + make build + sudo -E "PATH=$PATH" make install - - name: Run tests + - name: Test unprivileged + run: | + # keep PATH to use go installed through actions/setup-go@v2 + # and not the system version (which is currently go 1.15.x) + sudo /bin/sh -c "echo '$(whoami):1000:1' >> /etc/subuid" + sudo /bin/sh -c "echo '$(whoami):20000:65536' >> /etc/subuid" + sudo /bin/sh -c "echo '$(whoami):1000:1' >> /etc/subgid" + sudo /bin/sh -c "echo '$(whoami):20000:65536' >> /etc/subgid" + sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup/unified$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) + make test + + - name: Test privileged run: | # keep PATH to use go installed through actions/setup-go@v2 # and not the system version (which is currently go 1.15.x) From c968955fe29c3282ff829749d21d089c5f9668ed Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 8 Apr 2021 00:29:28 +0200 Subject: [PATCH 286/373] Add runtime hook examples. Signed-off-by: Ruben Jenster --- create.go | 13 +++++++++++++ runtime_test.go | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/create.go b/create.go index a107875d..26d78b56 100644 --- a/create.go +++ b/create.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "os/exec" "path/filepath" "strings" @@ -35,6 +36,18 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container c.OnCreate(ctx, c) } + if cfg.Spec.Hooks != nil { + for i, hook := range cfg.Spec.Hooks.CreateRuntime { + cmd := exec.Command(hook.Path, hook.Args...) + cmd.Env = hook.Env + out, err := cmd.CombinedOutput() + if err != nil { + rt.Log.Error().Msgf("failed to run hook CreateRuntime[%d]: %s", i, err) + } + println(string(out)) + } + } + if err := configureContainer(rt, c); err != nil { return c, errorf("failed to configure container: %w", err) } diff --git a/runtime_test.go b/runtime_test.go index 42d143c6..445ba6b4 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -163,10 +163,28 @@ func TestRuntimeUnprivileged2(t *testing.T) { testRuntime(t, rt, cfg) } +type HookType string + +const ( + HookCreateRuntime HookType = "CreateRuntime" +) + func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() + cfg.Spec.Hooks = &specs.Hooks{} + cfg.Spec.Hooks.CreateRuntime = append(cfg.Spec.Hooks.CreateRuntime, + specs.Hook{ + Path: "/tmp/myhook.sh", + //Args: []string{}, + Env: []string{ + "LXCRI_CONTAINER_ID=" + cfg.ContainerID, + "LXCRI_RUNTIME_ROOT=" + rt.Root, + "LXCRI_HOOK_TYPE=" + string(HookCreateRuntime), + }, + }) + c, err := rt.Create(ctx, cfg) require.NoError(t, err) require.NotNil(t, c) From db1c6e5bec9f3a75579d00bafe7f34bec4d6a63e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 09:00:10 +0200 Subject: [PATCH 287/373] Set LibexecDir to default to fix 'go test -run' Signed-off-by: Ruben Jenster --- runtime_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime_test.go b/runtime_test.go index 445ba6b4..364cee88 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -34,6 +34,9 @@ func newRuntime(t *testing.T) *Runtime { Root: runtimeRoot, LibexecDir: os.Getenv("LIBEXEC_DIR"), } + if rt.LibexecDir == "" { + rt.LibexecDir = "/usr/local/libexec/lxcri" + } //ExecInit = "lxcri-debug" require.NoError(t, rt.Init()) return rt @@ -210,7 +213,7 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { require.NoError(t, err) require.Equal(t, specs.StateRunning, state.Status) - time.Sleep(time.Second * 3) + time.Sleep(time.Millisecond * 500) // SIGHUP by default terminates a process if it is not ignored or catched by // a signal handler From 0ebee36bd6f5a3e5db34a0fccbebb50977614b71 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 09:33:14 +0200 Subject: [PATCH 288/373] Fix file descriptor leak and permissions in encodeFileJSON. Signed-off-by: Ruben Jenster --- utils.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/utils.go b/utils.go index 9e757e7c..9e3fe077 100644 --- a/utils.go +++ b/utils.go @@ -60,29 +60,34 @@ func decodeFileJSON(obj interface{}, src string) error { err = json.NewDecoder(f).Decode(obj) if err != nil { f.Close() - return fmt.Errorf("failed to decode JSON from %s: %w", src, err) + return errorf("failed to decode JSON from %s: %w", src, err) } err = f.Close() if err != nil { - return fmt.Errorf("failed to close %s: %w", src, err) + return errorf("failed to close %s: %w", src, err) } return nil } -func encodeFileJSON(dst string, obj interface{}, flags int, mode uint32) error { - f, err := os.OpenFile(dst, flags, os.FileMode(mode)) +func encodeFileJSON(dst string, obj interface{}, flags int, mode os.FileMode) error { + f, err := os.OpenFile(dst, flags, mode) if err != nil { return err } enc := json.NewEncoder(f) - //enc.SetIndent("", " ") err = enc.Encode(obj) if err != nil { f.Close() - return fmt.Errorf("failed to encode JSON to %s: %w", dst, err) + return errorf("failed to encode JSON to %s: %w", dst, err) } + err = f.Close() + if err != nil { + return errorf("failed to close %s: %w", dst, err) + } + // Use chmod because initial mode is affected by umask and flags. + err = os.Chmod(dst, mode) if err != nil { - return fmt.Errorf("failed to close %s: %w", dst, err) + return errorf("failed to 'chmod %o %s': %w", mode, dst, err) } return nil } From b7276841c075d3d22518d001a7c377cc8aeba93d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 09:53:42 +0200 Subject: [PATCH 289/373] Set Spec.Version. Signed-off-by: Ruben Jenster --- runtime.go | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime.go b/runtime.go index 09c48a4c..baf921ff 100644 --- a/runtime.go +++ b/runtime.go @@ -304,6 +304,7 @@ func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { proc := NewSpecProcess(cmd, args...) return &specs.Spec{ + Version: specs.Version, Linux: &specs.Linux{ Namespaces: []specs.LinuxNamespace{ // isolate all namespaces by default From 3b746bf18aa9a1c1374bdd64e02099f10da66e83 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 10:34:02 +0200 Subject: [PATCH 290/373] Separate spec from container runtime state. This allows external tools (e.g runtime hooks) to read the spec without having to unwrap it from the runtime state. Signed-off-by: Ruben Jenster --- container.go | 11 ++++++++++- create.go | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/container.go b/container.go index d508d7fb..1207d496 100644 --- a/container.go +++ b/container.go @@ -16,7 +16,10 @@ import ( // ContainerConfig is the configuration for a single Container instance. type ContainerConfig struct { - *specs.Spec + // The modified/updated Spec used to generate the liblxc config. + // It's serialized to a separate file to allow external tool access, + // without the need to import lxcri. + *specs.Spec `json:"-"` // ContainerID is the identifier of the container. // The ContainerID is used as name for the containers runtime directory. @@ -127,6 +130,12 @@ func (c *Container) load() error { return fmt.Errorf("failed to load container config: %w", err) } + c.Spec = new(specs.Spec) + err = decodeFileJSON(c.Spec, c.RuntimePath("spec.json")) + if err != nil { + return fmt.Errorf("failed to load container spec: %w", err) + } + _, err = os.Stat(c.ConfigFilePath()) if err != nil { return fmt.Errorf("failed to load lxc config file: %w", err) diff --git a/create.go b/create.go index 26d78b56..d6472412 100644 --- a/create.go +++ b/create.go @@ -52,12 +52,22 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to configure container: %w", err) } + specPath := c.RuntimePath("spec.json") + err := encodeFileJSON(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) + if err != nil { + return c, err + } + if err := rt.runStartCmd(ctx, c); err != nil { return c, errorf("failed to run container process: %w", err) } p := c.RuntimePath("container.json") - err := encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0640) + err = encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) + if err != nil { + return c, err + } + return c, err } From 9b8a84f1c68784af4074191c30e3670423ce7c21 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 11:55:32 +0200 Subject: [PATCH 291/373] Cleanup user ID mapping detection. Signed-off-by: Ruben Jenster --- container.go | 26 +++++++++++--------------- init.go | 2 +- runtime.go | 6 ++++++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/container.go b/container.go index 1207d496..72d91383 100644 --- a/container.go +++ b/container.go @@ -73,29 +73,25 @@ type Container struct { runtimeDir string } -// Return true if init user is mapped to runtime user -func (c *Container) isUserUID() bool { - cuid := uint32(os.Getuid()) - puid := c.Process.User.UID - - // no id mappings - if len(c.Linux.UIDMappings) == 0 { - return puid == cuid - } - - for _, idmap := range c.Linux.UIDMappings { +// unmapContainerID returns the (user/group) ID to which the given +// ID is mapped to by the given idmaps. +// The returned id will be equal to the given id +// if it is not mapped by the given idmaps. +func unmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { + for _, idmap := range idmaps { if idmap.Size < 1 { continue } maxID := idmap.ContainerID + idmap.Size - 1 // check if c.Process.UID is contained in the mapping - if (puid >= idmap.ContainerID) && (puid <= maxID) { - offset := puid - idmap.ContainerID + if (id >= idmap.ContainerID) && (id <= maxID) { + offset := id - idmap.ContainerID hostid := idmap.HostID + offset - return hostid == cuid + return hostid } } - return false + // uid is not mapped + return id } func (c *Container) create() error { diff --git a/init.go b/init.go index 2a1019a1..927b6f30 100644 --- a/init.go +++ b/init.go @@ -60,7 +60,7 @@ func configureInit(rt *Runtime, c *Container) error { } // create files required for lxcri-init - if c.isUserUID() { + if rt.runAsRuntimeUser(c) { if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } diff --git a/runtime.go b/runtime.go index baf921ff..9ce0c956 100644 --- a/runtime.go +++ b/runtime.go @@ -112,6 +112,12 @@ func (rt *Runtime) Load(containerID string) (*Container, error) { return c, nil } +// runAsRuntimeUser returns true if container process is started as runtime user. +func (rt *Runtime) runAsRuntimeUser(c *Container) bool { + puid := unmapContainerID(c.Process.User.UID, c.Linux.UIDMappings) + return puid == uint32(os.Getuid()) +} + // Start starts the given container. // Start simply unblocks the container init process `lxcri-init`, // which then executes the actuall container process. From 6119e3097d95e865e8bf3267ef7aff69127359ab Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 12:11:01 +0200 Subject: [PATCH 292/373] Introduce spec_utils.go Collect helper functions that operate on specs.Spec without internal knowledge within an separate file. Signed-off-by: Ruben Jenster --- container.go | 21 --------------------- spec_utils.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 spec_utils.go diff --git a/container.go b/container.go index 72d91383..e0d7d41a 100644 --- a/container.go +++ b/container.go @@ -73,27 +73,6 @@ type Container struct { runtimeDir string } -// unmapContainerID returns the (user/group) ID to which the given -// ID is mapped to by the given idmaps. -// The returned id will be equal to the given id -// if it is not mapped by the given idmaps. -func unmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { - for _, idmap := range idmaps { - if idmap.Size < 1 { - continue - } - maxID := idmap.ContainerID + idmap.Size - 1 - // check if c.Process.UID is contained in the mapping - if (id >= idmap.ContainerID) && (id <= maxID) { - offset := id - idmap.ContainerID - hostid := idmap.HostID + offset - return hostid - } - } - // uid is not mapped - return id -} - func (c *Container) create() error { if err := os.MkdirAll(c.runtimeDir, 0777); err != nil { return fmt.Errorf("failed to create container dir: %w", err) diff --git a/spec_utils.go b/spec_utils.go new file mode 100644 index 00000000..f95f7f13 --- /dev/null +++ b/spec_utils.go @@ -0,0 +1,30 @@ +package lxcri + +import ( + "github.com/opencontainers/runtime-spec/specs-go" +) + +// This file is only for helper functions that operate +// on (parts of) the runtime spec specs.Spec +// without any internal internal knowledge. + +// unmapContainerID returns the (user/group) ID to which the given +// ID is mapped to by the given idmaps. +// The returned id will be equal to the given id +// if it is not mapped by the given idmaps. +func unmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { + for _, idmap := range idmaps { + if idmap.Size < 1 { + continue + } + maxID := idmap.ContainerID + idmap.Size - 1 + // check if c.Process.UID is contained in the mapping + if (id >= idmap.ContainerID) && (id <= maxID) { + offset := id - idmap.ContainerID + hostid := idmap.HostID + offset + return hostid + } + } + // uid is not mapped + return id +} From 088e89dd30f374fa98953fc58867f4a3b1173733 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 14:12:27 +0200 Subject: [PATCH 293/373] Remove embedded spec.Spec from ContainerConfig. Access the Spec through ContainerConfig.Spec field instead. This makes access to it obvious within the code and avoids shadowing. This is the first step in order to separate Spec modifications from the actual translation to the liblxc configuration. Signed-off-by: Ruben Jenster --- cgroup.go | 20 +++++------ container.go | 8 ++--- create.go | 91 +++++++++++++++++++++++++------------------------ devices.go | 32 ++++++++--------- init.go | 30 ++++++++-------- mount.go | 16 ++++----- namespaces.go | 4 +-- runtime.go | 2 +- runtime_test.go | 24 ++++++------- 9 files changed, 115 insertions(+), 112 deletions(-) diff --git a/cgroup.go b/cgroup.go index 5ec31e93..03d29a45 100644 --- a/cgroup.go +++ b/cgroup.go @@ -43,7 +43,7 @@ func configureCgroup(rt *Runtime, c *Container) error { return err } - if devices := c.Linux.Resources.Devices; devices != nil { + if devices := c.Spec.Linux.Resources.Devices; devices != nil { if rt.Features.CgroupDevices { if err := configureDeviceController(c); err != nil { return err @@ -54,30 +54,30 @@ func configureCgroup(rt *Runtime, c *Container) error { } - if mem := c.Linux.Resources.Memory; mem != nil { + if mem := c.Spec.Linux.Resources.Memory; mem != nil { c.Log.Debug().Msg("TODO cgroup memory controller not implemented") } - if cpu := c.Linux.Resources.CPU; cpu != nil { + if cpu := c.Spec.Linux.Resources.CPU; cpu != nil { if err := configureCPUController(rt, cpu); err != nil { return err } } - if pids := c.Linux.Resources.Pids; pids != nil { + if pids := c.Spec.Linux.Resources.Pids; pids != nil { if err := c.SetConfigItem("lxc.cgroup2.pids.max", fmt.Sprintf("%d", pids.Limit)); err != nil { return err } } - if blockio := c.Linux.Resources.BlockIO; blockio != nil { + if blockio := c.Spec.Linux.Resources.BlockIO; blockio != nil { c.Log.Debug().Msg("TODO cgroup blockio controller not implemented") } - if hugetlb := c.Linux.Resources.HugepageLimits; hugetlb != nil { + if hugetlb := c.Spec.Linux.Resources.HugepageLimits; hugetlb != nil { // set Hugetlb limit (in bytes) c.Log.Debug().Msg("TODO cgroup hugetlb controller not implemented") } - if net := c.Linux.Resources.Network; net != nil { + if net := c.Spec.Linux.Resources.Network; net != nil { c.Log.Debug().Msg("TODO cgroup network controller not implemented") } return nil @@ -86,9 +86,9 @@ func configureCgroup(rt *Runtime, c *Container) error { func configureCgroupPath(rt *Runtime, c *Container) error { if rt.SystemdCgroup { - c.CgroupDir = parseSystemdCgroupPath(c.Linux.CgroupsPath) + c.CgroupDir = parseSystemdCgroupPath(c.Spec.Linux.CgroupsPath) } else { - c.CgroupDir = c.Linux.CgroupsPath + c.CgroupDir = c.Spec.Linux.CgroupsPath } c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") @@ -147,7 +147,7 @@ func configureDeviceController(c *Container) error { blockDevice := "b" charDevice := "c" - for _, dev := range c.Linux.Resources.Devices { + for _, dev := range c.Spec.Linux.Resources.Devices { key := devicesDeny if dev.Allow { key = devicesAllow diff --git a/container.go b/container.go index e0d7d41a..bfa9b380 100644 --- a/container.go +++ b/container.go @@ -19,7 +19,7 @@ type ContainerConfig struct { // The modified/updated Spec used to generate the liblxc config. // It's serialized to a separate file to allow external tool access, // without the need to import lxcri. - *specs.Spec `json:"-"` + Spec *specs.Spec `json:"-"` // ContainerID is the identifier of the container. // The ContainerID is used as name for the containers runtime directory. @@ -194,7 +194,7 @@ func (c *Container) State() (*specs.State, error) { ID: c.ContainerID, Bundle: c.BundlePath, Pid: c.Pid, - Annotations: c.Annotations, + Annotations: c.Spec.Annotations, Status: status, } return state, nil @@ -393,7 +393,7 @@ func (c *Container) readFifo() error { // It's up to the caller to wait for the process to exit using the returned PID. // The container state must be either specs.StateCreated or specs.StateRunning func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { - opts, err := attachOptions(proc, c.Linux.Namespaces) + opts, err := attachOptions(proc, c.Spec.Linux.Namespaces) if err != nil { return 0, errorf("failed to create attach options: %w", err) } @@ -413,7 +413,7 @@ func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, e // It waits for the process to exit and returns its exit code. // The container state must either be specs.StateCreated or specs.StateRunning func (c *Container) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { - opts, err := attachOptions(proc, c.Linux.Namespaces) + opts, err := attachOptions(proc, c.Spec.Linux.Namespaces) if err != nil { return 0, errorf("failed to create attach options: %w", err) } diff --git a/create.go b/create.go index d6472412..5d56b141 100644 --- a/create.go +++ b/create.go @@ -119,32 +119,35 @@ func (rt *Runtime) Init() error { return nil } -func (rt *Runtime) checkConfig(config *ContainerConfig) error { - if len(config.ContainerID) == 0 { +func (rt *Runtime) checkConfig(cfg *ContainerConfig) error { + if len(cfg.ContainerID) == 0 { return errorf("missing container ID") } + return rt.checkSpec(cfg.Spec) +} - if config.Root == nil { - return errorf("config.Root is nil") +func (rt *Runtime) checkSpec(spec *specs.Spec) error { + if spec.Root == nil { + return errorf("spec.Root is nil") } - if len(config.Root.Path) == 0 { - return errorf("empty config.Root.Path") + if len(spec.Root.Path) == 0 { + return errorf("empty spec.Root.Path") } - if config.Process == nil { - return errorf("config.Process is nil") + if spec.Process == nil { + return errorf("spec.Process is nil") } - if len(config.Process.Args) == 0 { - return errorf("configs.Process.Args is empty") + if len(spec.Process.Args) == 0 { + return errorf("specs.Process.Args is empty") } - if config.Process.Cwd == "" { - rt.Log.Info().Msg("configs.Process.Cwd is unset defaulting to '/'") - config.Process.Cwd = "/" + if spec.Process.Cwd == "" { + rt.Log.Info().Msg("specs.Process.Cwd is unset defaulting to '/'") + spec.Process.Cwd = "/" } - yes, err := isHostNamespaceShared(config.Linux.Namespaces, specs.MountNamespace) + yes, err := isHostNamespaceShared(spec.Linux.Namespaces, specs.MountNamespace) if err != nil { return err } @@ -154,7 +157,7 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { // It should be best practise not to do so, but there are containers that // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set - yes, err = isHostNamespaceShared(config.Linux.Namespaces, specs.PIDNamespace) + yes, err = isHostNamespaceShared(spec.Linux.Namespaces, specs.PIDNamespace) if err != nil { return err } @@ -165,14 +168,14 @@ func (rt *Runtime) checkConfig(config *ContainerConfig) error { } func configureContainer(rt *Runtime, c *Container) error { - if c.Hostname != "" { - if err := c.SetConfigItem("lxc.uts.name", c.Hostname); err != nil { + if c.Spec.Hostname != "" { + if err := c.SetConfigItem("lxc.uts.name", c.Spec.Hostname); err != nil { return err } - uts := getNamespace(specs.UTSNamespace, c.Linux.Namespaces) + uts := getNamespace(specs.UTSNamespace, c.Spec.Linux.Namespaces) if uts != nil && uts.Path != "" { - if err := setHostname(uts.Path, c.Hostname); err != nil { + if err := setHostname(uts.Path, c.Spec.Hostname); err != nil { return fmt.Errorf("failed to set hostname: %w", err) } } @@ -190,7 +193,7 @@ func configureContainer(rt *Runtime, c *Container) error { // ensure user namespace is enabled if !isNamespaceEnabled(c.Spec, specs.UserNamespace) { rt.Log.Warn().Msg("unprivileged runtime - enabling user namespace") - c.Linux.Namespaces = append(c.Linux.Namespaces, + c.Spec.Linux.Namespaces = append(c.Spec.Linux.Namespaces, specs.LinuxNamespace{Type: specs.UserNamespace}, ) } @@ -199,13 +202,13 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure namespaces: %w", err) } - if c.Process.OOMScoreAdj != nil { - if err := c.SetConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *c.Process.OOMScoreAdj)); err != nil { + if c.Spec.Process.OOMScoreAdj != nil { + if err := c.SetConfigItem("lxc.proc.oom_score_adj", fmt.Sprintf("%d", *c.Spec.Process.OOMScoreAdj)); err != nil { return err } } - if c.Process.NoNewPrivileges { + if c.Spec.Process.NoNewPrivileges { if err := c.SetConfigItem("lxc.no_new_privs", "1"); err != nil { return err } @@ -220,9 +223,9 @@ func configureContainer(rt *Runtime, c *Container) error { } if rt.Features.Seccomp { - if c.Linux.Seccomp != nil && len(c.Linux.Seccomp.Syscalls) > 0 { + if c.Spec.Linux.Seccomp != nil && len(c.Spec.Linux.Seccomp.Syscalls) > 0 { profilePath := c.RuntimePath("seccomp.conf") - if err := writeSeccompProfile(profilePath, c.Linux.Seccomp); err != nil { + if err := writeSeccompProfile(profilePath, c.Spec.Linux.Seccomp); err != nil { return err } if err := c.SetConfigItem("lxc.seccomp.profile", profilePath); err != nil { @@ -246,18 +249,18 @@ func configureContainer(rt *Runtime, c *Container) error { return err } - ensureDefaultDevices(c) + ensureDefaultDevices(c.Spec) if rt.privileged { // devices are created with mknod in lxcri-hook - if err := writeDevices(c.RuntimePath("devices.txt"), c); err != nil { + if err := createDeviceFile(c.RuntimePath("devices.txt"), c.Spec); err != nil { return fmt.Errorf("failed to create devices.txt: %w", err) } } else { // if running as non-root bind mount devices, because user can not execute mknod - newMounts := make([]specs.Mount, 0, len(c.Mounts)+len(c.Linux.Devices)) - for _, m := range c.Mounts { + newMounts := make([]specs.Mount, 0, len(c.Spec.Mounts)+len(c.Spec.Linux.Devices)) + for _, m := range c.Spec.Mounts { if m.Destination == "/dev" { rt.Log.Info().Msg("unprivileged runtime - removing /dev mount") continue @@ -265,13 +268,13 @@ func configureContainer(rt *Runtime, c *Container) error { newMounts = append(newMounts, m) } rt.Log.Info().Msg("unprivileged runtime - bind mount devices") - for _, device := range c.Linux.Devices { + for _, device := range c.Spec.Linux.Devices { newMounts = append(newMounts, specs.Mount{Destination: device.Path, Source: device.Path, Type: "bind", Options: []string{"bind", "create=file"}}, ) } - c.Mounts = newMounts + c.Spec.Mounts = newMounts } if err := writeMasked(c.RuntimePath("masked.txt"), c); err != nil { @@ -290,7 +293,7 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure cgroups: %w", err) } - for key, val := range c.Linux.Sysctl { + for key, val := range c.Spec.Linux.Sysctl { if err := c.SetConfigItem("lxc.sysctl."+key, val); err != nil { return err } @@ -298,8 +301,8 @@ func configureContainer(rt *Runtime, c *Container) error { // `man lxc.container.conf`: "A resource with no explicitly configured limitation will be inherited // from the process starting up the container" - seenLimits := make([]string, 0, len(c.Process.Rlimits)) - for _, limit := range c.Process.Rlimits { + seenLimits := make([]string, 0, len(c.Spec.Process.Rlimits)) + for _, limit := range c.Spec.Process.Rlimits { name := strings.TrimPrefix(strings.ToLower(limit.Type), "rlimit_") for _, seen := range seenLimits { if seen == name { @@ -329,7 +332,7 @@ func configureContainer(rt *Runtime, c *Container) error { } func configureRootfs(rt *Runtime, c *Container) error { - if err := c.SetConfigItem("lxc.rootfs.path", c.Root.Path); err != nil { + if err := c.SetConfigItem("lxc.rootfs.path", c.Spec.Root.Path); err != nil { return err } @@ -347,10 +350,10 @@ func configureRootfs(rt *Runtime, c *Container) error { } rootfsOptions := []string{} - if c.Linux.RootfsPropagation != "" { - rootfsOptions = append(rootfsOptions, c.Linux.RootfsPropagation) + if c.Spec.Linux.RootfsPropagation != "" { + rootfsOptions = append(rootfsOptions, c.Spec.Linux.RootfsPropagation) } - if c.Root.Readonly { + if c.Spec.Root.Readonly { rootfsOptions = append(rootfsOptions, "ro") } if err := c.SetConfigItem("lxc.rootfs.options", strings.Join(rootfsOptions, ",")); err != nil { @@ -364,7 +367,7 @@ func configureReadonlyPaths(c *Container) error { if rootmnt == "" { return fmt.Errorf("lxc.rootfs.mount unavailable") } - for _, p := range c.Linux.ReadonlyPaths { + for _, p := range c.Spec.Linux.ReadonlyPaths { mnt := fmt.Sprintf("%s %s %s %s", filepath.Join(rootmnt, p), strings.TrimPrefix(p, "/"), "bind", "bind,ro,optional") if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { return fmt.Errorf("failed to make path readonly: %w", err) @@ -375,7 +378,7 @@ func configureReadonlyPaths(c *Container) error { func configureApparmor(c *Container) error { // The value *apparmor_profile* from crio.conf is used if no profile is defined by the container. - aaprofile := c.Process.ApparmorProfile + aaprofile := c.Spec.Process.ApparmorProfile if aaprofile == "" { aaprofile = "unconfined" } @@ -388,9 +391,9 @@ func configureApparmor(c *Container) error { // https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work func configureCapabilities(c *Container) error { keepCaps := "none" - if c.Process.Capabilities != nil { + if c.Spec.Process.Capabilities != nil { var caps []string - for _, c := range c.Process.Capabilities.Permitted { + for _, c := range c.Spec.Process.Capabilities.Permitted { lcCapName := strings.TrimPrefix(strings.ToLower(c), "cap_") caps = append(caps, lcCapName) } @@ -404,14 +407,14 @@ func configureCapabilities(c *Container) error { func writeMasked(dst string, c *Container) error { // #nosec - if c.Linux.MaskedPaths == nil { + if c.Spec.Linux.MaskedPaths == nil { return nil } f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } - for _, p := range c.Linux.MaskedPaths { + for _, p := range c.Spec.Linux.MaskedPaths { _, err = fmt.Fprintln(f, p) if err != nil { f.Close() diff --git a/devices.go b/devices.go index 24ee7ff7..5f33add4 100644 --- a/devices.go +++ b/devices.go @@ -29,17 +29,17 @@ func isDeviceEnabled(c *Container, dev specs.LinuxDevice) bool { return false } -func addDevice(c *Container, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { +func addDevice(spec *specs.Spec, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { dev.FileMode = &mode dev.UID = &uid dev.GID = &gid - c.Linux.Devices = append(c.Linux.Devices, dev) - addDevicePerms(c, dev.Type, &dev.Major, &dev.Minor, access) + spec.Linux.Devices = append(spec.Linux.Devices, dev) + addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) } -func addDevicePerms(c *Container, devType string, major *int64, minor *int64, access string) { +func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64, access string) { devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} - c.Linux.Resources.Devices = append(c.Linux.Resources.Devices, devCgroup) + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) } // ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) @@ -47,38 +47,38 @@ func addDevicePerms(c *Container, devType string, major *int64, minor *int64, ac // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(c *Container) { +func ensureDefaultDevices(spec *specs.Spec) { mode := os.FileMode(0666) - var uid, gid uint32 = c.Process.User.UID, c.Process.User.GID + var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} - addDevicePerms(c, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx + addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} - addDevicePerms(c, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] + addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] // add missing default devices for _, dev := range defaultDevices { - if !isDeviceEnabled(c, dev) { - addDevice(c, dev, mode, uid, gid, "rwm") + if !isDeviceEnabled(spec, dev) { + addDevice(spec, dev, mode, uid, gid, "rwm") } } } -func writeDevices(dst string, c *Container) error { - if c.Linux.Devices == nil { +func createDeviceFile(dst string, spec *specs.Spec) error { + if spec.Linux.Devices == nil { return nil } f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return err } - for _, d := range c.Linux.Devices { - uid := c.Process.User.UID + for _, d := range spec.Linux.Devices { + uid := spec.Process.User.UID if d.UID != nil { uid = *d.UID } - gid := c.Process.User.GID + gid := spec.Process.User.GID if d.GID != nil { gid = *d.GID } diff --git a/init.go b/init.go index 927b6f30..ec943fbd 100644 --- a/init.go +++ b/init.go @@ -48,7 +48,7 @@ func configureInit(rt *Runtime, c *Container) error { return fmt.Errorf("failed to create runtime init dir %q: %w", runtimeInitDir, err) } - c.Mounts = append(c.Mounts, specs.Mount{ + c.Spec.Mounts = append(c.Spec.Mounts, specs.Mount{ Source: runtimeInitDir, Destination: strings.TrimLeft(initDir, "/"), Type: "bind", @@ -64,30 +64,30 @@ func configureInit(rt *Runtime, c *Container) error { if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Spec.Process.Args, 0400); err != nil { return err } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, 0400); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Spec.Process.Env, 0400); err != nil { return err } } else { if err := createFifo(c.syncFifoPath(), 0666); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Process.Args, 0444); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Spec.Process.Args, 0444); err != nil { return err } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Process.Env, 0444); err != nil { + if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Spec.Process.Env, 0444); err != nil { return err } } - if err := os.Symlink(c.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { + if err := os.Symlink(c.Spec.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { return err } - if c.Annotations != nil { - msgPath := c.Annotations["io.kubernetes.container.terminationMessagePath"] + if c.Spec.Annotations != nil { + msgPath := c.Spec.Annotations["io.kubernetes.container.terminationMessagePath"] if msgPath != "" { if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "error.log")); err != nil { return err @@ -106,7 +106,7 @@ func configureInit(rt *Runtime, c *Container) error { return fmt.Errorf("failed to create %s: %w", initCmdPath, err) } initCmd := filepath.Join(initDir, "init") - c.Mounts = append(c.Mounts, specs.Mount{ + c.Spec.Mounts = append(c.Spec.Mounts, specs.Mount{ Source: rt.libexec(ExecInit), Destination: strings.TrimLeft(initCmd, "/"), Type: "bind", @@ -155,28 +155,28 @@ func createList(dst string, entries []string, mode uint32) error { func configureInitUser(c *Container) error { // TODO ensure that the user namespace is enabled // See `man lxc.container.conf` lxc.idmap. - for _, m := range c.Linux.UIDMappings { + for _, m := range c.Spec.Linux.UIDMappings { if err := c.SetConfigItem("lxc.idmap", fmt.Sprintf("u %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { return err } } - for _, m := range c.Linux.GIDMappings { + for _, m := range c.Spec.Linux.GIDMappings { if err := c.SetConfigItem("lxc.idmap", fmt.Sprintf("g %d %d %d", m.ContainerID, m.HostID, m.Size)); err != nil { return err } } - if err := c.SetConfigItem("lxc.init.uid", fmt.Sprintf("%d", c.Process.User.UID)); err != nil { + if err := c.SetConfigItem("lxc.init.uid", fmt.Sprintf("%d", c.Spec.Process.User.UID)); err != nil { return err } - if err := c.SetConfigItem("lxc.init.gid", fmt.Sprintf("%d", c.Process.User.GID)); err != nil { + if err := c.SetConfigItem("lxc.init.gid", fmt.Sprintf("%d", c.Spec.Process.User.GID)); err != nil { return err } - if len(c.Process.User.AdditionalGids) > 0 && c.SupportsConfigItem("lxc.init.groups") { + if len(c.Spec.Process.User.AdditionalGids) > 0 && c.SupportsConfigItem("lxc.init.groups") { var b strings.Builder - for i, gid := range c.Process.User.AdditionalGids { + for i, gid := range c.Spec.Process.User.AdditionalGids { if i > 0 { b.WriteByte(',') } diff --git a/mount.go b/mount.go index 54b0f52e..0f6caf6f 100644 --- a/mount.go +++ b/mount.go @@ -48,8 +48,8 @@ func configureMounts(rt *Runtime, c *Container) error { return err } - for i := range c.Mounts { - ms := c.Mounts[i] + for i := range c.Spec.Mounts { + ms := c.Spec.Mounts[i] if ms.Type == "cgroup" { // TODO check if hieararchy is cgroup v2 only (unified mode) ms.Type = "cgroup2" @@ -62,15 +62,15 @@ func configureMounts(rt *Runtime, c *Container) error { // TODO replace with symlink.FollowSymlinkInScope(filepath.Join(rootfs, "/etc/passwd"), rootfs) ? // "github.com/docker/docker/pkg/symlink" - mountDest, err := resolveMountDestination(c.Root.Path, ms.Destination) + mountDest, err := resolveMountDestination(c.Spec.Root.Path, ms.Destination) // Intermediate path resolution failed. This is not an error, since // the remaining directories / files are automatically created (create=dir|file) rt.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. - if !filepath.HasPrefix(mountDest, c.Root.Path) { + if !filepath.HasPrefix(mountDest, c.Spec.Root.Path) { // refuses mount destinations that escape from rootfs - return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, c.Root.Path) + return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, c.Spec.Root.Path) } ms.Destination = mountDest @@ -99,7 +99,7 @@ func configureMounts(rt *Runtime, c *Container) error { // TODO check whether this is desired behaviour in lxc ? // Shouldn't the rootfs should be mounted readonly after all mounts destination directories have been created ? // https://github.com/lxc/lxc/issues/1702 -func createMountDestination(spec *Container, ms *specs.Mount) error { +func createMountDestination(c *Container, ms *specs.Mount) error { info, err := os.Stat(ms.Source) // source for bind mount must exist @@ -114,14 +114,14 @@ func createMountDestination(spec *Container, ms *specs.Mount) error { if err != nil || info.IsDir() { ms.Options = append(ms.Options, "create=dir") - if spec.Root.Readonly { + if c.Spec.Root.Readonly { return os.MkdirAll(ms.Destination, 0755) } return nil } ms.Options = append(ms.Options, "create=file") - if spec.Root.Readonly { + if c.Spec.Root.Readonly { if err := os.MkdirAll(filepath.Dir(ms.Destination), 0755); err != nil { return fmt.Errorf("failed to create mount destination dir: %w", err) } diff --git a/namespaces.go b/namespaces.go index 24fe9509..1d007f20 100644 --- a/namespaces.go +++ b/namespaces.go @@ -55,9 +55,9 @@ func cloneFlags(namespaces []specs.LinuxNamespace) (int, error) { func configureNamespaces(c *Container) error { seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} - cloneNamespaces := make([]string, 0, len(c.Linux.Namespaces)) + cloneNamespaces := make([]string, 0, len(c.Spec.Linux.Namespaces)) - for _, ns := range c.Linux.Namespaces { + for _, ns := range c.Spec.Linux.Namespaces { if _, seen := seenNamespaceTypes[ns.Type]; seen { return fmt.Errorf("duplicate namespace %s", ns.Type) } diff --git a/runtime.go b/runtime.go index 9ce0c956..a8bc1e5e 100644 --- a/runtime.go +++ b/runtime.go @@ -142,7 +142,7 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { cmd.Env = rt.env cmd.Dir = c.RuntimePath() - if c.ConsoleSocket == "" && !c.Process.Terminal { + if c.ConsoleSocket == "" && !c.Spec.Process.Terminal { // Inherit stdio from calling process (conmon). // lxc.console.path must be set to 'none' or stdio of init process is replaced with a PTY by lxc if err := c.SetConfigItem("lxc.console.path", "none"); err != nil { diff --git a/runtime_test.go b/runtime_test.go index 364cee88..abe8ca12 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -54,7 +54,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true)} - cfg.Linux.CgroupsPath = "" // use /proc/self/cgroup" + cfg.Spec.Linux.CgroupsPath = "" // use /proc/self/cgroup" cfg.LogFile = "/dev/stderr" cfg.LogLevel = "trace" @@ -66,11 +66,11 @@ func TestEmptyNamespaces(t *testing.T) { defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - defer os.RemoveAll(cfg.Root.Path) + defer os.RemoveAll(cfg.Spec.Root.Path) // Clearing all namespaces should not work, // since the mount namespace must never be shared with the host. - cfg.Linux.Namespaces = cfg.Linux.Namespaces[0:0] + cfg.Spec.Linux.Namespaces = cfg.Spec.Linux.Namespaces[0:0] ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() @@ -83,7 +83,7 @@ func TestEmptyNamespaces(t *testing.T) { Type: specs.PIDNamespace, Path: fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()), } - cfg.Linux.Namespaces = append(cfg.Linux.Namespaces, pidns) + cfg.Spec.Linux.Namespaces = append(cfg.Spec.Linux.Namespaces, pidns) c, err = rt.Create(ctx, cfg) require.Error(t, err) @@ -99,7 +99,7 @@ func TestRuntimePrivileged(t *testing.T) { defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - defer os.RemoveAll(cfg.Root.Path) + defer os.RemoveAll(cfg.Spec.Root.Path) testRuntime(t, rt, cfg) } @@ -122,23 +122,23 @@ func TestRuntimeUnprivileged(t *testing.T) { defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - defer os.RemoveAll(cfg.Root.Path) + defer os.RemoveAll(cfg.Spec.Root.Path) // The container UID must have full access to the rootfs. // MkdirTemp sets directory permissions to 0700. // If we the container UID (0) / or GID are not mapped to the owner (creator) of the rootfs, // then the rootfs and runtime directory permissions must be expanded. - err := unix.Chmod(cfg.Root.Path, 0777) + err := unix.Chmod(cfg.Spec.Root.Path, 0777) require.NoError(t, err) err = unix.Chmod(rt.Root, 0755) require.NoError(t, err) - cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + cfg.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, } - cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + cfg.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: 20000, Size: 65536}, } @@ -150,14 +150,14 @@ func TestRuntimeUnprivileged2(t *testing.T) { defer os.RemoveAll(rt.Root) cfg := newConfig(t, "lxcri-test") - defer os.RemoveAll(cfg.Root.Path) + defer os.RemoveAll(cfg.Spec.Root.Path) if os.Getuid() != 0 { - cfg.Linux.UIDMappings = []specs.LinuxIDMapping{ + cfg.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } - cfg.Linux.GIDMappings = []specs.LinuxIDMapping{ + cfg.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } From 149ae4c88c90ddcbdef1e1dcb3fbc267749d1fdc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 14:45:39 +0200 Subject: [PATCH 294/373] Check device type, major and minor number for default devices. Signed-off-by: Ruben Jenster --- create.go | 4 +++- devices.go | 28 +++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/create.go b/create.go index 5d56b141..c1201b98 100644 --- a/create.go +++ b/create.go @@ -249,7 +249,9 @@ func configureContainer(rt *Runtime, c *Container) error { return err } - ensureDefaultDevices(c.Spec) + if err := ensureDefaultDevices(c.Spec); err != nil { + return err + } if rt.privileged { // devices are created with mknod in lxcri-hook diff --git a/devices.go b/devices.go index 5f33add4..1533d074 100644 --- a/devices.go +++ b/devices.go @@ -20,13 +20,22 @@ var defaultDevices = []specs.LinuxDevice{ // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` } -func isDeviceEnabled(c *Container, dev specs.LinuxDevice) bool { - for _, specDev := range c.Linux.Devices { - if specDev.Path == dev.Path { - return true +func isDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) (bool, error) { + for _, d := range spec.Linux.Devices { + if d.Path == dev.Path { + if d.Type != dev.Type { + return false, errorf("%s type mismatch (expected %s but was %s)", dev, dev.Type, d.Type) + } + if d.Major != dev.Major { + return false, errorf("%s major number mismatch (expected %d but was %d)", dev, dev.Major, d.Major) + } + if d.Minor != dev.Minor { + return false, errorf("%s major number mismatch (expected %d but was %d)", dev, dev.Major, d.Major) + } + return true, nil } } - return false + return false, nil } func addDevice(spec *specs.Spec, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { @@ -47,7 +56,7 @@ func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64 // crio can add devices to containers, but this does not work for privileged containers. // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 // TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(spec *specs.Spec) { +func ensureDefaultDevices(spec *specs.Spec) error { mode := os.FileMode(0666) var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID @@ -59,10 +68,15 @@ func ensureDefaultDevices(spec *specs.Spec) { // add missing default devices for _, dev := range defaultDevices { - if !isDeviceEnabled(spec, dev) { + exist, err := isDeviceEnabled(spec, dev) + if err != nil { + return err + } + if !exist { addDevice(spec, dev, mode, uid, gid, "rwm") } } + return nil } func createDeviceFile(dst string, spec *specs.Spec) error { From 8bd9f51088739e64c18ef3871f632e9006889b27 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 14:47:52 +0200 Subject: [PATCH 295/373] Move process user ID check to init.go Signed-off-by: Ruben Jenster --- init.go | 8 +++++++- runtime.go | 6 ------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/init.go b/init.go index ec943fbd..175a97de 100644 --- a/init.go +++ b/init.go @@ -32,6 +32,12 @@ func createFifo(dst string, mode uint32) error { return nil } +// runAsRuntimeUser returns true if container process is started as runtime user. +func runAsRuntimeUser(spec *specs.Spec) bool { + puid := unmapContainerID(spec.Process.User.UID, spec.Linux.UIDMappings) + return puid == uint32(os.Getuid()) +} + func configureInit(rt *Runtime, c *Container) error { runtimeInitDir := c.RuntimePath(initDir) //rootfsInitDir := filepath.Join(c.Root.Path, initDir) @@ -60,7 +66,7 @@ func configureInit(rt *Runtime, c *Container) error { } // create files required for lxcri-init - if rt.runAsRuntimeUser(c) { + if runAsRuntimeUser(c.Spec) { if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } diff --git a/runtime.go b/runtime.go index a8bc1e5e..abc5fd3c 100644 --- a/runtime.go +++ b/runtime.go @@ -112,12 +112,6 @@ func (rt *Runtime) Load(containerID string) (*Container, error) { return c, nil } -// runAsRuntimeUser returns true if container process is started as runtime user. -func (rt *Runtime) runAsRuntimeUser(c *Container) bool { - puid := unmapContainerID(c.Process.User.UID, c.Linux.UIDMappings) - return puid == uint32(os.Getuid()) -} - // Start starts the given container. // Start simply unblocks the container init process `lxcri-init`, // which then executes the actuall container process. From 0a80b7890a0a02a8f2bd9c9cb7225c269796e0c3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 9 Apr 2021 20:09:29 +0200 Subject: [PATCH 296/373] cli: Fix exec command. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 13 +++++-------- container.go | 10 +++++----- runtime.go | 13 +++++++++++++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 9990f334..dafbd620 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -447,13 +447,13 @@ func doDelete(ctxcli *cli.Context) error { var execCmd = cli.Command{ Name: "exec", Usage: "execute a new process in a running container", - ArgsUsage: "", + ArgsUsage: " [COMMAND] [args...]", Action: doExec, Flags: []cli.Flag{ &cli.StringFlag{ Name: "process", Aliases: []string{"p"}, - Usage: "path to process json", + Usage: "path to process json - cmd and args are ignored if set", Value: "", }, &cli.StringFlag{ @@ -504,13 +504,10 @@ func doExec(ctxcli *cli.Context) error { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := lxcri.ReadSpecProcessJSON(ctxcli.String("process")) + procSpec, err := lxcri.LoadSpecProcess(ctxcli.String("process"), args) if err != nil { return err } - if procSpec != nil { - args = procSpec.Args - } c, err := clxc.Load(clxc.cfg.ContainerID) if err != nil { @@ -518,7 +515,7 @@ func doExec(ctxcli *cli.Context) error { } if detach { - pid, err := c.ExecDetached(args, procSpec) + pid, err := c.ExecDetached(procSpec) if err != nil { return err } @@ -526,7 +523,7 @@ func doExec(ctxcli *cli.Context) error { return createPidFile(pidFile, pid) } } else { - status, err := c.Exec(args, procSpec) + status, err := c.Exec(procSpec) if err != nil { return err } diff --git a/container.go b/container.go index bfa9b380..5027f9e1 100644 --- a/container.go +++ b/container.go @@ -392,17 +392,17 @@ func (c *Container) readFifo() error { // The given process is started and the process PID is returned. // It's up to the caller to wait for the process to exit using the returned PID. // The container state must be either specs.StateCreated or specs.StateRunning -func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, err error) { +func (c *Container) ExecDetached(proc *specs.Process) (pid int, err error) { opts, err := attachOptions(proc, c.Spec.Linux.Namespaces) if err != nil { return 0, errorf("failed to create attach options: %w", err) } - c.Log.Info().Strs("args", args). + c.Log.Info().Strs("args", proc.Args). Int("uid", opts.UID).Int("gid", opts.GID). Ints("groups", opts.Groups).Msg("execute cmd") - pid, err = c.LinuxContainer.RunCommandNoWait(args, opts) + pid, err = c.LinuxContainer.RunCommandNoWait(proc.Args, opts) if err != nil { return pid, errorf("failed to run exec cmd detached: %w", err) } @@ -412,12 +412,12 @@ func (c *Container) ExecDetached(args []string, proc *specs.Process) (pid int, e // Exec executes the given process spec within the container. // It waits for the process to exit and returns its exit code. // The container state must either be specs.StateCreated or specs.StateRunning -func (c *Container) Exec(args []string, proc *specs.Process) (exitStatus int, err error) { +func (c *Container) Exec(proc *specs.Process) (exitStatus int, err error) { opts, err := attachOptions(proc, c.Spec.Linux.Namespaces) if err != nil { return 0, errorf("failed to create attach options: %w", err) } - exitStatus, err = c.LinuxContainer.RunCommandStatus(args, opts) + exitStatus, err = c.LinuxContainer.RunCommandStatus(proc.Args, opts) if err != nil { return exitStatus, errorf("failed to run exec cmd: %w", err) } diff --git a/runtime.go b/runtime.go index abc5fd3c..5ec7602e 100644 --- a/runtime.go +++ b/runtime.go @@ -296,6 +296,19 @@ func ReadSpecProcessJSON(src string) (*specs.Process, error) { return proc, err } +// LoadSpecProcess calls ReadSpecProcessJSON if the given specProcessPath is not empty, +// otherwise it creates a new specs.Process from the given args. +// It's an error if both values are empty. +func LoadSpecProcess(specProcessPath string, args []string) (*specs.Process, error) { + if specProcessPath != "" { + return ReadSpecProcessJSON(specProcessPath) + } + if len(args) == 0 { + return nil, fmt.Errorf("spec process path and args are empty") + } + return &specs.Process{Cwd: "/", Args: args}, nil +} + // NewSpec returns a minimal spec.Spec instance, which is // required to run the given process within a container // using the given rootfs. From fabb128bf3a18f1c60c75f8d512845d518ae7129 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 10 Apr 2021 00:25:46 +0200 Subject: [PATCH 297/373] Serialize spec with runtime state to lxcri.json. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 2 +- container.go | 20 ++++++++------------ create.go | 6 ++++-- runtime.go | 6 ++++++ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index dafbd620..9a70ba70 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -293,7 +293,7 @@ func doCreate(ctxcli *cli.Context) error { if err := clxc.Init(); err != nil { return err } - specPath := filepath.Join(clxc.cfg.BundlePath, "config.json") + specPath := filepath.Join(clxc.cfg.BundlePath, lxcri.BundleConfigFile) spec, err := lxcri.ReadSpecJSON(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) diff --git a/container.go b/container.go index 5027f9e1..ad5d8e8e 100644 --- a/container.go +++ b/container.go @@ -16,10 +16,13 @@ import ( // ContainerConfig is the configuration for a single Container instance. type ContainerConfig struct { - // The modified/updated Spec used to generate the liblxc config. - // It's serialized to a separate file to allow external tool access, - // without the need to import lxcri. - Spec *specs.Spec `json:"-"` + // The Spec used to generate the liblxc config file. + // Any changes to the spec after creating the liblxc config file have no effect + // and should be avoided. + // NOTE The Spec must be serialized with the runtime config (lxcri.json) + // This is required because Spec.Annotations are required for Container.State() + // and spec.Namespaces are required for attach. + Spec *specs.Spec // ContainerID is the identifier of the container. // The ContainerID is used as name for the containers runtime directory. @@ -99,18 +102,11 @@ func (c *Container) create() error { } func (c *Container) load() error { - - err := decodeFileJSON(c, c.RuntimePath("container.json")) + err := decodeFileJSON(c, c.RuntimePath("lxcri.json")) if err != nil { return fmt.Errorf("failed to load container config: %w", err) } - c.Spec = new(specs.Spec) - err = decodeFileJSON(c.Spec, c.RuntimePath("spec.json")) - if err != nil { - return fmt.Errorf("failed to load container spec: %w", err) - } - _, err = os.Stat(c.ConfigFilePath()) if err != nil { return fmt.Errorf("failed to load lxc config file: %w", err) diff --git a/create.go b/create.go index c1201b98..c2bbe891 100644 --- a/create.go +++ b/create.go @@ -52,7 +52,9 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to configure container: %w", err) } - specPath := c.RuntimePath("spec.json") + // Seralize the modified spec.Spec separately, to make it available for + // runtime hooks. + specPath := c.RuntimePath(BundleConfigFile) err := encodeFileJSON(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) if err != nil { return c, err @@ -62,7 +64,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to run container process: %w", err) } - p := c.RuntimePath("container.json") + p := c.RuntimePath("lxcri.json") err = encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) if err != nil { return c, err diff --git a/runtime.go b/runtime.go index 5ec7602e..108acada 100644 --- a/runtime.go +++ b/runtime.go @@ -15,6 +15,12 @@ import ( "golang.org/x/sys/unix" ) +const ( + // BundleConfigFile is the name of the OCI container bundle config file. + // The content is the JSON encoded specs.Spec. + BundleConfigFile = "config.json" +) + // Required runtime executables loaded from Runtime.LibexecDir var ( // ExecStart starts the liblxc monitor process, similar to lxc-start From 1457f26b491de05e92ff14f42e992c1bd2b91f8d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 10 Apr 2021 00:33:08 +0200 Subject: [PATCH 298/373] Wrap spec.State and add lxc.State and runtime directory. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 2 +- container.go | 39 +++++++++++++++++++++++++++------------ runtime.go | 4 ++-- runtime_test.go | 10 +++++----- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 9a70ba70..adbd60ad 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -367,7 +367,7 @@ func doState(unused *cli.Context) error { if err != nil { return err } - j, err := json.Marshal(state) + j, err := json.Marshal(state.SpecState) if err != nil { return fmt.Errorf("failed to marshal json: %w", err) } diff --git a/container.go b/container.go index ad5d8e8e..8e7de7be 100644 --- a/container.go +++ b/container.go @@ -176,31 +176,46 @@ func (c *Container) wait(ctx context.Context, state lxc.State) bool { } } -// State returns the OCI specs.State value for the containers process. +// State wraps specs.State and adds runtime specific state. +type State struct { + ContainerState string + RuntimePath string + SpecState specs.State +} + +// State returns the runtime state of the containers process. // The State.Pid value is the PID of the liblxc // container monitor process (lxcri-start). -func (c *Container) State() (*specs.State, error) { +func (c *Container) State() (*State, error) { status, err := c.ContainerState() if err != nil { return nil, errorf("failed go get container status: %w", err) } - state := &specs.State{ - Version: specs.Version, - ID: c.ContainerID, - Bundle: c.BundlePath, - Pid: c.Pid, - Annotations: c.Spec.Annotations, - Status: status, + state := &State{ + ContainerState: c.LinuxContainer.State().String(), + RuntimePath: c.RuntimePath(), + SpecState: specs.State{ + Version: c.Spec.Version, + ID: c.ContainerID, + Bundle: c.RuntimePath(), + Pid: c.Pid, + Annotations: c.Spec.Annotations, + Status: status, + }, } + return state, nil } // ContainerState returns the current state of the container process, // as defined by the OCI runtime spec. func (c *Container) ContainerState() (specs.ContainerState, error) { - state := c.LinuxContainer.State() - switch state { + return c.state(c.LinuxContainer.State()) +} + +func (c *Container) state(s lxc.State) (specs.ContainerState, error) { + switch s { case lxc.STOPPED: return specs.StateStopped, nil case lxc.STARTING: @@ -208,7 +223,7 @@ func (c *Container) ContainerState() (specs.ContainerState, error) { case lxc.RUNNING, lxc.STOPPING, lxc.ABORTING, lxc.FREEZING, lxc.FROZEN, lxc.THAWED: return c.getContainerInitState() default: - return specs.StateStopped, fmt.Errorf("unsupported lxc container state %q", state) + return specs.StateStopped, fmt.Errorf("unsupported lxc container state %q", s) } } diff --git a/runtime.go b/runtime.go index 108acada..eb2f35d9 100644 --- a/runtime.go +++ b/runtime.go @@ -129,8 +129,8 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { if err != nil { return errorf("failed to get container state: %w", err) } - if state.Status != specs.StateCreated { - return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state.Status) + if state.SpecState.Status != specs.StateCreated { + return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state.SpecState.Status) } return c.start(ctx) diff --git a/runtime_test.go b/runtime_test.go index abe8ca12..3b0180eb 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -194,14 +194,14 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { state, err := c.State() require.NoError(t, err) - require.Equal(t, specs.StateCreated, state.Status) + require.Equal(t, specs.StateCreated, state.SpecState.Status) err = rt.Start(ctx, c) require.NoError(t, err) state, err = c.State() require.NoError(t, err) - require.Equal(t, specs.StateRunning, state.Status) + require.Equal(t, specs.StateRunning, state.SpecState.Status) // Must wait otherwise init process signal handlers may not // yet be established and then sending SIGHUP will kill the container @@ -211,7 +211,7 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { state, err = c.State() require.NoError(t, err) - require.Equal(t, specs.StateRunning, state.Status) + require.Equal(t, specs.StateRunning, state.SpecState.Status) time.Sleep(time.Millisecond * 500) @@ -224,14 +224,14 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { state, err = c.State() require.NoError(t, err) - require.Equal(t, specs.StateStopped, state.Status) + require.Equal(t, specs.StateStopped, state.SpecState.Status) err = rt.Delete(ctx, c.ContainerID, false) require.NoError(t, err) state, err = c.State() require.NoError(t, err) - require.Equal(t, specs.StateStopped, state.Status) + require.Equal(t, specs.StateStopped, state.SpecState.Status) t.Log("done") From 53db7267a9e099fc057020e8e03edad0fe98a223 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 10 Apr 2021 00:33:38 +0200 Subject: [PATCH 299/373] cli: Add inspect command. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index adbd60ad..3a651ac9 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -7,10 +7,12 @@ import ( "fmt" "os" "path/filepath" + "text/template" "time" "github.com/drachenfels-de/lxcri" "github.com/drachenfels-de/lxcri/log" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) @@ -83,6 +85,7 @@ func main() { &killCmd, &deleteCmd, &execCmd, + &inspectCmd, // TODO extend urfave/cli to render a default environment file. } @@ -533,3 +536,73 @@ func doExec(ctxcli *cli.Context) error { } return nil } + +var inspectCmd = cli.Command{ + Name: "inspect", + Usage: "returns inspect of a container", + Action: doInspect, + ArgsUsage: `containerID [containerID...] + + [containerID...] list of IDs for container to inspect +`, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "template", + Usage: "Use this go template to to format output.", + }, + }, +} + +func doInspect(ctxcli *cli.Context) (err error) { + var t *template.Template + tmpl := ctxcli.String("template") + if tmpl != "" { + t, err = template.New("inspect").Parse(tmpl) + if err != nil { + return err + } + } + + for _, id := range ctxcli.Args().Slice() { + if err := inspectContainer(id, t); err != nil { + return err + } + } + return nil +} + +func inspectContainer(id string, t *template.Template) error { + c, err := clxc.Load(id) + if err != nil { + return fmt.Errorf("failed to load container: %w", err) + } + state, err := c.State() + if err != nil { + return fmt.Errorf("failed ot get container state: %w", err) + } + + info := struct { + Spec *specs.Spec + Container *lxcri.Container + State *lxcri.State + }{ + Spec: c.Spec, + Container: c, + State: state, + } + + if t != nil { + return t.Execute(os.Stdout, info) + } + + // avoid duplicate output + c.Spec = nil + state.SpecState.Annotations = nil + + j, err := json.MarshalIndent(info, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal json: %w", err) + } + _, err = fmt.Fprint(os.Stdout, string(j)) + return err +} From 2f77336d8f4db09ca849677fd5845a6553e1d74a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 10 Apr 2021 00:34:53 +0200 Subject: [PATCH 300/373] Add annotation org.linuxcontainers.lxc.ConfigFile Signed-off-by: Ruben Jenster --- create.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/create.go b/create.go index c2bbe891..061f5823 100644 --- a/create.go +++ b/create.go @@ -25,6 +25,11 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container c := &Container{ContainerConfig: cfg} c.runtimeDir = filepath.Join(rt.Root, c.ContainerID) + if cfg.Spec.Annotations == nil { + cfg.Spec.Annotations = make(map[string]string) + } + cfg.Spec.Annotations["org.linuxcontainers.lxc.ConfigFile"] = c.RuntimePath("config") + if err := c.create(); err != nil { return c, errorf("failed to create container: %w", err) } From e214d91195057b85d59e47d4469c94ce609f14f6 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 10 Apr 2021 22:01:02 +0200 Subject: [PATCH 301/373] Remove unused cgroup utils. Signed-off-by: Ruben Jenster --- utils/.gitignore | 1 - utils/cgfix | Bin 2248913 -> 0 bytes utils/cgfix.go | 64 ----------------------------------------------- utils/cglist.sh | 7 ------ 4 files changed, 72 deletions(-) delete mode 100644 utils/.gitignore delete mode 100755 utils/cgfix delete mode 100644 utils/cgfix.go delete mode 100755 utils/cglist.sh diff --git a/utils/.gitignore b/utils/.gitignore deleted file mode 100644 index 93f86994..00000000 --- a/utils/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cgfix diff --git a/utils/cgfix b/utils/cgfix deleted file mode 100755 index 9ce4abb80cbd33e6723719f66cac6709fcabc0c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2248913 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

d?=I1Dbig$} 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

286eJ*|jzXCq; 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μ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%0A#bz{>1Z8+TB8dXc5Ja=b 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 z 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%0DK!b`dHmc+ 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

-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 z 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∨l;@h+_bj%%j7raL0_#d-kIKrX+(W4>75twqjm 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�CucAFKL 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Ðn59Z7s?DrMszP#2s=j2@nktLp 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≻Q3deHhhnA6=MJ?(|8zTfXWO8 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

r85yrF2jQ^{r?8uH zpHlrt@)}f%V*BvABxM6$sr;ek|B`JOKomQM zMSe;|G9U&%DSnz|i8k1PxHcy6M#zh@WfWC}q-`9>ds0O51Qsx7OMQ_=eGQ$q-dALZ$ZM+Cz*rN$M^IrgUp`3JxX^q43=v`tHq zaOEO}3&OKLz$Z37f8XA10P`H<_oPVZKOW}7N7)Hsp#R;TX+y*8in_CJayY7#|hw%kUg9^GSXo1{!JidZ@M37!G10)Rka_}t82qjL7*M$%Vv zRxsxsg&{JA?w^YWiR0)$3e@45c~tQS5v@1X^4W6ZBL7+Du4_)$4I<4RZV&8Ew9HTL z^;NUmx~XMuRp_lpV85xqyvNV>4^nBZK+P_&vo_GfY{H=dE+|R1Cc_2D1B45Z*pf<> zmc7@97I7DqOMU_M!W_8@+kaA9zsX6YHuF2qO#HbH*|&5!>>d>#b|y0Dg>|wEt&NoO zoq8Q>C;(Xp_r)z2^b2_(FY~Vf>{OjS8#o&Hm5J7ar3RIl`w1uYTOkFMd<259a1ALA z2h})$S+X|g!>BdCKy0`MbnqcJF|!SeMAO1!f;I1A0Vxp;xKC=7#*o~$y{%HhAy9(42p$|{Kzj}(8HZ7@1_2E>c6`M zwuHme=PNDV$tnzJM={4^aKW5nQ%l%dK6lnx6nJrtVyAbauY=^HAHk3!`HOt9a+u+k z>wM?Mvk`O%)+~KwO|d!kFuMt^{XLA1%5AeQnP17(Haoq$3(&QsP4isrQ}@13VHtW?owcz! zxv^y3Z}}Z)G$^PZhSn=6sLpTH=}vvI2*|{C-TS5kKpynaA*VDdX<6}0?X{zu(|%t7 zr^dfFRpx7`^0;YUriq^v-h}rMDzk+Fq=+`YUPiA$`_}~)Oq!hs8ZtYD^DpOM0nMs` zVm%kYZ4iq7=Ut`upKyp$^xp~s5Kio)?MM2+;2cp|-&__E8DvQIizNvNB{KLKmmr|W zVC!i+;Xu!gXIe0lEL=?O%V7VP1w<$~6?$kynzXt($voc2i?oS$`@cHqm=tE%KL&{# zSvpM$OhiqKV!yWK+{f^qsQNUu^p1yXSiQ8GI_F=uxGXfq^Af?Fdy7*M2yBlW$&e-2mxUb4?> zG=<)1Fc#G9obTL%)qw%BN5K$scrqFpHg%)ePDOyF_@ASnwDA$ZTk?z2b0SATkX7nW z8n}ER!U44mepo{{HxoF^8gHd;>yiKY&bO+v>kS6UsIDxtd_pRwdIT(r-@Ts46n0X* zTB}9T^)~xub1|Kzu?k8XU@$-h_s#+8pRFuh`#^x6^^U@~_>BJs!)r$6?S`CsvgAfCaW)!sbo+iAs0T1c#y)rF3M0yUWJnm6Qu{?tg(zN@16MlUtEg!1@+x{)Py=jT*qjinun>dKn znPbEMS?fumX=1lP0aT-x1{A6+I!Cn#;@V|(L~Lq$_rqw@nO#Y*Dql2ip{ zRd)&+LW~#_jegcOfFFwaK)jayXVh(0=y4HGQ-48MpE*%WN5uIcb5OoXEqN>&+P&Ku z%MD3-Bu4TF$UkMBTYcCHB{0v8c;tE32Rr>#F5xs|>O4cxV5riKX#DD_(p7KG zZq&S2;!;0Cs#;Z{TLoPg+eMdCTVh;_#mmX7tP5uxi?36nst;~pAXVMm0N%xnuJheN z!1rfxXrsae&_PE|0S3nOs-Z@rio|K%mp+*gARzF_$p5QEVwraz!~yp}`XR7~gM%m) z<-~dcAWQDU!_A=cikn5t7{@wyG5|DFrQUWpf-occ{DE@GIpe^6Q0!m zM-*e22D+EW7A~$Z>u??;IXI7WI)ZRTBNpb?^M!nK+YlDJ=_q)pn!%do&Gv(FWw&52 zaSTRwJcby-q1g)rOaP33QUjr#`4A_uycd_k>J+2NP1zZnug&DnOddUFX1f35F#kCs zI=-!ET8^;6KFku*&*Fle^=(+Am0B9#mR0Gi1@HDcfV5+))V)DTlT<)n$>F=J$SuUp z4zE|J`I@bHbG#+0B$=mBOD? z2!U&j05NP6!NZ}+$IiUo&S>lfnM$y1+Ql{7Nc4g-G(jRSzq&Wh$aAQ{R{#EsVL^M; z^E9AV_0)J>%k6>-Q#XNlr8O(Q)DV+&9TyrUGAflt7-SE5z^kdfiD~GXmZP#`Mp<%N z1*iw<(#!<2$H@MKkY{{T9Qsn27WWUv+fX@YxEX!gRcPm<&pjWHW}-y?r%=Fv011hg z@xj{b0%Nkl`(!3{mP1s04FqUcHfC~#O*PU3tjJEYQ{1!jW_4%5+Ig!IHKEE2VoX5+ zB+HW*;g^;O>kJlMP@PYLRnytbyaONpF$%pV2Bd*%;*F*`$*$Cc8!P=|F_9rZ63eQD z1!A&)>!Gtud=*}%~9nmS?$EhhSsD- z%7!lnH9jDT^(|n!7>jbmK#on9)CRwqCG}sK%=*(}XZl_~-d%xbb53o(q6?!*m){65 z8Om9*cv7Us!q~WJ1_a>*r5CXL`mv-I$E*3w$-IszWbAZ)Wm+#ZHFbTMdU=nn`jY%D zcc@}|2{L#AKRHuzEv#*lqbe91K~93=eWt3PV|FJK#Ajw<+U+HmG}xEeNAt$p1rb!g zE-1s|PEF)sAQn|O)Q~MTWpcknhk-XVbvSpC7fbrA6$~U`Y+2He)5c!C@?#MxtMJ!9 z@MqI7RdJdY>}dGFK?jZAONQp(8*&&4p)9=aG5&o_2wpxq;BjX1s|pR{8cJHmP5_sR zpYSv6ED?{vRUhGjIZIc?{H~Xsp02-1k20Z%D-G88xgWSrcNEAWkv%FbGExQg&jx;~ zS%l*f@$ay1FyWpEWgkPGm1l;M_v>NthwQ=7*Z{h2lWV01U}EKae9y#_P9+|6LDb1e0z)^EEbSF`qJ+`b zuUS5U-TE0uRhBre;Jy8E;`SgzxXoy|l&QrrI47h>F3%2KCm#i_-)z zk7VJ%0sP+gb;vQfKt@cN+&lyFIWKU)PSW)&Jw&@FGiU-S!Px8YE6VQCA@242m;S*v zfrGU7EK&l@@j!^9?Vy%7S|oI=GYCz_NF6X2tN~k2mpcbckcYdAGS&f8 zT;xhTas}lybBgD?1nC0~uMA*g4w2mdL8?w%3?a?xLPHEX8&s{2rqD+;0av(23uF@Q z<-bMdo_=fpprFTWk+YPfD)Qc&6xHCxlIh6?{jO-C_!>-fc^P6?WVv;?=8yX7;U1s9JDG@I8U1w&i}2m@ zW>V_S^-R+kP>|!r1^v!I5mtvn6cYQaWrof6`gf-5%hTKfb%r0W&BVex)lSrU4HG;c zVZ5!h4Rk{3;RUvKXJ&{KA>&})BulH-ytl;4CSF|NG0S_LIw+O)WNx`l=8x*y;Gm6A1VC!F z8u$vWv9(Lf&KU+`@@%h5yY1X4n?uGSR4j%>{6~!oxYR14xE38kRnX>2%(Puj&Hitp z_%(m2>>7o1{fLs}2J^5QE*6#>#fm|~t5tZ3_27VNse$u8Q(I~s4Yl&B$z8aN;`0@b zZzU9Lky0f zcACq1jJ2-Uq3Z;9cH8jFCG=ke{HKpJ(~Lc@Ghsph93X!~o>&N!2`GwPwum0Ux;(o- zt=+S_Tl=lp^NWB538G%OdK8jDvp~D)05eZE3c!!WCTAir>&Uqb@*5B;8UPoaH%$+6j$|J zhvCz@V9Y0yZo2XzQk6NB3Y85lAz$7@LgA!KPk~=g+M&&=U&k&E9jpBO_rfiL+$Dq| za6x=>)l~qq&=A43LyZ0POoL;YZb`ge_59Za$=Su9lMz9Bd@&N>Kfm)9P|EShms0ms zvaHS!{A zw^zc-Z^lx@!HxGPYCgl*Nt7+0xgfn)o{w{hUT=Kt>#$A{lj-Nh&W%6wv8S9Iuu=aeOR-8Cmh2%P2wbP3PTn;?$g;;MdgF9f{8~FU+?%_n!n+&2C#%pn7I*hV(R5Wjp3nVoY9O; zNk=@E89W(+5U2n+^85J>CjYo1t_jtV&Ml>d`DqZV@RgG*Zyx?#- z`}O7tQj$sg45B(6_#fNZ@OFofV;KIO=a=%Oh|*qX5YP^SchT! zPDKkSEOS&UX9G_ieW$aV0j}0)xT>h$eb2T+F^&iLc`LN>>gUpf;(&#zG$%6|QSG>F z&c8I;C1w~_gjT2!Dn=q~Q$uXxq7~pdQCX5&4po(NsWIF{!;YMVX+JCA=Qt&{zo;TZla$!eY zG7-Y*b99wdcQVO?SbzfX^MYa%DG-O8a7mAYzi96nX~ZeN;Tomh^C&g!Lm*P+m$Pf* zr_AgRz|Fe}I^#cWN7JQtcv)Vvb3v5~i0H2`axzPG$gxai)ha8ab zWu9sDE8P$TVAvz-ng9^xprRHXWMQzz{?ImmVHG;dk6m#RDIldQA`W~O7Hx50RzsMe zbxy1IN~Zgz;h3tLfLbxtDI2LX0$m6NY%@roGZfU?RS@9oZQSKI-ryXa`${$QAO^q> zL&3?ph(jO5rd*~vuc+tl;?L4f(;vKvGOMC4bAz}B=c1=P@M^11`a}}oK3wyxqh1~B zj;g3kkSw^7c}ZMbC^}){@~DmbX25um56kHXoD61-Ygvg`kLs8!O8D~jW5hNmbr&Gm z{U!9U9w6VqNnMmang9r>VAnn|73GPi({5B4yi&%i0pEz$xmpbSVLT>qQPoWjw+=4x zW$aq;%_jhvrJgC4`YZ?hT5*4tvHbHIjd zv_2@5^dDOhlf@ir=oAK^A3!;z&Q4p4ddJJxKk;GuMP+xfiN z2{vKY<;T9R)k<5s8AA@$nj9-)w*O`ouSILZ^NX>8GQW9)=D zY=xuoL0eeGK}cLagrxR6GR2bJ*{s&&f~!L8$@7z3#`(s@VGHU2LM|h}2Rwp*N;0_I z!q0cPIp+fd*ItBkE^$36msHds*&5g>O1poIKEMH0{$Uv1jqc}{ta7T&&PM{xf zpUY4bb%bsZ>XV8Bo&0eqUXfh0B{i@z3*(N~t7n3-RX_uttZi-nU?i|sV@G1jp{>(G ztOKn1hA+w4paY(agW6Yqg8yi)Zx_SR9)n8bdrN>2)JYD4!g2b*sh)?(;Fl_h_!-pc zpRq|=7x7^zI0!3MiV}}6E=@#1#6{xWO#7u;Y6$;Rnq$}}D&-K8SNl$CQuc%mtFPqt z4Xkuvqkt(&2hvIx**c``fedc`f!xHSCO$!!)ytzMpWOK!dwu`soe0O=KAFkc1u=)# zG4_+yf)HO9I5xzf8zKaGfxj{@&qIRKURY*N)VO+(!FaAGhK&QWS5GsmZxkUba3hPBBjCV1D zbBc6s7?bpuD&XuHVciM=)+y*?;;hLPV0aL20T*zPOR_u;fbU|qkgXmVWCVavS{D(+ zcU4B28(kR>4PM)-TO)pWz@cecFV^KWBKpIj8KWhe&~BtO9}p(js`2Ll-{EY_JrsOb z0t#d}7@h?f4xWfhVb&XjiZ>iu;H1s`VfkN|E;p038Rr}S_zE9|f`LJYxMACBB!!q1HjHMtrO;Iht*QGdQF*m2~K7Btz$a3y3@>~IrH?8h^=V1YsL48uCSig-e;cVWCVOj*g0h z#Q`fhp;C*o%5Bf0%pgMc3)0#krLrM2#N@W+wN?+m<=~(mT2N@0HXF+4!GQz>z6*T{ znyuhkZFm46#DjVcpu_gaFTA(2+N*xFK1E)-8nQW}!}JsV zVDb#*od{4*MTzI4bQ4l1Tp>^4&Aq!Wjk zj!}}LRDlua>k0LlKp%6cki@Hv{}@11okI&QRcUOme2B0Dra)#%)w+kQPux0P$9y8) z9fyQR@at-Nz(Ry6UU0Qjt! z!)^;%#s_9pVYvb;Udl=M6)^M8){jD@L*bqbt&7ncIz&w;>Rq8UgYHGw#PA2x747NF zA04t+ehTe5t$3j#-|DjIyuA!*Nms8l=B4HGYLjClx0wZ3pkOqFh1!y+-C z?45-<-zf`k)bZ@nh7_MGa-p*!{mrMdz&~$TY_T3qk}3%ZgUHL#aTD(Iy~`<{{(A5?4#WFWL@j*Nd{^pi%4O zRtX^(1L}*UaP@o~*-m4mZqd7wIJ`FM7eI5x2eZwx56lvvQeQmDc<7VNLXhD=q((ib zFJqkJhA$urbzW~GF1-lR;(~s}H$AJwZ=76|JnN6aOK8XVF>#&)YxxM!@8d%xSqRjr&R}#+UFjC zsYEZt&B6)BV_x?4r|;JJ8vD6^U2dfYOJh7v-+-^ImY_rGmLlWpB=wTa7pNN9gl^d-71hwjnSR#Sp7dfEwOU z<`oOgh9kmdFIZ!>PBmv9G$tgV#vPcvcP=g}Ee2^$hT}ogYC*uiS@VfFmZpal$L8); zJsIhA4q7lCIT95rYRL&l!vmTJPQeKZZ7qZ!H)=aNfAui`PM)~&iPqU!5m*Y-fuPOp z13LznAgd7zI@}E3Hh357&wL!nk$At&JCU9SeSaRrm<=$1*lZGWO@@y+MkvG$n>K6N z5s|qQRV~5uk%7jc?MtVTTa)2};Ky6!ix->UvV|BE&Kt=f7DLZwF7Kq|%N{FaC2BWd zQG-_7&HkOp*Dc6tAfP8|n^y7+ZWVqtmC?cRLPNKVM9EeAF&K*52@KvTnu-uXrZA3K z+7v=s{7M>lHShSM5wqdSilLo;@_H(C1D$jM1lyz0k=Gw9P&HgCu?50DPqZpnLKz>xjpgqHBf#(y9-?bd5{EIe&wWpa6Y?5 zSRI;5$zQ#`)Wp2$tDHlXU$?SLXQ5Nmyvd>h*@oit*OBiwX9LEm7=@l(MS?JuM#QcJ1Wo8B9nK3lW% zJW1c_T*BQoUJxU>a^=4{+VvOYTi3_X#b=ShVkSF9Fh7ZLlYe<%(+lzea+S*qd!LOz zz%c%{j+s{iS9kkH__P zhI)E@EY#Uum{zt?YsU}SpHx&`cCln4TF4$kI(cfAxl+fz3M-alQ#B92qYcC38%hN} zGfRh zEj0cCSx2l$ARuKTXJ}6fJjeyA8g9*3oMR{$4UA6!=FA=OYzaMJY)VcVy6do`zczR# zWS=4ABmul)Y6$hiuImoVK?Ayv*1Jp{>95$iLSBB~10&P*cU_7}+LvDlZD-TrKNz${3 z?D*}agXIufG$R8>?-hfoF{;ba~dku7V(ZtxTGb}8kFxZ`h)#+N+?U1BtWI}swrztVbh%?x90w}T9 z3jGiWvbnoZ_eQ-g97mSVDo8*n8wh=GZ-)w12z5$^ih1w3xk{$@o-l8&Q=6EXLb zNw)-g62+^T!JnQlLi&$oG||2>gYqPeKNi1#N^&imEYypA9-DVA`JHGS5XN|r6gUrs z#R!dafk25j^ zTul``w+g4DUB5nP9w^YOUtKoxYjAQFopTE zX4e76-^|0V(=2k3iMS`wEYP)(J_A~>#Q<>;xZt0b24QKxb9O<4D-Bp@VF#p2a{}aT zF-?5v!X_j&WRHW=WoRAcvgn7>L^vsUXPZxWQV+2!YCppljIZ=UzqCq$MB@JFA5fU= zNa%NSD#Bg!e)Y?)!6R1zoz@-l$I>hk__hnXLTnnuR~n6Be$8Zy=}{=#pxHCc1`oYU zCg9Ql(&He|G^(CwqDJI|_K6HdT!9i`v6u;J`=JTyBMBsw{u0x)!i^FQ9q(?>e6m0T zp9p1!^_i>?XYO+YUT<4>UGPhgdd<(#HuYJeRMGPy)6Xye5P1b^WEC1|1`=Llz@rgF3C|829+XQm z)iaN>$EnS@IiRXWNDI$yPev8Y5vI*4v1y)dZ4e_iMD|5Dr6NY0Te0EV_fT$?#{Mt3 zQThOq0^}k}vWRX$Bx(&}mgtamXgJ`HwPP}Xi|%Q*L;d$#H{g|6Hl&rP_|_HpmKa); zo*K~~pBe>^otFGrY^hEeSgJvK*etFfD8wPM!39Jy@oGRu7DKKe{M~%u*m*`2=iwLB z3TOf^A^aVIKeVP@!r=NYIP_s(@hG7vm{9Yr6l2&NH8#Te6ik43dVwGWKOLJbVc_@_ zWG5SDFq|#FCtXvLHgATbB>kI2W&qy!O0vUJBzcQ35x*X;?Ll_pQ>Jvl!ur%pv;lH{ z2w>N+t_0VkR>@^foBr*oaoXmaLiA(%Yx>ey%BUO|==_0!u5&Y=H2Kl^LL|$9s8sT& zbm#ijT*5o`HX$iR^5S$`RLd5t7?EIOYq!=_*=uA<*?qW!fEsE4k_ckD^iE=D1ofxt zEH-U(af?3UuTj!u!D4;H8i#+Demr zL`JXrBD)m~!v|S)sAjfo0)ml38#nv<1Xctk-#XaL&7|Neox9{o!tF_gQL-GAZOB3{ zP{y>=yCfG$5nNj9}8$Mct@&$pta=a|CaX#s!e1K>P<5_Q!yGL)^B)c!kT?IXwu5% zeA0CG+I@s=@lIgyZtUlz>c*R6s@7Ov=&vG7wJ&SPHvLL-Nl>v z)!|nz95K89#%X+|Gg})lbDx~42a!p=e9ZZ6Z6_QQXDj##X96j1V6D!i0l#G5e&tJtY4$twF!Up6xyF&DuW(b(d<&t|ccH{U?aP#ZvU{)^j z=FESvYDVN9<{|K#<`)5--dMZg)JP3frZkF}4OsxZqYlEV269#)#6GXeHC+!c z5tL5cE$ASUq^K2zG%K5HKqrs{vZR}K^+dq*iSd0rddQ^qYoCBau$2h7Z1z+y_TZ%s zVP%XoqvnNGvDhuj<3L4mNE2#L)J$*CIss+d`Db$p1D%_{o-8Ln_dao5 z*1TGl;T#g5kZIks8FEJi?$>lO;Q$eHClPS!KwAh8Jb{f*jL&_3kpC7IPRbfELnq+c$?J)gY3Tim+g`aQHsj%-cw=gl}3=0GR1 z7N3P6*V?RWYU)>F>w~QxEpC7$(=D(iVLSEg+RxN9-;||_Vna}48b=$eDNuCWAQvZq zfQEe)(N_(R2C$ToWn+Q)5`#PC%6qH-ocHqK8c1cuCI)2XKil{zPH%8;8@i*`D{kwnW-aF@> zbN1eAud^1UuUV@G{KImVW>7v}3xBNmwHA0A{VvDp3jbg{S_}11o3#R|=#hGrTSW{} z;F*I)d5LjQSYc8pQ~76+E^%WB2Mo8e!T~laxsg$BCzbY#(cICsV|jJ1^~FbXc4`@z3V*UumEsSLemnVL)y4Nes5eXs>sJXBDJTO@o_)o$_P6i zv2_CvEud^TZ~lc%N4c#}#Q)eXegRb#w1q9J`_C)dd|elLZ?8hK4M%e5WQJ;eowqg|Q@ zyRxB}Ut#4sJ8*r<9U&gdDWM>=P>;{D=2MDL4_k$TD5VV{dtsWC;lyP_C7F&BJRzMK zIprSZJtt25$1NSG217P&S@R=hNDP`;Iq8IL&%s1n@6Goc(gG}uhcckLlzZuTtD*J6 z*Fn%SD6d^5k!pyvN`_2cys%^4Z30di7$DzhOiKZdvkR-SQwNgB4{N-^ zl6$l({~mr_Qvc8~+pb>D#*z@+Nl#F7aK%do>>I{BMZ;0PE+ODEM6rF?nuNX6?a)hz zw!I=eLJZoUfiT#F8Ga^H?ve^lEvx7AK}uXIx&!iu0|a0lsmtS60Gtze)P7mBk50PpWd}ci@NtK4AR)m)&5}8 zaDXUoESV)u7Bu7>sN&SgO++M8fLB9eCG!KE3qs-kpt!ZWST!tpF)UO2@($Ryk$Ks6 zE9j}@``P|Y=0<~ESxOXA&PpYC#P0&sBXe}(uyePTLH`M%TaP2Hi@9gO0!K7~;-_50 zdq02oG#*g*PyJEbSQWf%w(HRb-{+~N?q}&FkF*0wTs+H>=b#jW98wsX&*j$h* zMRt?W`nAyS*zP3x%O&0k$wH@G#~i}T5hp?P4sqWw2h6ZPkjm1DZpTTEPMkqnBZR#S z!i3amTSAIh8ix9|)vxS%O5--2*FiYchOSX5DVR9@c6P;Z1I=;X6@9(QEoqWf6-Rc1O`Qc z4T3YF=Lp#A()3*jxsCb3#9FOM(OKlAllEm{1zs`j!!AC^xi8;`|bc z)n3bW^DF&?mu3+(r8YTsA*E<*RHr&qV}SrRxwz)*sfOGW|C(^-Mwx$BxUYVBc(aj- z2KHP|RUt^;U@~Ge zD`xERx@^w4ylyD*FRjSlIFn+LBMS}>{-*gXk>fwna)7aaQ{QmX#{B~}y89d{=KKuy z25Th-C_~3>n4dbN8Hfp-mK{(Zb+o#WNCPRHcbLl?eZc41mCWg~scuOs=jJj}UV~}J zggvi|E)youSH$L}Sz446`O(!|Zs0$o{x>Utc_ihQS zC@LR`{%ktvX}-j~+h6aXdd-puEwKRycQrL|VltB(fFUH61Q1!8dpeScdchPLyQWpx zyWT%sv)qIzdLs(t?V9B(+Xw6V(`dFJFR=o~be>;}{Zh;iE? z77~xXWe@xYED>J^niBFm!ro;#PsU4 zTMX>^{*G5C?(eC;yqh?JuB(qSq0x#kqquRPZ@T)Ph+I_1o(YSKG6f2^2zCqhQ<8^* zEjlj|$VDOEol~g*8W;l0!T`jSKTzi+!B;2xW{uK-Ayb@2zeQwNnilw==0*$~_ z5#+RM*$`ZjOksM z25c44kndEw(X!}3@*hgRj`J^AYodvR>u9ue_t|x~^}ndDV7Nnt@43VMA!qnLVS(WY zt&I4$4@q9UGmOBOG%ftq9f*#BwiwJAtn$W1C`!PhN~qu`vl`fs$1&|-0QbCVv0sY>N+0_>jbC1+Ph(Axrhq1m8@p+JtGjr z8_d*gI!QDS1q!Nu3`?p_!f#P1fG#$7oIqpPh}G*a`Vt{A|9_hsx;VjMGJN&}kchum z0x6tOVf@-i6%Cpxnk>(T@ta9baKVXH8eH4a2g40^8h-7+DA34CRr-DQ0U6|4FtPg< zdbGzTlwv*E$WM?jmH!f6>niHOr)wE_+4LuRLXlxX+U)akP<}%q**lGE2biYf!)Hb4 z^kANsn;m}SRFdwB%2cMp=yGk;^)>HoE-n9>GHa%A)HrV0_oGbveVb%ZB(nr!5#WtH zbW5gWHWwmge)HNwJaE}x7^SM|fA_?t2>KPy8vu*A)W;*4Qu~tB2>C~sSiG6h@T1D$ zhP~~ZS1h@tvc{~xyrd-#`+1#$&g} zQ>&*>50NE_B`RugQ&MLf?$?2-Y!IOe3>0DK_EM;|R?jp7Iq5N~bkv0KFohm6!Y|ut zAY~RJ)K^x?EC2?E$+IXKRtVs?3B$N2bwV=km}C$edT`@F_tR%h_jl{_hpU}z*zEgR z9uKESp+tUXUx$ z{kR*VHk!&)@$i$^Hv@QDhnjCoJyizj*DyXoPA5A z_;L)aYI?2JF#GNu=1KTb>e1vLh#k)x$MklRp}SR^ROVBK|N5d<%gQ)&p&DwzD;qY3zna*CDr0cK`lgm=)j#Kq}x&*NPLpE z_gfs;7Z0g$3HJ%#FC5cc+CmD6yy6@J0s1eO>g&TQUa4x@v?wDEuim2W*WHC}k_Oz| zm<`zKaajCfuiil=UP2(Ed;1CYz{nSXwH-gVLhJSKeFG`qHR$)!;;E-%L|8@n{Mt+} z`X8>L6yP72^NPw3tYwiAPQN`-KH!BjHJ>%{OTTi5GXc39%R9yOT0vHSg*2D$Van2V zQA*aY{hg(tSYb~MAzzM`t!K6D8^y?{r+Y6#+~6fD2ZmUp(iJkX8SECDxyTnGY~u7_ zu(&-6^66D63(CLEbq>8Y3u*o9)lq~pHrnwh8lb+NMCTrf?4Jq58fYxipq1ea5Aioa zrD_lg8kGSS?^phOrC=KXPmq)v3oA4=doeeMZHTc>-um#6L74oJR){Z%CFvvUy_*Na z%s?Z$fnL2LHgT9q`$s$S$$&Qrw>qGmA5s&7C>1JVLx5`Og}sH>qYYOp4R`f(mqK!* zTeSJ;2tVA-W;ve994AV{mxk6}sTGwdigyT4n;3KRO4CR>V1_WKU1Y8q+w7+4-w|BI zr`Y>qJiVKr$Cq_SXQ6$jf*FlTQA*Deyt7HA&{+_&tx!PD9DHCxW)fa35}-@<;8Ul_ z^zK)PZ!WZAT$3b>8_^@L2%H*4g;zl9RH$F{#yt4o-ZW`^)U~cv{u5KbT<60(oss?snQFsD0!WJ$xR@XI#kX{q-dpVw_F#^( zx=HJt7PvQ8rNo3|uJNg_));Pvoy7RPcq)@7T0ncycWvyR7iV1$Dbrd4PqGl=M3y?G z_pOQ^5@I&h%e`>R!=S#o0@_Q(qs7Zz1mnfx@oR5xkLW3y2Mr@nI+Q|BfNqXA&%9dc zynK+?ec>e^?SP6m5NW1C3*h(8iF8wyrG>&+IC!KQ9KI55sKdk{@FRk8Q%2!(o4grV z3&ghLJOvBFGCg2 z6kqM2k9z;jQ?elfllVk7yi|&&sc^B>?Fd_t1v)FYP4g2G0jKWvmUWGR_3mBCk-jM& zkvh~e4XDv3uaCbd>W&#y8vNPw5aI<(Ygh)-2wfs%6-08}VN6I;nvA&J&?|06ox1c$ zzlF#s_Tho&Z#eIA==bTAOx9Y!x>lY?OfcjreOA9eLzNW?8B_o!`kt zNlJ2N?B(d+U1m%SZ<>O}D65UF^3~ zz4i=gLgC+_!HTg^T8u4HLAundzCl7DVXkAGJEc__g>@ljzi9Y!4^-L@CU{#PfIN8T zlr?xJwS!h9Ub0t)y9gmS8%M1dY=paKm|&lf-#;}(ZykSwPJZS&YB>@|BkeB%mJE$~ zlQ>6UT;qvmj#4Qg29<<*AyYc5_@SmkDlWNFGhO!n3ZFZfnzY{9+cvM0RQ^n5oAxU- z7{;dOcj2yWZ-h6VZM?r2Crqf~$h)dY;_GDN!`cieBS3ay&!Dg4$Tj~>&#6pgEXrp()x&4eqz1sjyZNrV zzGe5kp$l=?GX3^h$?CIaI7{^^29r4-_3{fTz6cHoq>4T0%YBVf3xSfxM#bObP9_pk z0-ox%@upfGjZevY*6H#93Zo|G zE^vkI@Pa+1lg$n1;+*j;2i;g=P5Dw>BY}u6%D8k`l2a1pVN2GcICGXcn}5{R0G_kl z_Lh+9u*zp%S$rS$k@RWdk{B|yWsxAFSIX9(%ckmd&VVvZoYXgvKmBb;%gO$!ajLa2 zvZd{Cif4K>1Sm^IdI`EKr?$UyETF`4;tUP!2))|bYYiS2z^xi zuy~%<{L|EQIGKaOjgKt`^OmQ@NXYl!>}KIaX>KZ8GMGYKD7Jf%$MszkP?zV)FLN13 zb^6X_3sH%%ryiBh;U=C-`9f519e;FBaw|LS+2cp#AD2wl+66RF`D!5iVONhNMphye zIX`xA506xLu1E?+B4wq#PsRjXWr$pDWvYV9`2+cOsB<)54K*uB3Qy?0R$_l^=<$WS z3lh1JV)P*z^~!@{_clPcSGXfr!>sq!Sa3rxu_@L>207DcNog6;Imw%11NW?zq1% zUQh_)9fW7rf3Q1PG@hlZnNA+4{Bdb;cBceBk}am2sEIawBMQIU6LRnWB#(I=BOe|h zTI409(*NFf5&8k2&FIe&TEUX@FaBqpyy+g^+l5=0DAI?5=J+@bZdLh{l3E`aTr4t; zbM$a~sYz{VlykyHkl60uZa;~Ou z?iPDU*I+@He%igVMo(7Z(z(dy5SDtUfjvmdIX<&4p2t zHtlzy6%_lIu^(S#g2JGM7B`+ZxLyBdR6nSiEZIms^-ZZVi$2yP^EYb-M}{^j5;9!5 zo6XKhostKA<^|l>!%x{-?Q_*R#@qwcfdfe7Lx?ZS}HVV#Ff; zQGLA6L`UI4-y!_K9YGsN&QL`gO{uCN5rGu|Yx{pB(dnUZ zik=Shg_8kl1f1Z0qD_DC&ZOupR+Uq8@lxE>^7t9CT(n)s+a) z4zRk5K{oz-!};QWtqJqwfO9xcEjaCfA$}4OP)JxqVJlKr7J?$WAz5s#`rpPk7-(X3 zDFV;$55{E7l|sSB4jCe)@faHcD0DkIbnu^^t;c4^D+DOPhskd25!-zXIyz(B$|WvC zu(#3j=*+gzR;xf4pDlXB?wT%(*FYDsE6OZAMsY@EW0_kd;lk{5MJE?K+*A{icvE`` zg?_fFnha;EJI-e=+iE_oQg10t{`pbVJV^!cpQ$so?BNs72CtU(s;usIAC2gG1Kjggoi z2G)OUgXcrjY7FQP4e`@TUZ>L81m6N?svQalS0T6^%#oTO+nW856CtQEIim5uyg3~$ z*Ww?8NG_12DW?~&Qjy}9MWK4hkL^8w(8`#_V-s?2ut0=TUzGC^l}t{8El=iHemc}f z@W3Uwo0WrVVG$GllGCjZ+k*L>ct55~(j2g*?h@m9l#2*J#Sop>+El3&GV6mU+a$Eu z2dljT4waz7$9i-<^AY+mgjR^gePQ+0cp_c2$?K>M8XTfW7)lamFyjmw>rcXzLL7vf zMbAPK87w04!iL)UHdF`Y54?+3SS`Ir^|VFOuba4!k9KB)++(F_S2j#)GhS#M%)bmo z6ig!Ljp}-2zg}Wqs ztrM++(L176{^8i)Ouhj8{|PEE_?)Fk*_6LnX;vAl+gR49ea|&gyqKDxKTac~q2;V5 z;8AB1f0wG75tH24;=9ocAEGrrr}@@(ljm;Hd*L>I2dlPCfNe7sIZ7X`NCZBV1D%UJ zg669(lX2T;8fm?#uBiAe2XP(CY5WRZ;6%<(tz^yTa1^5RUIA&?KgxB0IT`}MF(sBT z`Vz%q)4W>>x=eRs>TdvKgC2qL_2-~D)#3cksJo+ zB!d0i)9;dvp6$Y@8z+2Ps3})v(v;TADS^`W9IPAKaA{~H#6}5w*f@vT8jqM6qZc z&Uacw`)?V?d^6dfL&Q1n$mSL)ZY41{$t`CUaN&kS3GuN){>jbC@kg&V^IEIz^V{!! zW^?cq{2rx;W#5d?J%}x3ZXuO0dM-=Mxsl&0mYOFTdd%#cei_F{2lKO$u1-X2PE~L5 zs&Wg*WM<^10UTR~NoH}(0`!1?*mBsu3Dg~0183qeQ4N8|kR!AhyrHAu!k>?sr5A2a zrELL^X}d)Zr=>8`%u&ll_;q{b5L_EJFEL+g!YDJjK~A|=?{nQqBF$F7-OBSlb zqayaO#hitHG!SsXPpzPWlR>sfHpghj!ZB1Ba7Oivn&VKjRyq{6?~dK;q;zv}2(vHb z645U~2Sro0FO-7L*%Bh(M@tKSaXOlP4Wb)ydha#pG8OP=f#NKijU_?V?>xlhlO&(4 zA0My(hqYrCXCfg^DC_qzQ4ULUoG^&j&kH+=g9qKHL(BtV$Eo||@lMel98bA3i;g??m+SgC+vZrD?)tc^71?y0k-j+y&%BBctA?G`rg`;; zP*pQ^BW)lLku6Y|k*IzIvD&qti9t^Mhf%C3+TcmaOWC;f#Cxf9{QNp)qwKT&0a!sQ zjjjUJc)o_9=#d2#zS`phBFc4mHt6@V1i{OS>glkDUf#eVG~)j$A> zw=Lx)x{kaE1QtUDN{&Ol=*Y$p<+qq+oeOoZe1q)QaJl(Ra1?>HbXz!Y9gMhp9~qU_ zfq8?)+UpqqB`jmMu~Rs?NlK(P6s=c8KTaf6MSK8+0x6LDX#Z|W71oPa_5|R5U*)~J z(181G@83+EoN=vg$&FOel799k13*lIh^90ar-Tg}ouYbTVVM1P)z=dl)prqs<+}!d zWF=w0kWBzxfxvctLLy829$bQ9Zo^$O>XK^SMo;N5o(FvthF#M*3>Q=$ZejGj+a}%! zTdk8m@(8(2p0T5x{lQ@hH?x%RyF710Dq&?2HE>B)&Zx`z=qfP@*H#_;6t};99yj<7 zh5McFH_1qIP{t!a8g*$L6EbGs>3>16WF`{Kbv?A;BI1WMt8Da;p3c6w(NzfZQ9Sh# z@v~4Q!>d3JzwN(3ChX*)Bi*yU!hAeooo+uDMjxPwcQeWAZK|X{Zki3}fIjb4) z9;%&2;zX-kc&phzPnDkayWW)l~-SRm(|uD#m3eK z*bVbB&D1IX2ApL3jB6p8Ko8Cl{0s?W`DiWW6gY-LOk&2IY%fc4dEtm=Q|P&eOqcyr zNB5)+hRu+DyZh+6-TE!HPjAB!#6gG=P70PU7TRP*dWt(k?H9w{)mtG{LzaG`TN*pX&XGHFXh zhEx6y6plrZXzcaFq)y`+klJPI`BI3YU@N|rI!z8CS3g&dzd8*O1X0Z@ z9wIgw3Qam0q@c^GeAY)A|EKho{xc~$KK&wnX-bDg9b1LWeCN>hNzW$vO9$3mavO)! z&EF=;L~P6)Kkz4ac8_Ko-UY<()-_6z2P57=+K9Ownx<$z>hS~f{| zqyC^Mj?==kRZ#z~o)fVT=^_dK+%aJ{Ike;;>@Y4bRn{v@g$+?CkRhv}kc`=P-H{v(!CtTw3|sa#8VW9uShAiLmQo=b+&}60 zM?3)gDrj2l-aHeYb)!_IJHEMTV2zroJtr5G^z&C*PPk=Ebjp;bXc#~f`$C@TGm?Z- zoPaNWB%pxBlBa9PIb=Z1RhoGydtn~AG{ftCW%%W%lql`Vo~+I%YRYR5SetG@|C9`D zmoV?R5SU#|DF{Uxogqp-nbRdJKCBcakOD`8Dlj^pJ23T%I2=%R!_Y+O*P~y_%@Ix( zP5E9@I-2rRwP`dZK~+x;k+W_P5!<%V8DI0O*~mBOLkI^gFu5d}d}KeYO<#L)`^DX% zp~t`hycG}v(2O7g)P3XY{>9}+rmO^&%YmPHd_6@`tpVZKUJx4=R=}ip?W;ljFLVK- zLC{U(CXqa|x1QXz|DYx3HE1l@wNKF5=O4 zZx<68yndDV(3igKk>p;1r!B|%1B}xix~%I)HdfjREGMGSE|*4OL~PLgP~;IF*)lOW zCYm~;Z4O&AF+^L2l{?hNig^$fkDcMY>XZLtCh`x{P~A_1Ef^Xat=Gqj}qVv z1nbZyZuAhi8D)yhF!A%h2yBaflzE&d8OfW?2*nr0&&katjBI~1G*7|#>~gonGPyUA zE<^3%eW+E-^wl?DegAo-q(SB{R4JoS{gf73#2(PRq$~)==_bUK zYf=%rCJmm4Muec`uaJvA3meVuIFz)b(KZod3F1h25;w^+76vkwLm$we?rM`G|gtsU@outfDth)M97GsscAB zK2;xw;)wlo?S!GCBhYgpIxR+fNNLT-{)6zeE)1{Lv1V}UybM8(Y=qyL4Fq)geb%6_ z=RIve$t8^RS>Q8JoIc_(tprmz<8l1Nv2NivFXHJb5VAcpOa-%wq`8VCz z((y(SL0sR_WoQXDfsds1WTo;PWfe4{Am<1wS1$TpwrJt!fqGN~Ev87W>Q(a#yEszy zvqlQ+zNtbLMBB;~s7JdbigTXulbpTGR9Uu_ClI8tG>5!M-HNf-c<*#O=4R$p!BI`f zD`G^lzZw!Ig*T5~rJ7A1KAW$Bv~vYprU358?L!MDVUW!?#DHdY>>rWedUGo>!gHG_ z5MVd%Q#vhVa=w~s@g)nQrqR=&kO$FNHp{E;DU84gfEP>WZ0FEZbKBXFlO_Z73|Sal zCNG5hu}z#Ey^LAgJ{V=e4;ORyN`V|be2`X5TD7ni;N`>O;3H&PRU+ikt{O*yrAP() z7arZx9QN3qNP@^d&)H5t9*tt={nc%ws(5O&56*lW88k7bl zx;PG{9TQbw>gD&dTx3C6xE?tQgX*b90Y1yMt(if>j6Szw(mK;-9p^#CqpTKH7Stja#P-2MH)Hd2TsBp7J7thB9?744M3fGp7RJ7|>@R63!;;LIi!`C;lUw%oMud z_B$G4(jU{=)s7_ACQ-7l4~~PXo0V`T&?aaU-{A}NbkP#!Qjdf{3~jyD26ICr1@vH; z^^{IeU9*2;gc#?{@VfszKfj^TKQYppezB3E+D)7N1q|308}iM~L;wG(t1~pR)GoLh zEXI*ShF)oaWo`#SBdrT?w4@bf!MO)<9B>s*MzrL!EF$kbsyw0T@}jJS2sAmFDndBM z>2+pP18eobmFDU&oML|}g$SHow?{{s}s2VdYPLAj}#q6{% zjG_-MEcuA_t$?Eo zM8An&5c-w<3i!G61;WiPEK}De@dip7r50f9HiWs6gJo@WNTq+7X+Zw5)nwUUN*R&8 z<#2Mjf`r3g+F;+XLl;)YA)}6q$3jN5N5+;dP*++fH(AGH9;kJ);eTS-Mb^p*{``8) zecnhCt?5!!)bXl02}Wss1L?l-BN61YW08`csOHn3ZfEg~dOAwvA`mQ-5ZQeSH zXoBjp8>OR$U+H>Y

S)}|WU`J~ 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©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�$9g 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 V_L+QLOJF=}G=PB`vit2%{}0y5K%D>p diff --git a/utils/cgfix.go b/utils/cgfix.go deleted file mode 100644 index c71017ec..00000000 --- a/utils/cgfix.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "strings" -) - -func main() { - - root := "/sys/fs/cgroup/kubepods.slice" - - cgControllers, err := loadControllers(root) - if err != nil { - panic(err) - } - - subtreeControl := fmtControllers(cgControllers...) - print(subtreeControl) - - err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() && strings.HasSuffix(path, ".scope") { - return filepath.SkipDir - } - if !info.IsDir() && info.Name() == "cgroup.subtree_control" { - println(path) - if err := os.WriteFile(path, []byte(subtreeControl), 0); err != nil { - return err - } - } - return nil - }) - - if err != nil { - panic(err) - } - -} - -func fmtControllers(controllers ...string) string { - var b strings.Builder - for i, c := range controllers { - if i > 0 { - b.WriteByte(' ') - } - b.WriteByte('+') - b.WriteString(c) - } - b.WriteString("\n") - return b.String() -} - -func loadControllers(cgroupPath string) ([]string, error) { - // #nosec - data, err := os.ReadFile(filepath.Join(cgroupPath, "cgroup.controllers")) - if err != nil { - return nil, fmt.Errorf("failed to read cgroup.controllers: %s", err) - } - return strings.Split(strings.TrimSpace(string(data)), " "), nil -} diff --git a/utils/cglist.sh b/utils/cglist.sh deleted file mode 100755 index 7b65bdc7..00000000 --- a/utils/cglist.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -cd /sys/fs/cgroup/kubepods.slice - -for cg in $(find . -name cgroup.controllers); do - echo "$(dirname $cg) [$(cat $cg)]" -done From 2c7a64ed081a66baf7e7ace1459c96d991f7826e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 11 Apr 2021 15:17:09 +0200 Subject: [PATCH 302/373] Implement OCI hooks wrapper. Signed-off-by: Ruben Jenster --- Makefile | 4 +- cmd/lxcri-hook/README.md | 128 +++++++++++++++++++ cmd/lxcri-hook/hooks.go | 87 +++++++++++++ cmd/lxcri-hook/lxcri-hook.c | 245 ------------------------------------ cmd/lxcri-hook/main.go | 161 ++++++++++++++++++++++++ 5 files changed, 378 insertions(+), 247 deletions(-) create mode 100644 cmd/lxcri-hook/README.md create mode 100644 cmd/lxcri-hook/hooks.go delete mode 100644 cmd/lxcri-hook/lxcri-hook.c create mode 100644 cmd/lxcri-hook/main.go diff --git a/Makefile b/Makefile index 7cf0ff61..2e4f6d6e 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,8 @@ lxcri-init: cmd/lxcri-init/lxcri-init.c # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null -lxcri-hook: cmd/lxcri-hook/lxcri-hook.c - $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? +lxcri-hook: go.mod $(GO_SRC) Makefile + go build -o $@ ./cmd/lxcri-hook install: build mkdir -p $(PREFIX)/bin diff --git a/cmd/lxcri-hook/README.md b/cmd/lxcri-hook/README.md new file mode 100644 index 00000000..d1df1c79 --- /dev/null +++ b/cmd/lxcri-hook/README.md @@ -0,0 +1,128 @@ +# Hooks + +* see https://github.com/opencontainers/runtime-spec/blob/master/config.md + +## Notes + +The OCI hooks wrapper will work in plain lxc containers because the +OCI state (state.json, hooks.json, config.json) is not available. + +It's perfectly reasonable to run hooks directly from lxcri cli + +OCI state must be bind mounted into the container. + +## CreateRuntime + +NOTE underspecified +conditions: mount namespace have been created, mount operations performed (all ?) + +* when: before pivot_root, after namespace creation +* path: runtime namespace +* exec: runtime namespace + +* maps to: lxc.hook.pre-start ? (mounts are not created) +* lxc.hook.pre-mount ? (container's fs namespace == mount namespace ?) + +## CreateContainer + +* when: before pivot_root, after mount namespace setup +* path: runtime namespace +* exec: container namespace + +* maps to: lxc.hook.mount + +## StartContainer + +* when: before lxcri-init execs, after mounts are complete +* path: container namespace +* exec: container namespace + +* maps to: lxc.hook.start + +Run from `lxcri-init` the same way the user process is executed? + +Bind mount hook launcher into container. +Create folder with environ/cmdline files for each hook. + +## PostStart + +* when: after syncfifo is unblocked +* path: runtime namespace +* exec: runtime namespace + +* maps to: no LXC hook + +Usually this is done manually after calling `lxc-start` +Run directory after unblocking the syncfifo in Runtime.Start +Set LXC_ environment variables ? + +## PostStop + +* when: after container delete / before delete returns +* path: runtime namespace +* exec: runtime namespace + +* maps to: lxc.hook.destroy + +Run directly in Runtime.Delete + + +### Solution 1 + +Add a cli command `hooks` with the container name and the hook as argument. + +* Bad: hooks should not be accessible through the CLI because they + should only be executed within defined runtime states. + (simply hide the command from the help output ?) + +* Bad: lxcri with all libraries must be available in the container for + CreateContainer and StartContainer hooks. + +### Idea 2 + +* Update the container state in runtime commands and serialize it to the runtime directory. + +Extend / Update the state from the LXC hook environment variables. +Create a single C binary that executes the hooks from the lxc hook. + +Serialize hooks into a format that can be consumed by hooks +and started from 'liblxc' using a simple static C binary, +similar to `lxcri-init`. + +Use the same mechanism `lxcri-init` uses to exec the hook +processes. + +* Bind mount the hook directories, for hooks running in the +container namespace into the container. +e.g /.lxcri/hooks + +lxc.hook.mount = lxcri-hook create-runtime + + +e.g create + +{runtime_dir}/state.json + +{runtime_dir}/hooks/create_runtime/1/cmdline +{runtime_dir}/hooks/create_runtime/1/environ + +{runtime_dir}/hooks/create_runtime/2/cmdline +{runtime_dir}/hooks/create_runtime/2/environ + +... + +{runtime_dir}/hooks/create-container/1/cmdline +{runtime_dir}/hooks/create-container/2/environ + + + +Pass state.json to executed process. + + +c tool can iterate over contents in the hook directory +and load and execute process and cmline +for each subfolder. + +* can be implemented as go binary and as C binary .... + +* timeout: set as additional environment variable e.g OCI_HOOK_TIMEOUT diff --git a/cmd/lxcri-hook/hooks.go b/cmd/lxcri-hook/hooks.go new file mode 100644 index 00000000..50ede723 --- /dev/null +++ b/cmd/lxcri-hook/hooks.go @@ -0,0 +1,87 @@ +package main + +import ( + "errors" + "os" + "strings" +) + +type HookType string + +const ( + HookPreStart HookType = "pre-start" + HookPreMount = "pre-mount" + HookMount = "mount" + HookAutodev = "autodev" + HookStartHost = "start-host" + HookStart = "start" + HookPostStart = "post-start" // FIXME this is undefined by liblxc + HookStop = "stop" + HookPostStop = "post-stop" + HookClone = "clone" + HookDestroy = "destroy" +) + +// Env is the parsed liblxc hook environment. +type Env struct { + // CgroupAware is true if the container is cgroup namespace aware. + CgroupAware bool + // ConfigFile is the path to the container configuration file. + ConfigFile string + // Type is the hook type. + Type HookType + // Section is the hooks section type (e.g. 'lxc', 'net'). + Section string + // Version is the version of the hooks + Version string + // LogLevel is the container's log level. + LogLevel string + // ContainerName is the container's name. + ContainerName string + // SharedNamespaces maps namespace names from /proc/{pid}/ns + // to the file descriptor path referring to the container's namespace. + SharedNamespaces map[string]string + // RootfsMount is the path to the mounted root filesystem. + RootfsMount string + // RootfsPath is the lxc.rootfs.path entry for the container. + RootfsPath string + // SrcContainerName is the original container's name, + // in the case of the clone hook. + SrcContainerName string +} + +var namespaces = []string{"cgroup", "ipc", "mnt", "net", "pid", "time", "user", "uts"} + +var ErrEnv = errors.New("LXC_HOOK_TYPE environment variable is not set") + +// Env parses all environment variables available in liblxc hooks, +// and returns the parsed values in an Env struct. +// Env only parses the environment if`LXC_HOOK_TYPE` is set, +// and will return nil otherwise. +// NOTE The environment variables in liblxc hooks are all prefixed with LXC_. +func LoadEnv() (*Env, error) { + hookType, exist := os.LookupEnv("LXC_HOOK_TYPE") + if !exist { + return nil, ErrEnv + } + + env := &Env{ + ConfigFile: os.Getenv("LXC_CONFIG_FILE"), + Type: HookType(hookType), + Section: os.Getenv("LXC_HOOK_SECTION"), + Version: os.Getenv("LXC_HOOK_VERSION"), + LogLevel: os.Getenv("LXC_LOG_LEVEL"), + ContainerName: os.Getenv("LXC_NAME"), + RootfsMount: os.Getenv("LXC_ROOTFS_MOUNT"), + RootfsPath: os.Getenv("LXC_ROOTFS_PATH"), + SrcContainerName: os.Getenv("LXC_SRC_NAME"), + } + + env.SharedNamespaces = make(map[string]string, len(namespaces)) + for _, ns := range namespaces { + if val, ok := os.LookupEnv("LXC_" + strings.ToUpper(ns) + "_NS"); ok { + env.SharedNamespaces[ns] = val + } + } + return env, nil +} diff --git a/cmd/lxcri-hook/lxcri-hook.c b/cmd/lxcri-hook/lxcri-hook.c deleted file mode 100644 index 9ce889ff..00000000 --- a/cmd/lxcri-hook/lxcri-hook.c +++ /dev/null @@ -1,245 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include // dirname -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ERROR(...) \ - { \ - printf(__VA_ARGS__); \ - ret = EXIT_FAILURE; \ - goto out; \ - } - -int mask_paths_at(int rootfs, int runtime, const char *masked) -{ - // limits.h PATH_MAX - char line[PATH_MAX]; - const char *rel; - int fd; - FILE *f; - - printf("reading file \"%s\" from runtime directory\n", masked); - fd = openat(runtime, masked, O_RDONLY); - if (fd == -1) { - if (errno == ENOENT) { - printf("file \"%s\" does not exist\n", masked); - return 0; - } - return -1; - } - - f = fdopen(fd, "r"); - if (f == NULL) { - printf("file descriptor for runtime directory is null: %s", - strerror(errno)); - close(fd); - return -1; - } - - if (fchdir(rootfs) != 0) { - printf("file to change to rootfs: %s\n", strerror(errno)); - goto out; - } - - while (fgets(line, sizeof(line), f) != NULL) { - line[strlen(line) - 1] = '\0'; // remove newline; - rel = (line[0] == '/') ? line + 1 : line; // trim leading '/' - struct stat path_stat; - if (stat(rel, &path_stat) == -1) { - if (errno == ENOENT) { - printf("ignore non existing filepath %s\n", rel); - errno = 0; - continue; - } - goto out; - } - - if (S_ISDIR(path_stat.st_mode)) { - printf("masking directory %s\n", rel); - if (mount("tmpfs", rel, "tmpfs", MS_RDONLY, NULL) == -1) - goto out; - } else { - printf("masking file %s\n", rel); - if (mount("/dev/null", rel, NULL, MS_BIND, NULL) == -1) - goto out; - } - } -out: - fclose(f); - return (errno == 0) ? 0 : -1; -} - -/* reads up to maxlines-1 lines from path into lines */ -int create_devices_at(int rootfs, int runtime, const char *devices) -{ - int fd; - FILE *f = NULL; - char buf[256]; - - printf("reading file \"%s\" from runtime directory\n", devices); - fd = openat(runtime, devices, O_RDONLY); - if (fd == -1) { - if (errno == ENOENT) { - printf("file \"%s\" does not exist\n", devices); - return 0; - } - return -1; - } - - f = fdopen(fd, "r"); - if (f == NULL) { - printf("file descriptor for runtime directory is null: %s", - strerror(errno)); - close(fd); - return -1; - } - - for (int line = 0;; line++) { - char mode; - int major, minor; - unsigned int filemode; - int uid, gid; - char *dir = NULL; - char *dev = NULL; - char *sep = NULL; - char *tmp = NULL; - int ret; - - if (fchdir(rootfs) == -1) { - printf("file to change to rootfs: %s\n", strerror(errno)); - goto out; - } - - ret = fscanf(f, "%s %c %d %d %o %d:%d\n", &buf[0], &mode, - &major, &minor, &filemode, &uid, &gid); - if (ret == EOF) - goto out; - - if (ret != 7) { - // errno is not set on a matching error - printf("invalid format at line %d at token %d\n", line, ret); - fclose(f); - return -1; - } - - dev = (buf[0] == '/') ? buf + 1 : buf; - - struct stat path_stat; - if (stat(dev, &path_stat) == 0) { - printf("ignore existing device %s\n", dev); - continue; - } - - int ft; - switch (mode) { - case 'b': - ft = S_IFBLK; - break; - case 'c': - ft = S_IFCHR; - break; - case 'f': - ft = S_IFIFO; - break; - default: - printf("%s:%d unsupported device mode '%c'\n", devices, line, mode); - return -1; - } - - sep = strrchr(dev, '/'); - if (sep != NULL) { - printf("creating non-existent directories for device path \"%s\"\n", dev); - *sep = '\0'; - tmp = dev; - dev = sep + 1; - for ((dir = strtok(tmp, "/")); dir != NULL; - dir = strtok(NULL, "/")) { - if (mkdir(dir, 0755) == -1) { - if (errno == EEXIST) - errno = 0; - else - goto out; - } - if (chdir(dir) != 0) { - printf("%s:%d failed to change to directory \"%s\": %s\n", - devices, line, dir, strerror(errno)); - goto out; - } - } - } - printf("creating device: %s %c %d %d mode:%o %d:%d\n", - dev, mode, major, minor, filemode, uid, gid); - ret = mknod(dev, ft | filemode, makedev(major, minor)); - if (ret == -1) { - printf("%s:%d failed to create device \"%s\"\n", - devices, line, dev); - goto out; - } - ret = chown(dev, uid, gid); - if (ret == -1) { - printf("%s:%d failed to chown %d:%d device \"%s\"\n", - devices, line, uid, gid, dev); - goto out; - } - } -out: - fclose(f); - return (errno == 0) ? 0 : -1; -} - -int main(int argc, char **argv) -{ - const char *rootfs_mount; - const char *config_file; - const char *runtime_path; - int rootfs_fd; - int runtime_fd; - int ret = EXIT_SUCCESS; - - rootfs_mount = getenv("LXC_ROOTFS_MOUNT"); - config_file = getenv("LXC_CONFIG_FILE"); - - if (rootfs_mount == NULL) - ERROR("LXC_ROOTFS_MOUNT environment variable not set\n"); - - if (config_file == NULL) - ERROR("LXC_CONFIG_FILE environment variable not set\n"); - - rootfs_fd = open(rootfs_mount, O_PATH); - if (rootfs_fd == -1) - ERROR("failed to open rootfs mount directory: %s", - strerror(errno)); - - runtime_path = dirname(strdup(config_file)); - runtime_fd = open(runtime_path, O_PATH); - - if (runtime_fd == -1) - ERROR("failed to open runtime directory: %s", strerror(errno)); - - printf("create devices int container rootfs\n"); - if (create_devices_at(rootfs_fd, runtime_fd, "devices.txt") == -1) - ERROR("failed to create devices: %s", strerror(errno)); - - printf("masking files and directories in container rootfs\n"); - if (mask_paths_at(rootfs_fd, runtime_fd, "masked.txt") == -1) - ERROR("failed to mask paths: %s", strerror(errno)); - -out: - if (rootfs_fd >= 0) - close(rootfs_fd); - - if (runtime_fd >= 0) - close(runtime_fd); - - exit(ret); -} diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go new file mode 100644 index 00000000..8020bd16 --- /dev/null +++ b/cmd/lxcri-hook/main.go @@ -0,0 +1,161 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "time" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +func init() { + // from `man lxc.container.conf` + // Standard output from the hooks is logged at debug level + // Standard error is not logged, but can be captured by the hook + // redirecting its standard error to standard output. + os.Stderr = os.Stdout +} + +func main() { + + var timeout int + // Individual hooks should set a timeout lower than the overall timeout. + flag.IntVar(&timeout, "timeout", 30, "maximum run time in seconds allowed for all hooks") + flag.Parse() + + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + env, err := LoadEnv() + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + + err = run(ctx, env) + if err != nil { + fmt.Println(err.Error()) + os.Exit(3) + } +} + +func run(ctx context.Context, env *Env) error { + + runtimeDir := filepath.Dir(env.ConfigFile) + + // TODO save hooks to hooks.json + var hooks specs.Hooks + hooksPath := filepath.Join(runtimeDir, "hooks.json") + err := decodeFileJSON(&hooks, hooksPath) + if err != nil { + return err + } + + // TODO save state to state.json + hooksToRun, status, err := ociHooksAndState(env.Type, &hooks) + if err != nil { + return err + } + + if len(hooksToRun) == 0 { + return fmt.Errorf("no hooks defined for %q", env.Type) + } + + // need to deserialize it to set the current specs.ContainerState + var state specs.State + statePath := filepath.Join(runtimeDir, "state.json") + err = decodeFileJSON(&hooks, statePath) + if err != nil { + return err + } + state.Status = status + + return runHooks(ctx, &state, hooksToRun) +} + +// https://github.com/opencontainers/runtime-spec/blob/master/specs-go/state.go +// The only value that does change is the specs.ContainerState in specs.State.Status. +// The specs.ContainerState is implied by the runtime hook. +// status, and the status is already defined by the hook itself ... +func ociHooksAndState(t HookType, hooks *specs.Hooks) ([]specs.Hook, specs.ContainerState, error) { + switch t { + case HookPreMount: + // quote from https://github.com/opencontainers/runtime-spec/blob/master/config.md#posix-platform-hooks + // > For runtimes that implement the deprecated prestart hooks as createRuntime hooks, + // > createRuntime hooks MUST be called after the prestart hooks. + return append(hooks.Prestart, hooks.CreateRuntime...), specs.StateCreating, nil + case HookMount: + return hooks.CreateContainer, specs.StateCreating, nil + case HookStart: + return hooks.StartContainer, specs.StateCreated, nil + case HookPostStart: + return hooks.Poststart, specs.StateRunning, nil + case HookDestroy: + return hooks.Poststop, specs.StateStopped, nil + default: + return nil, specs.StateStopped, fmt.Errorf("liblxc hook %q is not mapped to OCI hooks", t) + } +} + +func runHooks(ctx context.Context, state *specs.State, hooks []specs.Hook) error { + stateJSON, err := json.Marshal(state) + if err != nil { + return fmt.Errorf("failed to serialize spec state: %w", err) + } + for i, h := range hooks { + fmt.Printf("running hook[%d] path:%s\n", i, h.Path) + if err := runHook(ctx, stateJSON, h); err != nil { + return err + } + } + return nil +} + +func runHook(ctx context.Context, stateJSON []byte, hook specs.Hook) error { + if hook.Timeout != nil { + hookCtx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(*hook.Timeout)) + defer cancel() + ctx = hookCtx + } + cmd := exec.CommandContext(ctx, hook.Path, hook.Args...) + cmd.Env = hook.Env + in, err := cmd.StdinPipe() + if err != nil { + return fmt.Errorf("failed to get stdin pipe: %w", err) + } + if err := cmd.Start(); err != nil { + return err + } + if _, err := io.Copy(in, bytes.NewReader(stateJSON)); err != nil { + return err + } + in.Close() + return cmd.Wait() +} + +// FIXME copied from `lxcri` +func decodeFileJSON(obj interface{}, src string) error { + // #nosec + f, err := os.Open(src) + if err != nil { + return err + } + // #nosec + err = json.NewDecoder(f).Decode(obj) + if err != nil { + f.Close() + return fmt.Errorf("failed to decode JSON from %s: %w", src, err) + } + err = f.Close() + if err != nil { + return fmt.Errorf("failed to close %s: %w", src, err) + } + return nil +} From 226bf8877fedd7827e87e6f687f0adb6f94d9ca7 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 11 Apr 2021 15:31:36 +0200 Subject: [PATCH 303/373] Disable HookPostStart and HookDestroy. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook/hooks.go | 2 +- cmd/lxcri-hook/main.go | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/lxcri-hook/hooks.go b/cmd/lxcri-hook/hooks.go index 50ede723..00857a58 100644 --- a/cmd/lxcri-hook/hooks.go +++ b/cmd/lxcri-hook/hooks.go @@ -15,11 +15,11 @@ const ( HookAutodev = "autodev" HookStartHost = "start-host" HookStart = "start" - HookPostStart = "post-start" // FIXME this is undefined by liblxc HookStop = "stop" HookPostStop = "post-stop" HookClone = "clone" HookDestroy = "destroy" + //HookPostStart = "post-start" // not defined by liblxc ) // Env is the parsed liblxc hook environment. diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 8020bd16..42840be0 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -95,10 +95,11 @@ func ociHooksAndState(t HookType, hooks *specs.Hooks) ([]specs.Hook, specs.Conta return hooks.CreateContainer, specs.StateCreating, nil case HookStart: return hooks.StartContainer, specs.StateCreated, nil - case HookPostStart: - return hooks.Poststart, specs.StateRunning, nil - case HookDestroy: - return hooks.Poststop, specs.StateStopped, nil + // NOTE the following hooks are executed directly from lxcri + //case HookPostStart: + // return hooks.Poststart, specs.StateRunning, nil + //case HookDestroy: + // return hooks.Poststop, specs.StateStopped, nil default: return nil, specs.StateStopped, fmt.Errorf("liblxc hook %q is not mapped to OCI hooks", t) } From 396d692c4cbae82cee5565f16f222e9340ce7557 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 12 Apr 2021 11:07:13 +0200 Subject: [PATCH 304/373] Introduce package pkg/specki for specs.Spec helper functions. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook/main.go | 67 ++------------------- container.go | 6 +- create.go | 5 +- init.go | 3 +- pkg/specki/specki.go | 128 +++++++++++++++++++++++++++++++++++++++++ runtime.go | 5 +- spec_utils.go | 30 ---------- utils.go | 43 -------------- 8 files changed, 144 insertions(+), 143 deletions(-) create mode 100644 pkg/specki/specki.go delete mode 100644 spec_utils.go diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 42840be0..b366b6ba 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -1,17 +1,14 @@ package main import ( - "bytes" "context" - "encoding/json" "flag" "fmt" - "io" "os" - "os/exec" "path/filepath" "time" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" ) @@ -53,7 +50,7 @@ func run(ctx context.Context, env *Env) error { // TODO save hooks to hooks.json var hooks specs.Hooks hooksPath := filepath.Join(runtimeDir, "hooks.json") - err := decodeFileJSON(&hooks, hooksPath) + err := specki.DecodeJSONFile(hooksPath, &hooks) if err != nil { return err } @@ -71,13 +68,13 @@ func run(ctx context.Context, env *Env) error { // need to deserialize it to set the current specs.ContainerState var state specs.State statePath := filepath.Join(runtimeDir, "state.json") - err = decodeFileJSON(&hooks, statePath) + err = specki.DecodeJSONFile(statePath, &hooks) if err != nil { return err } state.Status = status - return runHooks(ctx, &state, hooksToRun) + return specki.RunHooks(ctx, &state, hooksToRun) } // https://github.com/opencontainers/runtime-spec/blob/master/specs-go/state.go @@ -104,59 +101,3 @@ func ociHooksAndState(t HookType, hooks *specs.Hooks) ([]specs.Hook, specs.Conta return nil, specs.StateStopped, fmt.Errorf("liblxc hook %q is not mapped to OCI hooks", t) } } - -func runHooks(ctx context.Context, state *specs.State, hooks []specs.Hook) error { - stateJSON, err := json.Marshal(state) - if err != nil { - return fmt.Errorf("failed to serialize spec state: %w", err) - } - for i, h := range hooks { - fmt.Printf("running hook[%d] path:%s\n", i, h.Path) - if err := runHook(ctx, stateJSON, h); err != nil { - return err - } - } - return nil -} - -func runHook(ctx context.Context, stateJSON []byte, hook specs.Hook) error { - if hook.Timeout != nil { - hookCtx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(*hook.Timeout)) - defer cancel() - ctx = hookCtx - } - cmd := exec.CommandContext(ctx, hook.Path, hook.Args...) - cmd.Env = hook.Env - in, err := cmd.StdinPipe() - if err != nil { - return fmt.Errorf("failed to get stdin pipe: %w", err) - } - if err := cmd.Start(); err != nil { - return err - } - if _, err := io.Copy(in, bytes.NewReader(stateJSON)); err != nil { - return err - } - in.Close() - return cmd.Wait() -} - -// FIXME copied from `lxcri` -func decodeFileJSON(obj interface{}, src string) error { - // #nosec - f, err := os.Open(src) - if err != nil { - return err - } - // #nosec - err = json.NewDecoder(f).Decode(obj) - if err != nil { - f.Close() - return fmt.Errorf("failed to decode JSON from %s: %w", src, err) - } - err = f.Close() - if err != nil { - return fmt.Errorf("failed to close %s: %w", src, err) - } - return nil -} diff --git a/container.go b/container.go index 8e7de7be..bcc0abc4 100644 --- a/container.go +++ b/container.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" @@ -71,7 +72,8 @@ type Container struct { *ContainerConfig CreatedAt time.Time - Pid int + // Pid is the process ID of the liblxc monitor process ( see ExecStart ) + Pid int runtimeDir string } @@ -102,7 +104,7 @@ func (c *Container) create() error { } func (c *Container) load() error { - err := decodeFileJSON(c, c.RuntimePath("lxcri.json")) + err := specki.DecodeJSONFile(c.RuntimePath("lxcri.json"), c) if err != nil { return fmt.Errorf("failed to load container config: %w", err) } diff --git a/create.go b/create.go index 061f5823..b3feace3 100644 --- a/create.go +++ b/create.go @@ -8,6 +8,7 @@ import ( "path/filepath" "strings" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "gopkg.in/lxc/go-lxc.v2" ) @@ -60,7 +61,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container // Seralize the modified spec.Spec separately, to make it available for // runtime hooks. specPath := c.RuntimePath(BundleConfigFile) - err := encodeFileJSON(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) + err := specki.EncodeJSONFile(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE, 0440) if err != nil { return c, err } @@ -70,7 +71,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container } p := c.RuntimePath("lxcri.json") - err = encodeFileJSON(p, c, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0440) + err = specki.EncodeJSONFile(p, c, os.O_EXCL|os.O_CREATE, 0440) if err != nil { return c, err } diff --git a/init.go b/init.go index 175a97de..8b8717a9 100644 --- a/init.go +++ b/init.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" ) @@ -34,7 +35,7 @@ func createFifo(dst string, mode uint32) error { // runAsRuntimeUser returns true if container process is started as runtime user. func runAsRuntimeUser(spec *specs.Spec) bool { - puid := unmapContainerID(spec.Process.User.UID, spec.Linux.UIDMappings) + puid := specki.UnmapContainerID(spec.Process.User.UID, spec.Linux.UIDMappings) return puid == uint32(os.Getuid()) } diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go new file mode 100644 index 00000000..74cb3d35 --- /dev/null +++ b/pkg/specki/specki.go @@ -0,0 +1,128 @@ +// Package specki containse general-purpose helper functions that operate +// on (parts of) the runtime spec (specs.Spec). +// These functions should not contain any code that is `lxcri` specific. +package specki + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "os" + "os/exec" + "time" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +// UnmapContainerID returns the (user/group) ID to which the given +// ID is mapped to by the given idmaps. +// The returned id will be equal to the given id +// if it is not mapped by the given idmaps. +func UnmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { + for _, idmap := range idmaps { + if idmap.Size < 1 { + continue + } + maxID := idmap.ContainerID + idmap.Size - 1 + // check if c.Process.UID is contained in the mapping + if (id >= idmap.ContainerID) && (id <= maxID) { + offset := id - idmap.ContainerID + hostid := idmap.HostID + offset + return hostid + } + } + // uid is not mapped + return id +} + +// RunHooks calls RunHook for each of the given runtime hooks. +// The given runtime state is serialized as JSON and passed to each RunHook call. +func RunHooks(ctx context.Context, state *specs.State, hooks []specs.Hook) error { + stateJSON, err := json.Marshal(state) + if err != nil { + return fmt.Errorf("failed to serialize spec state: %w", err) + } + for i, h := range hooks { + fmt.Printf("running hook[%d] path:%s\n", i, h.Path) + if err := RunHook(ctx, stateJSON, h); err != nil { + return err + } + } + return nil +} + +// RunHook executes the command defined by the given hook. +// The given runtime state is passed over stdin to the executed command. +// The command is executed with the given context ctx, or a sub-context +// of it if Hook.Timeout is not nil. +func RunHook(ctx context.Context, stateJSON []byte, hook specs.Hook) error { + if hook.Timeout != nil { + hookCtx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(*hook.Timeout)) + defer cancel() + ctx = hookCtx + } + cmd := exec.CommandContext(ctx, hook.Path, hook.Args...) + cmd.Env = hook.Env + in, err := cmd.StdinPipe() + if err != nil { + return fmt.Errorf("failed to get stdin pipe: %w", err) + } + if err := cmd.Start(); err != nil { + return err + } + if _, err := io.Copy(in, bytes.NewReader(stateJSON)); err != nil { + return err + } + in.Close() + return cmd.Wait() +} + +// DecodeJSONFile reads the next JSON-encoded value from +// the file with the given filename and stores it in the value pointed to by v. +func DecodeJSONFile(filename string, v interface{}) error { + // #nosec + f, err := os.Open(filename) + if err != nil { + return err + } + // #nosec + err = json.NewDecoder(f).Decode(v) + if err != nil { + f.Close() + return fmt.Errorf("failed to decode JSON from %s: %w", filename, err) + } + err = f.Close() + if err != nil { + return fmt.Errorf("failed to close %s: %w", filename, err) + } + return nil +} + +// EncodeJSONFile writes the JSON encoding of v followed by a newline character +// to the file with the given filename. +// The file is opened read-write with the (optional) provided flags. +// The permission bits perm (not affected by umask) are set after the file was closed. +func EncodeJSONFile(filename string, v interface{}, flags int, perm os.FileMode) error { + f, err := os.OpenFile(filename, os.O_RDWR|flags, perm) + if err != nil { + return err + } + enc := json.NewEncoder(f) + err = enc.Encode(v) + if err != nil { + f.Close() + return fmt.Errorf("failed to encode JSON to %s: %w", filename, err) + } + err = f.Close() + if err != nil { + return fmt.Errorf("failed to close %s: %w", filename, err) + } + // Use chmod because initial perm is affected by umask and flags. + err = os.Chmod(filename, perm) + if err != nil { + return fmt.Errorf("failed to 'chmod %o %s': %w", perm, filename, err) + } + return nil +} diff --git a/runtime.go b/runtime.go index eb2f35d9..d246eac8 100644 --- a/runtime.go +++ b/runtime.go @@ -10,6 +10,7 @@ import ( "time" "github.com/creack/pty" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" @@ -289,7 +290,7 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e // This is a convenience function for the cli. func ReadSpecJSON(p string) (*specs.Spec, error) { spec := new(specs.Spec) - err := decodeFileJSON(spec, p) + err := specki.DecodeJSONFile(p, spec) return spec, err } @@ -298,7 +299,7 @@ func ReadSpecJSON(p string) (*specs.Spec, error) { // This is a convenience function for the cli. func ReadSpecProcessJSON(src string) (*specs.Process, error) { proc := new(specs.Process) - err := decodeFileJSON(proc, src) + err := specki.DecodeJSONFile(src, proc) return proc, err } diff --git a/spec_utils.go b/spec_utils.go deleted file mode 100644 index f95f7f13..00000000 --- a/spec_utils.go +++ /dev/null @@ -1,30 +0,0 @@ -package lxcri - -import ( - "github.com/opencontainers/runtime-spec/specs-go" -) - -// This file is only for helper functions that operate -// on (parts of) the runtime spec specs.Spec -// without any internal internal knowledge. - -// unmapContainerID returns the (user/group) ID to which the given -// ID is mapped to by the given idmaps. -// The returned id will be equal to the given id -// if it is not mapped by the given idmaps. -func unmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { - for _, idmap := range idmaps { - if idmap.Size < 1 { - continue - } - maxID := idmap.ContainerID + idmap.Size - 1 - // check if c.Process.UID is contained in the mapping - if (id >= idmap.ContainerID) && (id <= maxID) { - offset := id - idmap.ContainerID - hostid := idmap.HostID + offset - return hostid - } - } - // uid is not mapped - return id -} diff --git a/utils.go b/utils.go index 9e3fe077..d2254244 100644 --- a/utils.go +++ b/utils.go @@ -2,7 +2,6 @@ package lxcri import ( "bytes" - "encoding/json" "fmt" "os" "path/filepath" @@ -50,48 +49,6 @@ func isFilesystem(dir string, fsName string) error { return nil } -func decodeFileJSON(obj interface{}, src string) error { - // #nosec - f, err := os.Open(src) - if err != nil { - return err - } - // #nosec - err = json.NewDecoder(f).Decode(obj) - if err != nil { - f.Close() - return errorf("failed to decode JSON from %s: %w", src, err) - } - err = f.Close() - if err != nil { - return errorf("failed to close %s: %w", src, err) - } - return nil -} - -func encodeFileJSON(dst string, obj interface{}, flags int, mode os.FileMode) error { - f, err := os.OpenFile(dst, flags, mode) - if err != nil { - return err - } - enc := json.NewEncoder(f) - err = enc.Encode(obj) - if err != nil { - f.Close() - return errorf("failed to encode JSON to %s: %w", dst, err) - } - err = f.Close() - if err != nil { - return errorf("failed to close %s: %w", dst, err) - } - // Use chmod because initial mode is affected by umask and flags. - err = os.Chmod(dst, mode) - if err != nil { - return errorf("failed to 'chmod %o %s': %w", mode, dst, err) - } - return nil -} - func nullTerminatedString(data []byte) string { i := bytes.Index(data, []byte{0}) return string(data[:i]) From b152100317dc8a336c86c7e4dc5a9a3e7d4f3509 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 12 Apr 2021 15:07:04 +0200 Subject: [PATCH 305/373] Move log package to pkg/log Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 2 +- {log => pkg/log}/log.go | 0 runtime_test.go | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {log => pkg/log}/log.go (100%) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 3a651ac9..06464f04 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -11,7 +11,7 @@ import ( "time" "github.com/drachenfels-de/lxcri" - "github.com/drachenfels-de/lxcri/log" + "github.com/drachenfels-de/lxcri/pkg/log" "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) diff --git a/log/log.go b/pkg/log/log.go similarity index 100% rename from log/log.go rename to pkg/log/log.go diff --git a/runtime_test.go b/runtime_test.go index 3b0180eb..60115ed8 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/drachenfels-de/lxcri/log" + "github.com/drachenfels-de/lxcri/pkg/log" "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/require" "golang.org/x/sys/unix" From cda583fef2952f20c69752405a5ad8d8bcd2c1f8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 12 Apr 2021 15:13:25 +0200 Subject: [PATCH 306/373] Remove whitespaces. Signed-off-by: Ruben Jenster --- cgroup.go | 2 -- cmd/lxcri-hook/main.go | 2 -- create.go | 1 - namespaces.go | 3 +-- runtime_test.go | 1 - 5 files changed, 1 insertion(+), 8 deletions(-) diff --git a/cgroup.go b/cgroup.go index 03d29a45..94e5b8ba 100644 --- a/cgroup.go +++ b/cgroup.go @@ -84,7 +84,6 @@ func configureCgroup(rt *Runtime, c *Container) error { } func configureCgroupPath(rt *Runtime, c *Container) error { - if rt.SystemdCgroup { c.CgroupDir = parseSystemdCgroupPath(c.Spec.Linux.CgroupsPath) } else { @@ -294,7 +293,6 @@ func loadCgroup(cgName string) (*cgroupInfo, error) { } func killCgroupProcs(cgroupName string, sig unix.Signal) error { - cg, err := loadCgroup(cgroupName) if err != nil { return fmt.Errorf("failed to load cgroup %s: %w", cgroupName, err) diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index b366b6ba..9c9847f2 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -21,7 +21,6 @@ func init() { } func main() { - var timeout int // Individual hooks should set a timeout lower than the overall timeout. flag.IntVar(&timeout, "timeout", 30, "maximum run time in seconds allowed for all hooks") @@ -44,7 +43,6 @@ func main() { } func run(ctx context.Context, env *Env) error { - runtimeDir := filepath.Dir(env.ConfigFile) // TODO save hooks to hooks.json diff --git a/create.go b/create.go index b3feace3..83d0012c 100644 --- a/create.go +++ b/create.go @@ -18,7 +18,6 @@ import ( // You may have to call Runtime.Delete to cleanup container runtime state, // if Create returns with an error. func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { - if err := rt.checkConfig(cfg); err != nil { return nil, err } diff --git a/namespaces.go b/namespaces.go index 1d007f20..ab2a1916 100644 --- a/namespaces.go +++ b/namespaces.go @@ -6,9 +6,8 @@ import ( "runtime" "strings" - "golang.org/x/sys/unix" - "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" ) // namespace is a mapping from the namespace name diff --git a/runtime_test.go b/runtime_test.go index 60115ed8..86a33cb4 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -117,7 +117,6 @@ ruben:1000:1 ruben:20000:65536 */ func TestRuntimeUnprivileged(t *testing.T) { - rt := newRuntime(t) defer os.RemoveAll(rt.Root) From 469abb345cbe972139869017ccc691c91f6b37c9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 08:08:36 +0200 Subject: [PATCH 307/373] Move methods from start.go to runtime.go Signed-off-by: Ruben Jenster --- create.go | 96 ------------------------------------------------------ runtime.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 96 deletions(-) diff --git a/create.go b/create.go index 83d0012c..f1aeaed6 100644 --- a/create.go +++ b/create.go @@ -78,102 +78,6 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, err } -func (rt *Runtime) keepEnv(names ...string) { - for _, n := range names { - if val := os.Getenv(n); val != "" { - rt.env = append(rt.env, n+"="+val) - } - } -} - -// Init initializes the runtime instance. -// It creates required directories and checks the hosts system configuration. -// Unsupported runtime features are disabled and a warning message is logged. -// Init must be called once for a runtime instance before calling any other method. -func (rt *Runtime) Init() error { - rt.rootfsMount = filepath.Join(rt.Root, ".rootfs") - if err := os.MkdirAll(rt.rootfsMount, 0777); err != nil { - return errorf("failed to create directory for rootfs mount %s: %w", rt.rootfsMount, err) - } - if err := os.Chmod(rt.rootfsMount, 0777); err != nil { - return errorf("failed to 'chmod 0777 %s': %w", err) - } - - rt.privileged = os.Getuid() == 0 - - rt.keepEnv("HOME", "XDG_RUNTIME_DIR", "PATH") - - err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) - if err != nil { - return errorf("access check failed: %w", err) - } - - if err := isFilesystem("/proc", "proc"); err != nil { - return errorf("procfs not mounted on /proc: %w", err) - } - if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { - return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) - } - - if !lxc.VersionAtLeast(3, 1, 0) { - return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) - } - - if !lxc.VersionAtLeast(4, 0, 5) { - rt.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) - } - - return nil -} - -func (rt *Runtime) checkConfig(cfg *ContainerConfig) error { - if len(cfg.ContainerID) == 0 { - return errorf("missing container ID") - } - return rt.checkSpec(cfg.Spec) -} - -func (rt *Runtime) checkSpec(spec *specs.Spec) error { - if spec.Root == nil { - return errorf("spec.Root is nil") - } - if len(spec.Root.Path) == 0 { - return errorf("empty spec.Root.Path") - } - - if spec.Process == nil { - return errorf("spec.Process is nil") - } - - if len(spec.Process.Args) == 0 { - return errorf("specs.Process.Args is empty") - } - - if spec.Process.Cwd == "" { - rt.Log.Info().Msg("specs.Process.Cwd is unset defaulting to '/'") - spec.Process.Cwd = "/" - } - - yes, err := isHostNamespaceShared(spec.Linux.Namespaces, specs.MountNamespace) - if err != nil { - return err - } - if yes { - return errorf("container wants to share the hosts mount namespace") - } - - // It should be best practise not to do so, but there are containers that - // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set - yes, err = isHostNamespaceShared(spec.Linux.Namespaces, specs.PIDNamespace) - if err != nil { - return err - } - if yes { - rt.Log.Info().Msg("container wil share the hosts PID namespace") - } - return nil -} - func configureContainer(rt *Runtime, c *Container) error { if c.Spec.Hostname != "" { if err := c.SetConfigItem("lxc.uts.name", c.Spec.Hostname); err != nil { diff --git a/runtime.go b/runtime.go index d246eac8..0cea1a81 100644 --- a/runtime.go +++ b/runtime.go @@ -102,6 +102,102 @@ func (rt *Runtime) libexec(name string) string { return filepath.Join(rt.LibexecDir, name) } +// Init initializes the runtime instance. +// It creates required directories and checks the hosts system configuration. +// Unsupported runtime features are disabled and a warning message is logged. +// Init must be called once for a runtime instance before calling any other method. +func (rt *Runtime) Init() error { + rt.rootfsMount = filepath.Join(rt.Root, ".rootfs") + if err := os.MkdirAll(rt.rootfsMount, 0777); err != nil { + return errorf("failed to create directory for rootfs mount %s: %w", rt.rootfsMount, err) + } + if err := os.Chmod(rt.rootfsMount, 0777); err != nil { + return errorf("failed to 'chmod 0777 %s': %w", err) + } + + rt.privileged = os.Getuid() == 0 + + rt.keepEnv("HOME", "XDG_RUNTIME_DIR", "PATH") + + err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) + if err != nil { + return errorf("access check failed: %w", err) + } + + if err := isFilesystem("/proc", "proc"); err != nil { + return errorf("procfs not mounted on /proc: %w", err) + } + if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { + return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) + } + + if !lxc.VersionAtLeast(3, 1, 0) { + return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) + } + + if !lxc.VersionAtLeast(4, 0, 5) { + rt.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) + } + + return nil +} + +func (rt *Runtime) checkConfig(cfg *ContainerConfig) error { + if len(cfg.ContainerID) == 0 { + return errorf("missing container ID") + } + return rt.checkSpec(cfg.Spec) +} + +func (rt *Runtime) checkSpec(spec *specs.Spec) error { + if spec.Root == nil { + return errorf("spec.Root is nil") + } + if len(spec.Root.Path) == 0 { + return errorf("empty spec.Root.Path") + } + + if spec.Process == nil { + return errorf("spec.Process is nil") + } + + if len(spec.Process.Args) == 0 { + return errorf("specs.Process.Args is empty") + } + + if spec.Process.Cwd == "" { + rt.Log.Info().Msg("specs.Process.Cwd is unset defaulting to '/'") + spec.Process.Cwd = "/" + } + + yes, err := isHostNamespaceShared(spec.Linux.Namespaces, specs.MountNamespace) + if err != nil { + return err + } + if yes { + return errorf("container wants to share the hosts mount namespace") + } + + // It should be best practise not to do so, but there are containers that + // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set + yes, err = isHostNamespaceShared(spec.Linux.Namespaces, specs.PIDNamespace) + if err != nil { + return err + } + if yes { + rt.Log.Info().Msg("container wil share the hosts PID namespace") + } + return nil +} + +func (rt *Runtime) keepEnv(names ...string) { + for _, n := range names { + if val := os.Getenv(n); val != "" { + rt.env = append(rt.env, n+"="+val) + } + } +} + // Load loads a container from the runtime directory. // The container must have been created with Runtime.Create. func (rt *Runtime) Load(containerID string) (*Container, error) { From ea827ab23d24ebaaed618874df1fb678d44007e3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 08:27:00 +0200 Subject: [PATCH 308/373] Move Spec deserialization methods to specki package. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 5 +-- pkg/specki/specki.go | 79 ++++++++++++++++++++++++++++++++++++++++++++ runtime.go | 77 ------------------------------------------ runtime_test.go | 3 +- 4 files changed, 84 insertions(+), 80 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 06464f04..ecb65794 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -12,6 +12,7 @@ import ( "github.com/drachenfels-de/lxcri" "github.com/drachenfels-de/lxcri/pkg/log" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli/v2" ) @@ -297,7 +298,7 @@ func doCreate(ctxcli *cli.Context) error { return err } specPath := filepath.Join(clxc.cfg.BundlePath, lxcri.BundleConfigFile) - spec, err := lxcri.ReadSpecJSON(specPath) + spec, err := specki.ReadSpecJSON(specPath) if err != nil { return fmt.Errorf("failed to load container spec from bundle: %w", err) } @@ -507,7 +508,7 @@ func doExec(ctxcli *cli.Context) error { clxc.Log.Warn().Msg("detaching process but pid-file value is unset") } - procSpec, err := lxcri.LoadSpecProcess(ctxcli.String("process"), args) + procSpec, err := specki.LoadSpecProcess(ctxcli.String("process"), args) if err != nil { return err } diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 74cb3d35..366fe7c2 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -126,3 +126,82 @@ func EncodeJSONFile(filename string, v interface{}, flags int, perm os.FileMode) } return nil } + +// ReadSpecJSON reads the JSON encoded OCI +// spec from the given path. +// This is a convenience function for the cli. +func ReadSpecJSON(p string) (*specs.Spec, error) { + spec := new(specs.Spec) + err := DecodeJSONFile(p, spec) + return spec, err +} + +// ReadSpecProcessJSON reads the JSON encoded OCI +// spec process definition from the given path. +// This is a convenience function for the cli. +func ReadSpecProcessJSON(src string) (*specs.Process, error) { + proc := new(specs.Process) + err := DecodeJSONFile(src, proc) + return proc, err +} + +// LoadSpecProcess calls ReadSpecProcessJSON if the given specProcessPath is not empty, +// otherwise it creates a new specs.Process from the given args. +// It's an error if both values are empty. +func LoadSpecProcess(specProcessPath string, args []string) (*specs.Process, error) { + if specProcessPath != "" { + return ReadSpecProcessJSON(specProcessPath) + } + if len(args) == 0 { + return nil, fmt.Errorf("spec process path and args are empty") + } + return &specs.Process{Cwd: "/", Args: args}, nil +} + +// NewSpec returns a minimal spec.Spec instance, which is +// required to run the given process within a container +// using the given rootfs. +// NOTE /proc and /dev folders must be present within the given rootfs. +func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { + proc := NewSpecProcess(cmd, args...) + + return &specs.Spec{ + Version: specs.Version, + Linux: &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + // isolate all namespaces by default + specs.LinuxNamespace{Type: specs.PIDNamespace}, + specs.LinuxNamespace{Type: specs.MountNamespace}, + specs.LinuxNamespace{Type: specs.IPCNamespace}, + specs.LinuxNamespace{Type: specs.UTSNamespace}, + specs.LinuxNamespace{Type: specs.CgroupNamespace}, + specs.LinuxNamespace{Type: specs.NetworkNamespace}, + }, + Devices: EssentialDevices, + Resources: &specs.LinuxResources{ + Devices: EssentialDevicesAllow, + }, + }, + Mounts: []specs.Mount{ + specs.Mount{Destination: "/proc", Source: "proc", Type: "proc", + Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, + }, + specs.Mount{Destination: "/dev", Source: "tmpfs", Type: "tmpfs", + Options: []string{"rw", "nosuid", "noexec", "relatime", "dev"}, + // devtmpfs (rw,nosuid,relatime,size=6122620k,nr_inodes=1530655,mode=755,inode64) + }, + }, + Process: proc, + Root: &specs.Root{Path: rootfs}, + } +} + +// NewSpecProcess creates a specs.Process instance +// from the given command cmd and the command arguments args. +func NewSpecProcess(cmd string, args ...string) *specs.Process { + proc := new(specs.Process) + proc.Args = append(proc.Args, cmd) + proc.Args = append(proc.Args, args...) + proc.Cwd = "/" + return proc +} diff --git a/runtime.go b/runtime.go index 0cea1a81..cad5f9d7 100644 --- a/runtime.go +++ b/runtime.go @@ -380,80 +380,3 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e } return nil } - -// ReadSpecJSON reads the JSON encoded OCI -// spec from the given path. -// This is a convenience function for the cli. -func ReadSpecJSON(p string) (*specs.Spec, error) { - spec := new(specs.Spec) - err := specki.DecodeJSONFile(p, spec) - return spec, err -} - -// ReadSpecProcessJSON reads the JSON encoded OCI -// spec process definition from the given path. -// This is a convenience function for the cli. -func ReadSpecProcessJSON(src string) (*specs.Process, error) { - proc := new(specs.Process) - err := specki.DecodeJSONFile(src, proc) - return proc, err -} - -// LoadSpecProcess calls ReadSpecProcessJSON if the given specProcessPath is not empty, -// otherwise it creates a new specs.Process from the given args. -// It's an error if both values are empty. -func LoadSpecProcess(specProcessPath string, args []string) (*specs.Process, error) { - if specProcessPath != "" { - return ReadSpecProcessJSON(specProcessPath) - } - if len(args) == 0 { - return nil, fmt.Errorf("spec process path and args are empty") - } - return &specs.Process{Cwd: "/", Args: args}, nil -} - -// NewSpec returns a minimal spec.Spec instance, which is -// required to run the given process within a container -// using the given rootfs. -// NOTE /proc and /dev folders must be present within the given rootfs. -func NewSpec(rootfs string, cmd string, args ...string) *specs.Spec { - proc := NewSpecProcess(cmd, args...) - - return &specs.Spec{ - Version: specs.Version, - Linux: &specs.Linux{ - Namespaces: []specs.LinuxNamespace{ - // isolate all namespaces by default - specs.LinuxNamespace{Type: specs.PIDNamespace}, - specs.LinuxNamespace{Type: specs.MountNamespace}, - specs.LinuxNamespace{Type: specs.IPCNamespace}, - specs.LinuxNamespace{Type: specs.UTSNamespace}, - specs.LinuxNamespace{Type: specs.CgroupNamespace}, - specs.LinuxNamespace{Type: specs.NetworkNamespace}, - }, - Resources: &specs.LinuxResources{}, - Devices: defaultDevices, - }, - Mounts: []specs.Mount{ - specs.Mount{Destination: "/proc", Source: "proc", Type: "proc", - Options: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, - }, - specs.Mount{Destination: "/dev", Source: "tmpfs", Type: "tmpfs", - Options: []string{"rw", "nosuid", "noexec", "relatime", "dev"}, - // devtmpfs (rw,nosuid,relatime,size=6122620k,nr_inodes=1530655,mode=755,inode64) - }, - }, - Process: proc, - Root: &specs.Root{Path: rootfs}, - } -} - -// NewSpecProcess creates a specs.Process instance -// from the given command cmd and the command arguments args. -func NewSpecProcess(cmd string, args ...string) *specs.Process { - proc := new(specs.Process) - proc.Args = append(proc.Args, cmd) - proc.Args = append(proc.Args, args...) - proc.Cwd = "/" - return proc -} diff --git a/runtime_test.go b/runtime_test.go index 86a33cb4..fddd24e1 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/drachenfels-de/lxcri/pkg/log" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/require" "golang.org/x/sys/unix" @@ -51,7 +52,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { err = exec.Command("cp", cmd, rootfs).Run() require.NoError(t, err) - spec := NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) + spec := specki.NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true)} cfg.Spec.Linux.CgroupsPath = "" // use /proc/self/cgroup" From 544f30fb37fa019e3b76861cadb2aa97e2bc64f3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 08:28:47 +0200 Subject: [PATCH 309/373] Refactor device handling. Move to specki package. Signed-off-by: Ruben Jenster --- create.go | 1 - devices.go | 110 ------------------------------------------- pkg/specki/specki.go | 73 ++++++++++++++++++++++++++++ runtime.go | 3 +- 4 files changed, 74 insertions(+), 113 deletions(-) delete mode 100644 devices.go diff --git a/create.go b/create.go index f1aeaed6..5fea8e17 100644 --- a/create.go +++ b/create.go @@ -10,7 +10,6 @@ import ( "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" - "gopkg.in/lxc/go-lxc.v2" ) // Create creates a single container instance from the given ContainerConfig. diff --git a/devices.go b/devices.go deleted file mode 100644 index 1533d074..00000000 --- a/devices.go +++ /dev/null @@ -1,110 +0,0 @@ -package lxcri - -import ( - "fmt" - "os" - - "github.com/opencontainers/runtime-spec/specs-go" -) - -var defaultDevices = []specs.LinuxDevice{ - specs.LinuxDevice{Path: "/dev/null", Type: "c", Major: 1, Minor: 3}, - specs.LinuxDevice{Path: "/dev/zero", Type: "c", Major: 1, Minor: 5}, - specs.LinuxDevice{Path: "/dev/full", Type: "c", Major: 1, Minor: 7}, - specs.LinuxDevice{Path: "/dev/random", Type: "c", Major: 1, Minor: 8}, - specs.LinuxDevice{Path: "/dev/urandom", Type: "c", Major: 1, Minor: 9}, - specs.LinuxDevice{Path: "/dev/tty", Type: "c", Major: 5, Minor: 0}, - // FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? - // `man 2 mount` | devpts - // ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. - // See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` -} - -func isDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) (bool, error) { - for _, d := range spec.Linux.Devices { - if d.Path == dev.Path { - if d.Type != dev.Type { - return false, errorf("%s type mismatch (expected %s but was %s)", dev, dev.Type, d.Type) - } - if d.Major != dev.Major { - return false, errorf("%s major number mismatch (expected %d but was %d)", dev, dev.Major, d.Major) - } - if d.Minor != dev.Minor { - return false, errorf("%s major number mismatch (expected %d but was %d)", dev, dev.Major, d.Major) - } - return true, nil - } - } - return false, nil -} - -func addDevice(spec *specs.Spec, dev specs.LinuxDevice, mode os.FileMode, uid uint32, gid uint32, access string) { - dev.FileMode = &mode - dev.UID = &uid - dev.GID = &gid - spec.Linux.Devices = append(spec.Linux.Devices, dev) - addDevicePerms(spec, dev.Type, &dev.Major, &dev.Minor, access) -} - -func addDevicePerms(spec *specs.Spec, devType string, major *int64, minor *int64, access string) { - devCgroup := specs.LinuxDeviceCgroup{Allow: true, Type: devType, Major: major, Minor: minor, Access: access} - spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, devCgroup) -} - -// ensureDefaultDevices adds the mandatory devices defined by the [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) -// to the given container spec if required. -// crio can add devices to containers, but this does not work for privileged containers. -// See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 -// TODO file an issue on cri-o (at least for support) -func ensureDefaultDevices(spec *specs.Spec) error { - mode := os.FileMode(0666) - var uid, gid uint32 = spec.Process.User.UID, spec.Process.User.GID - - ptmx := specs.LinuxDevice{Path: "/dev/ptmx", Type: "c", Major: 5, Minor: 2} - addDevicePerms(spec, "c", &ptmx.Major, &ptmx.Minor, "rwm") // /dev/ptmx, /dev/pts/ptmx - - pts0 := specs.LinuxDevice{Path: "/dev/pts/0", Type: "c", Major: 88, Minor: 0} - addDevicePerms(spec, "c", &pts0.Major, nil, "rwm") // dev/pts/[0..9] - - // add missing default devices - for _, dev := range defaultDevices { - exist, err := isDeviceEnabled(spec, dev) - if err != nil { - return err - } - if !exist { - addDevice(spec, dev, mode, uid, gid, "rwm") - } - } - return nil -} - -func createDeviceFile(dst string, spec *specs.Spec) error { - if spec.Linux.Devices == nil { - return nil - } - f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) - if err != nil { - return err - } - for _, d := range spec.Linux.Devices { - uid := spec.Process.User.UID - if d.UID != nil { - uid = *d.UID - } - gid := spec.Process.User.GID - if d.GID != nil { - gid = *d.GID - } - mode := os.FileMode(0600) - if d.FileMode != nil { - mode = *d.FileMode - } - _, err = fmt.Fprintf(f, "%s %s %d %d %o %d:%d\n", d.Path, d.Type, d.Major, d.Minor, mode, uid, gid) - if err != nil { - f.Close() - return err - } - } - return f.Close() -} diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 366fe7c2..d7684314 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -127,6 +127,79 @@ func EncodeJSONFile(filename string, v interface{}, flags int, perm os.FileMode) return nil } +func int64p(v int64) *int64 { + return &v +} + +func modep(m os.FileMode) *os.FileMode { + return &m +} + +// FIXME runtime mandates that /dev/ptmx should be bind mount from host - why ? +// `man 2 mount` | devpts +// ` To use this option effectively, /dev/ptmx must be a symbolic link to pts/ptmx. +// See Documentation/filesystems/devpts.txt in the Linux kernel source tree for details.` +var ( + EssentialDevices = []specs.LinuxDevice{ + specs.LinuxDevice{Type: "c", Major: 1, Minor: 3, FileMode: modep(0666), Path: "/dev/null"}, + specs.LinuxDevice{Type: "c", Major: 1, Minor: 5, FileMode: modep(0666), Path: "/dev/zero"}, + specs.LinuxDevice{Type: "c", Major: 1, Minor: 7, FileMode: modep(0666), Path: "/dev/full"}, + specs.LinuxDevice{Type: "c", Major: 1, Minor: 8, FileMode: modep(0666), Path: "/dev/random"}, + specs.LinuxDevice{Type: "c", Major: 1, Minor: 9, FileMode: modep(0666), Path: "/dev/urandom"}, + specs.LinuxDevice{Type: "c", Major: 5, Minor: 0, FileMode: modep(0666), Path: "/dev/tty"}, + } + + EssentialDevicesAllow = []specs.LinuxDeviceCgroup{ + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(1), Minor: int64p(3), Access: "rwm"}, // null + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(1), Minor: int64p(5), Access: "rwm"}, // zero + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(1), Minor: int64p(7), Access: "rwm"}, // full + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(1), Minor: int64p(8), Access: "rwm"}, // random + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(1), Minor: int64p(9), Access: "rwm"}, // urandom + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(5), Minor: int64p(0), Access: "rwm"}, // tty + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(5), Minor: int64p(2), Access: "rwm"}, // ptmx + specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: int64p(88), Access: "rwm"}, // /dev/pts/{n} + } +) + +// AllowEssentialDevices adds and allows access to EssentialDevices which are required by the +// [runtime spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices) +func AllowEssentialDevices(spec *specs.Spec) error { + for _, dev := range EssentialDevices { + exist, err := IsDeviceEnabled(spec, dev) + if err != nil { + return err + } + if !exist { + spec.Linux.Devices = append(spec.Linux.Devices, dev) + } + } + + for _, perm := range EssentialDevicesAllow { + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, perm) + } + return nil +} + +// IsDeviceEnabled checks if the LinuxDevice dev is enabled in the Spec spec. +// An error is returned if the device Path matches and Type, Major or Minor don't match. +func IsDeviceEnabled(spec *specs.Spec, dev specs.LinuxDevice) (bool, error) { + for _, d := range spec.Linux.Devices { + if d.Path == dev.Path { + if d.Type != dev.Type { + return false, fmt.Errorf("%s type mismatch (expected %s but was %s)", dev.Path, dev.Type, d.Type) + } + if d.Major != dev.Major { + return false, fmt.Errorf("%s major number mismatch (expected %d but was %d)", dev.Path, dev.Major, d.Major) + } + if d.Minor != dev.Minor { + return false, fmt.Errorf("%s major number mismatch (expected %d but was %d)", dev.Path, dev.Major, d.Major) + } + return true, nil + } + } + return false, nil +} + // ReadSpecJSON reads the JSON encoded OCI // spec from the given path. // This is a convenience function for the cli. diff --git a/runtime.go b/runtime.go index cad5f9d7..0496cec7 100644 --- a/runtime.go +++ b/runtime.go @@ -10,10 +10,10 @@ import ( "time" "github.com/creack/pty" - "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" + "gopkg.in/lxc/go-lxc.v2" ) const ( @@ -138,7 +138,6 @@ func (rt *Runtime) Init() error { if !lxc.VersionAtLeast(4, 0, 5) { rt.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } - return nil } From c1660ac399b74582e06d9a5eceb271457d5114a8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 12:32:34 +0200 Subject: [PATCH 310/373] Refactor device handling. Check for CAP_MKNOD using gocapability. Signed-off-by: Ruben Jenster --- create.go | 38 +++++++++++++++++++++++--------------- go.mod | 1 + go.sum | 2 ++ runtime.go | 24 ++++++++++++++++++++---- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/create.go b/create.go index 5fea8e17..a73483e1 100644 --- a/create.go +++ b/create.go @@ -99,7 +99,7 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure init: %w", err) } - if !rt.privileged { + if os.Getuid() != 0 { // ensure user namespace is enabled if !isNamespaceEnabled(c.Spec, specs.UserNamespace) { rt.Log.Warn().Msg("unprivileged runtime - enabling user namespace") @@ -151,7 +151,7 @@ func configureContainer(rt *Runtime, c *Container) error { return fmt.Errorf("failed to configure capabilities: %w", err) } } else { - rt.Log.Warn().Msg("capabilities feature is disabled - running with full privileges") + rt.Log.Warn().Msg("capabilities feature is disabled - running with runtime privileges") } // make sure autodev is disabled @@ -159,34 +159,42 @@ func configureContainer(rt *Runtime, c *Container) error { return err } - if err := ensureDefaultDevices(c.Spec); err != nil { + // NOTE crio can add devices (through the config) but this does not work for privileged containers. + // See https://github.com/cri-o/cri-o/blob/a705db4c6d04d7c14a4d59170a0ebb4b30850675/server/container_create_linux.go#L45 + // File an issue on cri-o (at least for support) + if err := specki.AllowEssentialDevices(c.Spec); err != nil { return err } - if rt.privileged { - // devices are created with mknod in lxcri-hook - if err := createDeviceFile(c.RuntimePath("devices.txt"), c.Spec); err != nil { - return fmt.Errorf("failed to create devices.txt: %w", err) - } - - } else { - // if running as non-root bind mount devices, because user can not execute mknod + if !rt.hasCapability("mknod") { + rt.Log.Info().Msg("runtime does not have capability CAP_MKNOD") + // CAP_MKNOD is not granted `man capabilities` + // Bind mount devices instead. newMounts := make([]specs.Mount, 0, len(c.Spec.Mounts)+len(c.Spec.Linux.Devices)) for _, m := range c.Spec.Mounts { if m.Destination == "/dev" { - rt.Log.Info().Msg("unprivileged runtime - removing /dev mount") + rt.Log.Info().Msg("removing old /dev mount") continue } newMounts = append(newMounts, m) } - rt.Log.Info().Msg("unprivileged runtime - bind mount devices") + c.Spec.Mounts = append(c.Spec.Mounts, + specs.Mount{ + Destination: "/dev", Source: "tmpfs", Type: "tmpfs", + Options: []string{"rw", "nosuid", "noexec", "relatime"}, + }, + ) + rt.Log.Info().Msg("bind mount devices") for _, device := range c.Spec.Linux.Devices { newMounts = append(newMounts, - specs.Mount{Destination: device.Path, Source: device.Path, Type: "bind", Options: []string{"bind", "create=file"}}, + specs.Mount{ + Destination: device.Path, Source: device.Path, Type: "bind", + Options: []string{"bind", "create=file"}, + }, ) } - c.Spec.Mounts = newMounts + c.Spec.Linux.Devices = nil } if err := writeMasked(c.RuntimePath("masked.txt"), c); err != nil { diff --git a/go.mod b/go.mod index be406972..4b5a8199 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/creack/pty v1.1.11 github.com/davecgh/go-spew v1.1.1 // indirect + github.com/drachenfels-de/gocapability v0.0.0-20210413092208-755d79b01352 github.com/kr/pretty v0.2.1 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/rs/zerolog v1.20.0 diff --git a/go.sum b/go.sum index 117c0bf0..a0aa7537 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/drachenfels-de/gocapability v0.0.0-20210413092208-755d79b01352 h1:Qx+y7zFy52uzSTCYC3gUGHdbXkaY3ypP9bvgIjOlhfw= +github.com/drachenfels-de/gocapability v0.0.0-20210413092208-755d79b01352/go.mod h1:BhJFa1j1CrR5IPQo8i5+93q+HAAN2gaJDmNMLL3cPAU= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= diff --git a/runtime.go b/runtime.go index 0496cec7..6351ae60 100644 --- a/runtime.go +++ b/runtime.go @@ -10,6 +10,7 @@ import ( "time" "github.com/creack/pty" + "github.com/drachenfels-de/gocapability/capability" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" @@ -94,14 +95,22 @@ type Runtime struct { // Environment passed to `lxcri-start` env []string - // privileged is set by Runtime.Init if user has root privileges. - privileged bool + caps capability.Capabilities } func (rt *Runtime) libexec(name string) string { return filepath.Join(rt.LibexecDir, name) } +func (rt *Runtime) hasCapability(s string) bool { + c, exist := capability.Parse(s) + if !exist { + rt.Log.Warn().Msgf("undefined capability %q", s) + return false + } + return rt.caps.Get(capability.EFFECTIVE, c) +} + // Init initializes the runtime instance. // It creates required directories and checks the hosts system configuration. // Unsupported runtime features are disabled and a warning message is logged. @@ -115,11 +124,18 @@ func (rt *Runtime) Init() error { return errorf("failed to 'chmod 0777 %s': %w", err) } - rt.privileged = os.Getuid() == 0 + caps, err := capability.NewPid2(0) + if err != nil { + return errorf("failed to create capabilities object: %w", err) + } + if err := caps.Load(); err != nil { + return errorf("failed to load process capabilities: %w", err) + } + rt.caps = caps rt.keepEnv("HOME", "XDG_RUNTIME_DIR", "PATH") - err := canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) + err = canExecute(rt.libexec(ExecStart), rt.libexec(ExecHook), rt.libexec(ExecInit)) if err != nil { return errorf("access check failed: %w", err) } From 0e7bf347c4da6467b4750308810f7c055fed9302 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 14:21:02 +0200 Subject: [PATCH 311/373] Remove custom Hooks in favor of OCI hooks. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook/main.go | 2 +- container.go | 2 -- create.go | 33 +++++++++++++-------------------- runtime.go | 13 ------------- 4 files changed, 14 insertions(+), 36 deletions(-) diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 9c9847f2..89ba5b21 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -60,7 +60,7 @@ func run(ctx context.Context, env *Env) error { } if len(hooksToRun) == 0 { - return fmt.Errorf("no hooks defined for %q", env.Type) + return fmt.Errorf("no OCI hooks defined for lxc hook %q", env.Type) } // need to deserialize it to set the current specs.ContainerState diff --git a/container.go b/container.go index bcc0abc4..785d3957 100644 --- a/container.go +++ b/container.go @@ -47,8 +47,6 @@ type ContainerConfig struct { // Log is the container Logger Log zerolog.Logger `json:"-"` - - Hooks `json:"-"` } // ConfigFilePath returns the path to the liblxc config file. diff --git a/create.go b/create.go index a73483e1..bcb9f371 100644 --- a/create.go +++ b/create.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "os" - "os/exec" "path/filepath" "strings" @@ -33,25 +32,6 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to create container: %w", err) } - if rt.OnCreate != nil { - rt.OnCreate(ctx, c) - } - if c.OnCreate != nil { - c.OnCreate(ctx, c) - } - - if cfg.Spec.Hooks != nil { - for i, hook := range cfg.Spec.Hooks.CreateRuntime { - cmd := exec.Command(hook.Path, hook.Args...) - cmd.Env = hook.Env - out, err := cmd.CombinedOutput() - if err != nil { - rt.Log.Error().Msgf("failed to run hook CreateRuntime[%d]: %s", i, err) - } - println(string(out)) - } - } - if err := configureContainer(rt, c); err != nil { return c, errorf("failed to configure container: %w", err) } @@ -64,6 +44,19 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, err } + err = specki.EncodeJSONFile(c.RuntimePath("hooks.json"), cfg.Spec.Hooks, os.O_EXCL|os.O_CREATE, 0440) + if err != nil { + return c, err + } + state, err := c.State() + if err != nil { + return c, err + } + err = specki.EncodeJSONFile(c.RuntimePath("state.json"), state, os.O_EXCL|os.O_CREATE, 0440) + if err != nil { + return c, err + } + if err := rt.runStartCmd(ctx, c); err != nil { return c, errorf("failed to run container process: %w", err) } diff --git a/runtime.go b/runtime.go index 6351ae60..45ab5391 100644 --- a/runtime.go +++ b/runtime.go @@ -52,15 +52,6 @@ type RuntimeFeatures struct { // by runtime and container (non-OCI) callback hooks. type HookFunc func(ctx context.Context, c *Container) error -// Hooks are callback functions executed within the container lifecycle. -type Hooks struct { - // OnCreate is called right after creation of container runtime directory - // and descriptor, but before the liblxc 'config' file is written. - // At this point it's possible to add files to the container runtime directory - // and modify the ContainerConfig accordingly. - OnCreate HookFunc -} - // Runtime is a factory for creating and managing containers. // The exported methods of Runtime are required to implement the // OCI container runtime interface spec (CRI). @@ -87,10 +78,6 @@ type Runtime struct { // Featuress are runtime (security) features that apply to all containers // created by the runtime. Features RuntimeFeatures - // Hooks contains all callback functions supported by the runtime. - // These hooks are different from the hooks that are - // defined within the OCI runtime spec. - Hooks `json:"-"` // Environment passed to `lxcri-start` env []string From 821a4b8fad0a87b08060bbc9d3215fd79d4b42e5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 14:24:25 +0200 Subject: [PATCH 312/373] Makefile: Remove go build '-a' flag (force rebuilding). Signed-off-by: Ruben Jenster --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2e4f6d6e..ba39fd76 100644 --- a/Makefile +++ b/Makefile @@ -31,13 +31,13 @@ fmt: .PHONY: test test: build - go build -a ./cmd/lxcri-test + go build ./cmd/lxcri-test go test --count 1 -v ./... build: $(BINS) $(LIBEXEC_BINS) lxcri: go.mod $(GO_SRC) Makefile - go build -a -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri + go build -ldflags '$(LDFLAGS)' -o $@ ./cmd/lxcri lxcri-start: cmd/lxcri-start/lxcri-start.c $(CC) -Werror -Wpedantic -o $@ $? $$(pkg-config --libs --cflags lxc) From 6d41815cfa74c61c7100bc9137a9e90732fb958c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 17:00:30 +0200 Subject: [PATCH 313/373] (WIP) Working OCI hooks implementation. Signed-off-by: Ruben Jenster --- .gitignore | 1 + Makefile | 7 ++++-- cmd/lxcri-hook-builtin/main.go | 16 ++++++++++++ cmd/lxcri-hook/main.go | 9 +++---- container.go | 18 -------------- create.go | 42 ++++++++++++++++--------------- pkg/specki/specki.go | 32 +++++++++++++++++++++--- runtime.go | 45 ++++++++++++++++++++++++++++++---- runtime_test.go | 6 ++++- 9 files changed, 122 insertions(+), 54 deletions(-) create mode 100644 cmd/lxcri-hook-builtin/main.go diff --git a/.gitignore b/.gitignore index f23531e8..c1df613a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /lxcri-init /lxcri-hook /lxcri-test +/lxcri-hook-builtin .stacker/ diff --git a/Makefile b/Makefile index ba39fd76..47c9321e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ COMMIT_HASH = $(shell git describe --always --tags --long) COMMIT = $(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH)) BINS := lxcri -LIBEXEC_BINS := lxcri-start lxcri-init lxcri-hook +LIBEXEC_BINS := lxcri-start lxcri-init lxcri-hook lxcri-hook-builtin # Installation prefix for BINS PREFIX ?= /usr/local export PREFIX @@ -48,7 +48,10 @@ lxcri-init: cmd/lxcri-init/lxcri-init.c ! ldd $@ 2>/dev/null lxcri-hook: go.mod $(GO_SRC) Makefile - go build -o $@ ./cmd/lxcri-hook + go build -o $@ ./cmd/$@ + +lxcri-hook-builtin: go.mod $(GO_SRC) Makefile + go build -o $@ ./cmd/$@ install: build mkdir -p $(PREFIX)/bin diff --git a/cmd/lxcri-hook-builtin/main.go b/cmd/lxcri-hook-builtin/main.go new file mode 100644 index 00000000..93bc0e75 --- /dev/null +++ b/cmd/lxcri-hook-builtin/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "github.com/drachenfels-de/lxcri/pkg/specki" + "os" +) + +func main() { + state, spec, err := specki.InitHook(os.Stdin) + if err != nil { + panic(err) + } + fmt.Printf("----> %s %#v\n", os.Args[0], state) + fmt.Printf("----> %s %#v\\n", os.Args[0], spec) +} diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 89ba5b21..aa88f727 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -47,8 +47,7 @@ func run(ctx context.Context, env *Env) error { // TODO save hooks to hooks.json var hooks specs.Hooks - hooksPath := filepath.Join(runtimeDir, "hooks.json") - err := specki.DecodeJSONFile(hooksPath, &hooks) + err := specki.DecodeJSONFile(filepath.Join(runtimeDir, "hooks.json"), &hooks) if err != nil { return err } @@ -65,14 +64,14 @@ func run(ctx context.Context, env *Env) error { // need to deserialize it to set the current specs.ContainerState var state specs.State - statePath := filepath.Join(runtimeDir, "state.json") - err = specki.DecodeJSONFile(statePath, &hooks) + err = specki.DecodeJSONFile(filepath.Join(runtimeDir, "state.json"), &state) if err != nil { return err } state.Status = status - return specki.RunHooks(ctx, &state, hooksToRun) + fmt.Printf("running OCI hooks for lxc hook %q", env.Type) + return specki.RunHooks(ctx, &state, hooksToRun, true) } // https://github.com/opencontainers/runtime-spec/blob/master/specs-go/state.go diff --git a/container.go b/container.go index 785d3957..574ef066 100644 --- a/container.go +++ b/container.go @@ -339,24 +339,6 @@ func (c *Container) Release() error { return c.LinuxContainer.Release() } -// From OCI runtime spec -// "Note that resources associated with the container, but not -// created by this container, MUST NOT be deleted." -// The *lxc.Container is created with `rootfs.managed=0`, -// so calling *lxc.Container.Destroy will not delete container resources. -func (c *Container) destroy() error { - if err := c.LinuxContainer.Destroy(); err != nil { - return fmt.Errorf("failed to destroy container: %w", err) - } - if c.CgroupDir != "" { - err := deleteCgroup(c.CgroupDir) - if err != nil && !os.IsNotExist(err) { - return err - } - } - return os.RemoveAll(c.RuntimePath()) -} - func (c *Container) start(ctx context.Context) error { done := make(chan error) go func() { diff --git a/create.go b/create.go index bcb9f371..f4cff344 100644 --- a/create.go +++ b/create.go @@ -52,7 +52,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container if err != nil { return c, err } - err = specki.EncodeJSONFile(c.RuntimePath("state.json"), state, os.O_EXCL|os.O_CREATE, 0440) + err = specki.EncodeJSONFile(c.RuntimePath("state.json"), state.SpecState, os.O_EXCL|os.O_CREATE, 0440) if err != nil { return c, err } @@ -190,15 +190,7 @@ func configureContainer(rt *Runtime, c *Container) error { c.Spec.Linux.Devices = nil } - if err := writeMasked(c.RuntimePath("masked.txt"), c); err != nil { - return fmt.Errorf("failed to create masked.txt: %w", err) - } - - // pass context information as environment variables to hook scripts - if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { - return err - } - if err := c.SetConfigItem("lxc.hook.mount", rt.libexec(ExecHook)); err != nil { + if err := configureHooks(rt, c); err != nil { return err } @@ -318,21 +310,31 @@ func configureCapabilities(c *Container) error { return c.SetConfigItem("lxc.cap.keep", keepCaps) } -func writeMasked(dst string, c *Container) error { - // #nosec - if c.Spec.Linux.MaskedPaths == nil { +// NOTE keep in sync with cmd/lxcri-hook#ociHooksAndState +func configureHooks(rt *Runtime, c *Container) error { + if c.Spec.Hooks == nil { return nil } - f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) - if err != nil { + + // pass context information as environment variables to hook scripts + if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { return err } - for _, p := range c.Spec.Linux.MaskedPaths { - _, err = fmt.Fprintln(f, p) - if err != nil { - f.Close() + + if len(c.Spec.Hooks.Prestart) > 0 || len(c.Spec.Hooks.CreateRuntime) > 0 { + if err := c.SetConfigItem("lxc.hook.pre-mount", rt.libexec(ExecHook)); err != nil { + return err + } + } + if len(c.Spec.Hooks.CreateContainer) > 0 { + if err := c.SetConfigItem("lxc.hook.mount", rt.libexec(ExecHook)); err != nil { return err } } - return f.Close() + if len(c.Spec.Hooks.StartContainer) > 0 { + if err := c.SetConfigItem("lxc.hook.start", rt.libexec(ExecHook)); err != nil { + return err + } + } + return nil } diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index d7684314..346d4901 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -11,6 +11,7 @@ import ( "io" "os" "os/exec" + "path/filepath" "time" "github.com/opencontainers/runtime-spec/specs-go" @@ -39,15 +40,22 @@ func UnmapContainerID(id uint32, idmaps []specs.LinuxIDMapping) uint32 { // RunHooks calls RunHook for each of the given runtime hooks. // The given runtime state is serialized as JSON and passed to each RunHook call. -func RunHooks(ctx context.Context, state *specs.State, hooks []specs.Hook) error { +func RunHooks(ctx context.Context, state *specs.State, hooks []specs.Hook, continueOnError bool) error { + if len(hooks) == 0 { + return nil + } stateJSON, err := json.Marshal(state) if err != nil { return fmt.Errorf("failed to serialize spec state: %w", err) } for i, h := range hooks { fmt.Printf("running hook[%d] path:%s\n", i, h.Path) - if err := RunHook(ctx, stateJSON, h); err != nil { - return err + err := RunHook(ctx, stateJSON, h) + if err != nil { + fmt.Printf("hook[%d] failed: %s\n", i, err) + if !continueOnError { + return err + } } } return nil @@ -65,6 +73,8 @@ func RunHook(ctx context.Context, stateJSON []byte, hook specs.Hook) error { } cmd := exec.CommandContext(ctx, hook.Path, hook.Args...) cmd.Env = hook.Env + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout in, err := cmd.StdinPipe() if err != nil { return fmt.Errorf("failed to get stdin pipe: %w", err) @@ -278,3 +288,19 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { proc.Cwd = "/" return proc } + +func ReadSpecState(r io.Reader) (*specs.State, error) { + state := new(specs.State) + dec := json.NewDecoder(r) + err := dec.Decode(state) + return state, err +} + +func InitHook(r io.Reader) (*specs.State, *specs.Spec, error) { + state, err := ReadSpecState(r) + if err != nil { + return nil, nil, err + } + spec, err := ReadSpecJSON(filepath.Join(state.Bundle, "config.json")) + return state, spec, err +} diff --git a/runtime.go b/runtime.go index 45ab5391..7aa871a9 100644 --- a/runtime.go +++ b/runtime.go @@ -11,6 +11,7 @@ import ( "github.com/creack/pty" "github.com/drachenfels-de/gocapability/capability" + "github.com/drachenfels-de/lxcri/pkg/specki" "github.com/opencontainers/runtime-spec/specs-go" "github.com/rs/zerolog" "golang.org/x/sys/unix" @@ -28,7 +29,8 @@ var ( // ExecStart starts the liblxc monitor process, similar to lxc-start ExecStart = "lxcri-start" // ExecHook is run as liblxc hook and creates additional devices and remounts masked paths. - ExecHook = "lxcri-hook" + ExecHook = "lxcri-hook" + ExecHookBuiltin = "lxcri-hook-builtin" // ExecInit is the container init process that execs the container process. ExecInit = "lxcri-init" ) @@ -232,7 +234,19 @@ func (rt *Runtime) Start(ctx context.Context, c *Container) error { return fmt.Errorf("invalid container state. expected %q, but was %q", specs.StateCreated, state.SpecState.Status) } - return c.start(ctx) + err = c.start(ctx) + if err != nil { + return err + } + + if c.Spec.Hooks != nil { + state, err := c.State() + if err != nil { + return errorf("failed to get container state: %w", err) + } + specki.RunHooks(ctx, &state.SpecState, c.Spec.Hooks.Poststart, true) + } + return nil } func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { @@ -366,6 +380,7 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e } } + // FIXME move this to lxcri-hook ? if c.CgroupDir != "" { // In rare cases processes might escape from kill. // This could happens if the container does not use pid_namespaces. @@ -377,8 +392,28 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e rt.Log.Info().Msg("cgroup drained") } - if err := c.destroy(); err != nil { - return errorf("failed to destroy container: %w", err) + // From OCI runtime spec + // "Note that resources associated with the container, but not + // created by this container, MUST NOT be deleted." + // The *lxc.Container is created with `rootfs.managed=0`, + // so calling *lxc.Container.Destroy will not delete container resources. + if err := c.LinuxContainer.Destroy(); err != nil { + return fmt.Errorf("failed to destroy container: %w", err) } - return nil + if c.CgroupDir != "" { + err := deleteCgroup(c.CgroupDir) + if err != nil && !os.IsNotExist(err) { + return err + } + } + + if c.Spec.Hooks != nil { + state, err := c.State() + if err != nil { + return errorf("failed to get container state: %w", err) + } + specki.RunHooks(ctx, &state.SpecState, c.Spec.Hooks.Poststart, true) + } + + return os.RemoveAll(c.RuntimePath()) } diff --git a/runtime_test.go b/runtime_test.go index fddd24e1..333573bc 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -186,7 +186,11 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { "LXCRI_RUNTIME_ROOT=" + rt.Root, "LXCRI_HOOK_TYPE=" + string(HookCreateRuntime), }, - }) + }, + specs.Hook{ + Path: "/usr/local/libexec/lxcri/lxcri-hook-builtin", + }, + ) c, err := rt.Create(ctx, cfg) require.NoError(t, err) From 875000e68669e35296472e72ac7ffd6e3d54ddb2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 21:05:05 +0200 Subject: [PATCH 314/373] Add missing go doc. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook/hooks.go | 9 ++++++--- pkg/specki/specki.go | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmd/lxcri-hook/hooks.go b/cmd/lxcri-hook/hooks.go index 00857a58..bbe99063 100644 --- a/cmd/lxcri-hook/hooks.go +++ b/cmd/lxcri-hook/hooks.go @@ -6,8 +6,10 @@ import ( "strings" ) +// HookType is the liblxc hook type. type HookType string +// List of liblxc hook types. const ( HookPreStart HookType = "pre-start" HookPreMount = "pre-mount" @@ -52,12 +54,13 @@ type Env struct { var namespaces = []string{"cgroup", "ipc", "mnt", "net", "pid", "time", "user", "uts"} +// ErrEnv is the error returned by LoadEnv +// if the LXC_HOOK_TYPE environment variable is not set. var ErrEnv = errors.New("LXC_HOOK_TYPE environment variable is not set") -// Env parses all environment variables available in liblxc hooks, +// LoadEnv parses all liblxc hook environment variables, // and returns the parsed values in an Env struct. -// Env only parses the environment if`LXC_HOOK_TYPE` is set, -// and will return nil otherwise. +// If `LXC_HOOK_TYPE` is not set ErrEnv will be returned. // NOTE The environment variables in liblxc hooks are all prefixed with LXC_. func LoadEnv() (*Env, error) { hookType, exist := os.LookupEnv("LXC_HOOK_TYPE") diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 346d4901..4ba06f18 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -289,15 +289,19 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { return proc } -func ReadSpecState(r io.Reader) (*specs.State, error) { +// ReadSpecStateJSON parses the JSON encoded specs.State from the given reader. +func ReadSpecStateJSON(r io.Reader) (*specs.State, error) { state := new(specs.State) dec := json.NewDecoder(r) err := dec.Decode(state) return state, err } +// InitHook is a convenience function for OCI hooks. +// It parses specs.State from the given reader and +// loads specs.Spec from the specs.State.Bundle path. func InitHook(r io.Reader) (*specs.State, *specs.Spec, error) { - state, err := ReadSpecState(r) + state, err := ReadSpecStateJSON(r) if err != nil { return nil, nil, err } From e197bba7d2e516d1809b211d196598518ca692fc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 13 Apr 2021 21:32:54 +0200 Subject: [PATCH 315/373] Allow others to read spec.json hooks.json and state.json This is required if user namespaces are used and the container process user is different from the runtime user. Another option would be to chown the files to the container process user ID. This should be possible with lxc-usernsexec or alike. Signed-off-by: Ruben Jenster --- create.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/create.go b/create.go index f4cff344..599ab027 100644 --- a/create.go +++ b/create.go @@ -39,12 +39,12 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container // Seralize the modified spec.Spec separately, to make it available for // runtime hooks. specPath := c.RuntimePath(BundleConfigFile) - err := specki.EncodeJSONFile(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE, 0440) + err := specki.EncodeJSONFile(specPath, cfg.Spec, os.O_EXCL|os.O_CREATE, 0444) if err != nil { return c, err } - err = specki.EncodeJSONFile(c.RuntimePath("hooks.json"), cfg.Spec.Hooks, os.O_EXCL|os.O_CREATE, 0440) + err = specki.EncodeJSONFile(c.RuntimePath("hooks.json"), cfg.Spec.Hooks, os.O_EXCL|os.O_CREATE, 0444) if err != nil { return c, err } @@ -52,7 +52,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container if err != nil { return c, err } - err = specki.EncodeJSONFile(c.RuntimePath("state.json"), state.SpecState, os.O_EXCL|os.O_CREATE, 0440) + err = specki.EncodeJSONFile(c.RuntimePath("state.json"), state.SpecState, os.O_EXCL|os.O_CREATE, 0444) if err != nil { return c, err } From ae34b8f2feb25d2552780587c9be828a68e301b8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 14 Apr 2021 11:38:57 +0200 Subject: [PATCH 316/373] Use rootfs path from spec as rootfs mountpoint. Use the spec rootfs path as lxc.rootfs.path and lxc.rootfs.mount. This is required for OCI hooks to find and operate on the rootfs. Signed-off-by: Ruben Jenster --- create.go | 8 ++++++-- pkg/specki/specki.go | 20 +++++++++++++++----- runtime.go | 10 ---------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/create.go b/create.go index 599ab027..e7caa085 100644 --- a/create.go +++ b/create.go @@ -237,11 +237,15 @@ func configureContainer(rt *Runtime, c *Container) error { } func configureRootfs(rt *Runtime, c *Container) error { - if err := c.SetConfigItem("lxc.rootfs.path", c.Spec.Root.Path); err != nil { + rootfs := c.Spec.Root.Path + if !filepath.IsAbs(rootfs) { + rootfs = filepath.Join(c.BundlePath, rootfs) + } + if err := c.SetConfigItem("lxc.rootfs.path", rootfs); err != nil { return err } - if err := c.SetConfigItem("lxc.rootfs.mount", rt.rootfsMount); err != nil { + if err := c.SetConfigItem("lxc.rootfs.mount", rootfs); err != nil { return err } diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 4ba06f18..faa53dd0 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -300,11 +300,21 @@ func ReadSpecStateJSON(r io.Reader) (*specs.State, error) { // InitHook is a convenience function for OCI hooks. // It parses specs.State from the given reader and // loads specs.Spec from the specs.State.Bundle path. -func InitHook(r io.Reader) (*specs.State, *specs.Spec, error) { - state, err := ReadSpecStateJSON(r) +func InitHook(r io.Reader) (rootfs string, state *specs.State, spec *specs.Spec, err error) { + state, err = ReadSpecStateJSON(r) if err != nil { - return nil, nil, err + return } - spec, err := ReadSpecJSON(filepath.Join(state.Bundle, "config.json")) - return state, spec, err + spec, err = ReadSpecJSON(filepath.Join(state.Bundle, "config.json")) + + // quote from https://github.com/opencontainers/runtime-spec/blob/master/config.md#root + // > On POSIX platforms, path is either an absolute path or a relative path to the bundle. + // > For example, with a bundle at /to/bundle and a root filesystem at /to/bundle/rootfs, + // > the path value can be either /to/bundle/rootfs or rootfs. + // > The value SHOULD be the conventional rootfs. + rootfs = spec.Root.Path + if !filepath.IsAbs(rootfs) { + rootfs = filepath.Join(state.Bundle, rootfs) + } + return } diff --git a/runtime.go b/runtime.go index 7aa871a9..6c45ef7e 100644 --- a/runtime.go +++ b/runtime.go @@ -65,9 +65,6 @@ type Runtime struct { // Directories for containers created by the runtime // are created within this directory. Root string - // rootfsMount is the directory where liblxc recursively binds - // the container rootfs before pivoting. - rootfsMount string // Use systemd encoded cgroup path (from crio-o/conmon) // is true if /etc/crio/crio.conf#cgroup_manager = "systemd" SystemdCgroup bool @@ -105,13 +102,6 @@ func (rt *Runtime) hasCapability(s string) bool { // Unsupported runtime features are disabled and a warning message is logged. // Init must be called once for a runtime instance before calling any other method. func (rt *Runtime) Init() error { - rt.rootfsMount = filepath.Join(rt.Root, ".rootfs") - if err := os.MkdirAll(rt.rootfsMount, 0777); err != nil { - return errorf("failed to create directory for rootfs mount %s: %w", rt.rootfsMount, err) - } - if err := os.Chmod(rt.rootfsMount, 0777); err != nil { - return errorf("failed to 'chmod 0777 %s': %w", err) - } caps, err := capability.NewPid2(0) if err != nil { From 769dc0b54359733205c7e14a9254ec797759748a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 14 Apr 2021 11:53:57 +0200 Subject: [PATCH 317/373] Add Spec.Hooks to runtime and prepend to container hooks. Signed-off-by: Ruben Jenster --- create.go | 27 +++++++++++++++++++++++++-- runtime.go | 6 ++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/create.go b/create.go index e7caa085..f0121adf 100644 --- a/create.go +++ b/create.go @@ -316,10 +316,33 @@ func configureCapabilities(c *Container) error { // NOTE keep in sync with cmd/lxcri-hook#ociHooksAndState func configureHooks(rt *Runtime, c *Container) error { - if c.Spec.Hooks == nil { - return nil + + // prepend runtime OCI hooks to container hooks + hooks := rt.Hooks + + if c.Spec.Hooks != nil { + if len(c.Spec.Hooks.Prestart) > 0 { + hooks.Prestart = append(hooks.Prestart, c.Spec.Hooks.Prestart...) + } + if len(c.Spec.Hooks.CreateRuntime) > 0 { + hooks.CreateRuntime = append(hooks.CreateRuntime, c.Spec.Hooks.CreateRuntime...) + } + if len(c.Spec.Hooks.CreateContainer) > 0 { + hooks.CreateContainer = append(hooks.CreateContainer, c.Spec.Hooks.CreateContainer...) + } + if len(c.Spec.Hooks.StartContainer) > 0 { + hooks.StartContainer = append(hooks.StartContainer, c.Spec.Hooks.StartContainer...) + } + if len(c.Spec.Hooks.Poststart) > 0 { + hooks.Poststart = append(hooks.Poststart, c.Spec.Hooks.Poststart...) + } + if len(c.Spec.Hooks.Poststop) > 0 { + hooks.Poststop = append(hooks.Poststop, c.Spec.Hooks.Poststop...) + } } + c.Spec.Hooks = &hooks + // pass context information as environment variables to hook scripts if err := c.SetConfigItem("lxc.hook.version", "1"); err != nil { return err diff --git a/runtime.go b/runtime.go index 6c45ef7e..d1b37518 100644 --- a/runtime.go +++ b/runtime.go @@ -50,10 +50,6 @@ type RuntimeFeatures struct { CgroupDevices bool } -// HookFunc defines the function type that must be implemented -// by runtime and container (non-OCI) callback hooks. -type HookFunc func(ctx context.Context, c *Container) error - // Runtime is a factory for creating and managing containers. // The exported methods of Runtime are required to implement the // OCI container runtime interface spec (CRI). @@ -82,6 +78,8 @@ type Runtime struct { env []string caps capability.Capabilities + + specs.Hooks } func (rt *Runtime) libexec(name string) string { From 0dfbe25dbe25d2ca9a347016a3fb2809cbbd9f8a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Wed, 14 Apr 2021 11:55:27 +0200 Subject: [PATCH 318/373] Add hook (OCI hook) to create devices and mask paths. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook-builtin/main.go | 72 ++++++++++++++++++++++++++++++++-- runtime.go | 4 ++ runtime_test.go | 4 -- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/cmd/lxcri-hook-builtin/main.go b/cmd/lxcri-hook-builtin/main.go index 93bc0e75..607a4f4d 100644 --- a/cmd/lxcri-hook-builtin/main.go +++ b/cmd/lxcri-hook-builtin/main.go @@ -2,15 +2,79 @@ package main import ( "fmt" - "github.com/drachenfels-de/lxcri/pkg/specki" "os" + "path/filepath" + + "github.com/drachenfels-de/lxcri/pkg/specki" + "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" ) func main() { - state, spec, err := specki.InitHook(os.Stdin) + rootfs, _, spec, err := specki.InitHook(os.Stdin) if err != nil { panic(err) } - fmt.Printf("----> %s %#v\n", os.Args[0], state) - fmt.Printf("----> %s %#v\\n", os.Args[0], spec) + + for _, dev := range spec.Linux.Devices { + if err := createDevice(rootfs, dev); err != nil { + err := fmt.Errorf("failed to create device %s: %w", dev.Path, err) + fmt.Fprintln(os.Stderr, err.Error()) + } + } + + for _, p := range spec.Linux.MaskedPaths { + if err := maskPath(filepath.Join(rootfs, p)); err != nil { + err := fmt.Errorf("failed to mask path %s: %w", p, err) + fmt.Fprintln(os.Stderr, err.Error()) + } + } +} + +func getDeviceMode(dev specs.LinuxDevice) (uint32, error) { + var fileType uint32 + + switch dev.Type { + case "b": + fileType = unix.S_IFBLK + case "c": + fileType = unix.S_IFCHR + case "p": + fileType = unix.S_IFIFO + default: + return 0, fmt.Errorf("unsupported device type: %s", dev.Type) + } + + var perm uint32 = 0666 + if dev.FileMode == nil { + perm = uint32(*dev.FileMode) + } + return (fileType | perm), nil +} + +func createDevice(rootfs string, dev specs.LinuxDevice) error { + mode, err := getDeviceMode(dev) + if err != nil { + return err + } + + // ignored by unix.Mknod if dev.Type is not unix.S_IFBLK or unix.S_IFCHR + mkdev := int(unix.Mkdev(uint32(dev.Major), uint32(dev.Minor))) + + err = unix.Mknod(filepath.Join(rootfs, dev.Path), mode, mkdev) + if err != nil { + return fmt.Errorf("mknod failed: %s", err) + } + return nil +} + +func maskPath(p string) error { + err := unix.Mount("/dev/null", p, "", unix.MS_BIND, "") + if os.IsNotExist(err) { + return nil + } + if err == unix.ENOTDIR { + return unix.Mount("tmpfs", p, "tmpfs", unix.MS_RDONLY, "") + } + return err } diff --git a/runtime.go b/runtime.go index d1b37518..bf5afa53 100644 --- a/runtime.go +++ b/runtime.go @@ -131,6 +131,10 @@ func (rt *Runtime) Init() error { if !lxc.VersionAtLeast(4, 0, 5) { rt.Log.Warn().Msgf("liblxc runtime version >= 4.0.5 is recommended (was %s)", lxc.Version()) } + + rt.Hooks.CreateContainer = []specs.Hook{ + specs.Hook{Path: rt.libexec(ExecHookBuiltin)}, + } return nil } diff --git a/runtime_test.go b/runtime_test.go index 333573bc..12f7b5a3 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -187,11 +187,7 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { "LXCRI_HOOK_TYPE=" + string(HookCreateRuntime), }, }, - specs.Hook{ - Path: "/usr/local/libexec/lxcri/lxcri-hook-builtin", - }, ) - c, err := rt.Create(ctx, cfg) require.NoError(t, err) require.NotNil(t, c) From 92763890fd2d7cda221fc9c5ccc5eb6df06564cc Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 09:48:36 +0200 Subject: [PATCH 319/373] Fix OCI hooks. Fix Poststop hooks execution. OCI Lifecycle only allows Postart and Poststop hooks to fail. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook/main.go | 2 +- runtime.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index aa88f727..17f788cb 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -71,7 +71,7 @@ func run(ctx context.Context, env *Env) error { state.Status = status fmt.Printf("running OCI hooks for lxc hook %q", env.Type) - return specki.RunHooks(ctx, &state, hooksToRun, true) + return specki.RunHooks(ctx, &state, hooksToRun, false) } // https://github.com/opencontainers/runtime-spec/blob/master/specs-go/state.go diff --git a/runtime.go b/runtime.go index bf5afa53..a1e1e375 100644 --- a/runtime.go +++ b/runtime.go @@ -404,7 +404,7 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e if err != nil { return errorf("failed to get container state: %w", err) } - specki.RunHooks(ctx, &state.SpecState, c.Spec.Hooks.Poststart, true) + specki.RunHooks(ctx, &state.SpecState, c.Spec.Hooks.Poststop, true) } return os.RemoveAll(c.RuntimePath()) From 06add9f6d58f882b5a77dddb2d0b6d6b1d6ac756 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 10:18:54 +0200 Subject: [PATCH 320/373] Delete container if either start or create fail. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index ecb65794..6f72f326 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -309,15 +309,30 @@ func doCreate(ctxcli *cli.Context) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() + if err := doCreateInternal(ctx, pidFile); err != nil { + // Create a new context because create may fail with a timeout. + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := clxc.Delete(ctx, clxc.cfg.ContainerID, true); err != nil { + clxc.Log.Error().Err(err).Msg("failed to destroy container") + } + return err + } + return nil +} + +func doCreateInternal(ctx context.Context, pidFile string) error { c, err := clxc.Create(ctx, &clxc.cfg) if err != nil { return err } - defer c.Release() if pidFile != "" { - return createPidFile(pidFile, c.Pid) + err := createPidFile(pidFile, c.Pid) + if err != nil { + return err + } } - return nil + return c.Release() } var startCmd = cli.Command{ @@ -339,15 +354,29 @@ starts } func doStart(ctxcli *cli.Context) error { - c, err := clxc.Load(clxc.cfg.ContainerID) - if err != nil { - return fmt.Errorf("failed to load container: %w", err) - } timeout := time.Duration(ctxcli.Uint("timeout")) * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() + if err := doStartInternal(ctx); err != nil { + // a new context because start may fail with a timeout. + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := clxc.Delete(ctx, clxc.cfg.ContainerID, true); err != nil { + clxc.Log.Error().Err(err).Msg("failed to destroy container") + } + return err + } + return nil +} + +func doStartInternal(ctx context.Context) error { + c, err := clxc.Load(clxc.cfg.ContainerID) + if err != nil { + return fmt.Errorf("failed to load container: %w", err) + } + return clxc.Start(ctx, c) } From ec8e06ea37ceb7b4f1720a11ef5144865b6eb11e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 10:19:16 +0200 Subject: [PATCH 321/373] Return error on Delete if container does not exist. Signed-off-by: Ruben Jenster --- runtime.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime.go b/runtime.go index a1e1e375..e079910e 100644 --- a/runtime.go +++ b/runtime.go @@ -352,10 +352,10 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e rt.Log.Info().Bool("force", force).Msg("delete container") c, err := rt.Load(containerID) if err == ErrNotExist { - rt.Log.Info().Msg("container does not exist") - return nil + return err } if err != nil { + // NOTE hooks won't run in this case rt.Log.Warn().Msgf("deleting runtime dir for unloadable container: %s", err) return os.RemoveAll(filepath.Join(rt.Root, containerID)) } From 7b871508e0e130a97c5065b62275ae70d53a45ac Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:10:32 +0200 Subject: [PATCH 322/373] Fix nil pointers in builtin hook and oci hook runner. Signed-off-by: Ruben Jenster --- cmd/lxcri-hook-builtin/main.go | 2 +- cmd/lxcri-hook/main.go | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/lxcri-hook-builtin/main.go b/cmd/lxcri-hook-builtin/main.go index 607a4f4d..ef8918f3 100644 --- a/cmd/lxcri-hook-builtin/main.go +++ b/cmd/lxcri-hook-builtin/main.go @@ -46,7 +46,7 @@ func getDeviceMode(dev specs.LinuxDevice) (uint32, error) { } var perm uint32 = 0666 - if dev.FileMode == nil { + if dev.FileMode != nil { perm = uint32(*dev.FileMode) } return (fileType | perm), nil diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 17f788cb..1b09569f 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -84,7 +84,10 @@ func ociHooksAndState(t HookType, hooks *specs.Hooks) ([]specs.Hook, specs.Conta // quote from https://github.com/opencontainers/runtime-spec/blob/master/config.md#posix-platform-hooks // > For runtimes that implement the deprecated prestart hooks as createRuntime hooks, // > createRuntime hooks MUST be called after the prestart hooks. - return append(hooks.Prestart, hooks.CreateRuntime...), specs.StateCreating, nil + if len(hooks.CreateRuntime) > 0 { + return append(hooks.Prestart, hooks.CreateRuntime...), specs.StateCreating, nil + } + return hooks.Prestart, specs.StateCreating, nil case HookMount: return hooks.CreateContainer, specs.StateCreating, nil case HookStart: From 31e7f5b5410e0ea6d95fa272a800293d4a31741b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:12:08 +0200 Subject: [PATCH 323/373] Let cli delete command ignore ErrNotExist. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 6f72f326..533d197d 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -474,7 +474,13 @@ func doDelete(ctxcli *cli.Context) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - return clxc.Delete(ctx, clxc.cfg.ContainerID, ctxcli.Bool("force")) + err := clxc.Delete(ctx, clxc.cfg.ContainerID, ctxcli.Bool("force")) + // Deleting a non-existing container is a noop, + // otherwise cri-o / kubelet log warnings about that. + if err == lxcri.ErrNotExist { + return nil + } + return err } var execCmd = cli.Command{ From a32f3bf066b86cd009af42a923ab2d1c1c5e763c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:14:48 +0200 Subject: [PATCH 324/373] Fix error handling when reading from /proc/{pid}/cmdline. Signed-off-by: Ruben Jenster --- container.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/container.go b/container.go index 574ef066..e8a23eb6 100644 --- a/container.go +++ b/container.go @@ -237,15 +237,16 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { } cmdlinePath := fmt.Sprintf("/proc/%d/cmdline", initPid) cmdline, err := os.ReadFile(cmdlinePath) - if os.IsNotExist(err) { + // Ignore any error here. Most likely the error will be os.ErrNotExist. + // But I've seen race conditions where ESRCH is returned instead because + // the process has died while opening it's proc directory. + if err != nil { + if !(os.IsNotExist(err) || err == unix.ESRCH) { + c.Log.Warn().Str("file", cmdlinePath).Msgf("open failed: %s", err) + } // init process died or returned return specs.StateStopped, nil } - if err != nil { - // it's a serious error if cmdlinePath exists but can't be read - return specs.StateStopped, err - } - initCmdline := fmt.Sprintf("/.lxcri/init\000%s\000", c.ContainerID) if string(cmdline) == initCmdline { return specs.StateCreated, nil From 264b87810f2e138b551ec24e8ff321c5346cfc1a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:19:57 +0200 Subject: [PATCH 325/373] Remove test hook from runtime test. Signed-off-by: Ruben Jenster --- runtime_test.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index 12f7b5a3..ce2ebb77 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -166,28 +166,10 @@ func TestRuntimeUnprivileged2(t *testing.T) { testRuntime(t, rt, cfg) } -type HookType string - -const ( - HookCreateRuntime HookType = "CreateRuntime" -) - func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() - cfg.Spec.Hooks = &specs.Hooks{} - cfg.Spec.Hooks.CreateRuntime = append(cfg.Spec.Hooks.CreateRuntime, - specs.Hook{ - Path: "/tmp/myhook.sh", - //Args: []string{}, - Env: []string{ - "LXCRI_CONTAINER_ID=" + cfg.ContainerID, - "LXCRI_RUNTIME_ROOT=" + rt.Root, - "LXCRI_HOOK_TYPE=" + string(HookCreateRuntime), - }, - }, - ) c, err := rt.Create(ctx, cfg) require.NoError(t, err) require.NotNil(t, c) From 67559a2c974d8a2be37901a08c48d25af004a462 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:27:55 +0200 Subject: [PATCH 326/373] Do not run unprivileged runtime tests as root. Signed-off-by: Ruben Jenster --- runtime_test.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index ce2ebb77..7a195613 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -106,18 +106,18 @@ func TestRuntimePrivileged(t *testing.T) { } // The following tests require the following setup: -// TODO load UID/GID mappings from /etc/subgid /etc/subuid +// sudo /bin/sh -c "echo '$(whoami):1000:1' >> /etc/subuid" +// sudo /bin/sh -c "echo '$(whoami):20000:65536' >> /etc/subuid" +// sudo /bin/sh -c "echo '$(whoami):1000:1' >> /etc/subgid" +// sudo /bin/sh -c "echo '$(whoami):20000:65536' >> /etc/subgid" +// sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup/unified$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) // sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) -/* -[ruben@k8s-cluster8-controller lxcri]$ cat /etc/subgid -ruben:1000:1 -ruben:20000:65536 -[ruben@k8s-cluster8-controller lxcri]$ cat /etc/subuid -ruben:1000:1 -ruben:20000:65536 -*/ +// func TestRuntimeUnprivileged(t *testing.T) { + if os.Getuid() == 0 { + t.Skipf("this test is only run as non-root") + } rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -146,6 +146,9 @@ func TestRuntimeUnprivileged(t *testing.T) { } func TestRuntimeUnprivileged2(t *testing.T) { + if os.Getuid() == 0 { + t.Skipf("this test is only run as non-root") + } rt := newRuntime(t) defer os.RemoveAll(rt.Root) From 3968dae5be4454d3830285e83e177d2eddcb02d4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Thu, 15 Apr 2021 15:38:05 +0200 Subject: [PATCH 327/373] Fix lxcri app description. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index 533d197d..e7cf81a6 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -72,7 +72,7 @@ func (app *app) release() error { func main() { app := cli.NewApp() app.Name = "lxcri" - app.Usage = "lxcri is a CRI compliant runtime wrapper for lxc" + app.Usage = "lxcri is a OCI compliant runtime wrapper for lxc" app.Version = version // Disable the default ExitErrHandler. From 7668c81ea335a86707b2595852eb0118d5ec74a5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 08:28:30 +0200 Subject: [PATCH 328/373] Rewrite lxcri-init implementation in golang. Allthough the c implementation works fine this reduces overall complexity and allows execution of OCI StartContainer hooks within the init cmd. Signed-off-by: Ruben Jenster --- Makefile | 4 +- cmd/lxcri-hook/main.go | 6 +- cmd/lxcri-init/lxcri-init.c | 292 ------------------------------------ cmd/lxcri-init/main.go | 207 +++++++++++++++++++++++++ container.go | 44 +----- init.go | 85 +---------- pkg/specki/specki.go | 35 +++++ 7 files changed, 260 insertions(+), 413 deletions(-) delete mode 100644 cmd/lxcri-init/lxcri-init.c create mode 100644 cmd/lxcri-init/main.go diff --git a/Makefile b/Makefile index 47c9321e..1db8ed1d 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,8 @@ lxcri: go.mod $(GO_SRC) Makefile lxcri-start: cmd/lxcri-start/lxcri-start.c $(CC) -Werror -Wpedantic -o $@ $? $$(pkg-config --libs --cflags lxc) -lxcri-init: cmd/lxcri-init/lxcri-init.c - $(MUSL_CC) -Werror -Wpedantic -static -o $@ $? +lxcri-init: go.mod $(GO_SRC) Makefile + CGO_ENABLED=0 go build -o $@ ./cmd/lxcri-init # this is paranoia - but ensure it is statically compiled ! ldd $@ 2>/dev/null diff --git a/cmd/lxcri-hook/main.go b/cmd/lxcri-hook/main.go index 1b09569f..20045424 100644 --- a/cmd/lxcri-hook/main.go +++ b/cmd/lxcri-hook/main.go @@ -45,14 +45,12 @@ func main() { func run(ctx context.Context, env *Env) error { runtimeDir := filepath.Dir(env.ConfigFile) - // TODO save hooks to hooks.json var hooks specs.Hooks err := specki.DecodeJSONFile(filepath.Join(runtimeDir, "hooks.json"), &hooks) if err != nil { return err } - // TODO save state to state.json hooksToRun, status, err := ociHooksAndState(env.Type, &hooks) if err != nil { return err @@ -90,8 +88,8 @@ func ociHooksAndState(t HookType, hooks *specs.Hooks) ([]specs.Hook, specs.Conta return hooks.Prestart, specs.StateCreating, nil case HookMount: return hooks.CreateContainer, specs.StateCreating, nil - case HookStart: - return hooks.StartContainer, specs.StateCreated, nil + //case HookStart: + // return hooks.StartContainer, specs.StateCreated, nil // NOTE the following hooks are executed directly from lxcri //case HookPostStart: // return hooks.Poststart, specs.StateRunning, nil diff --git a/cmd/lxcri-init/lxcri-init.c b/cmd/lxcri-init/lxcri-init.c deleted file mode 100644 index 8e823dc1..00000000 --- a/cmd/lxcri-init/lxcri-init.c +++ /dev/null @@ -1,292 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *syncfifo_path = "syncfifo"; -const char *cmdline_path = "cmdline"; -const char *environ_path = "environ"; -const char *error_log = "error.log"; - -// A conformance test that will fail if SETENV_OVERWRITE is set to 0 -// is "StatefulSet [k8s.io] Basic StatefulSet functionality [StatefulSetBasic] -// should have a working scale subresource [Conformance]" In the spec two -// conflicting PATH environment variables are defined. The container image -// 'httpd:2.4.38-alpine' only defines the second. -// -// This value must be set to control the behaviour for conflicting environment -// variables: SETENV_OVERWRITE=0 the variable that is defined first takes -// precedence SETENV_OVERWRITE=1 the variable that is defined last overwrites -// all previous definitions -#ifndef SETENV_OVERWRITE -#define SETENV_OVERWRITE 1 -#endif - -#define ERROR(format, ...) \ - { \ - dprintf(errfd, "[lxcri-init] " format, ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } - -int writefifo(const char *fifo, const char *msg) -{ - int fd; - - fd = open(fifo, O_WRONLY | O_CLOEXEC); - if (fd == -1) - return -1; - - if (write(fd, msg, strlen(msg)) == -1) - return -1; - - return close(fd); -} - -/* load_cmdline reads up to maxargs-1 cmdline arguments from path into args. - * path is the path of the cmdline file. - * The cmdline files contains a list of null terminated arguments - * similar to /proc//cmdline. - * Each argument must have a maximum length of buflen (including null). - */ -int load_cmdline(const char *path, char *buf, int buflen, char **args, int maxargs) -{ - int fd; - FILE *f; - int n = 0; - - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd == -1) - return -1; - - f = fdopen(fd, "r"); - if (f == NULL) - return -1; - - for (n = 0; n < maxargs - 1; n++) { - char c; - int i; - /* read until next '\0' or EOF */ - for (i = 0; i < buflen; i++) { - c = getc(f); - if (c == EOF) { - break; - } - buf[i] = c; - if (c == '\0') - break; - } - - if (errno != 0) /* getc failed */ - return -1; - - if (c == EOF) { - if (i > 0) /* trailing garbage */ - return -1; - args[n] = (char *)NULL; - break; - } - - args[n] = strndup(buf, i); - if (errno != 0) /* strndup failed */ - return -1; - } - /* cmdline is empty */ - if (n == 0) - return -1; - - return 0; -} - -/* load_environ loads environment variables from path, - * and adds them to the process environment. - * path is the path to a list of - * null terminated environment variables like /proc//environ - * Each variable must have a maximum length of buflen (including null) - * see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 - */ -int load_environ(const char *path, char *buf, int buflen) -{ - int fd; - FILE *f; - - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd == -1) - return 0; - - f = fdopen(fd, "r"); - if (f == NULL) - return -1; - - for (;;) { - char *key = NULL; - char c; - int i; - /* read until next '\0' or EOF */ - for (i = 0; i < buflen; i++) { - c = getc(f); - if (c == EOF) { - break; - } - buf[i] = c; - if (c == '\0') - break; - - /* split at first '=' */ - if (key == NULL && c == '=') { - buf[i] = '\0'; - key = buf; - } - } - - if (errno != 0) /* getc failed */ - return -1; - - if (c == EOF) { - if (i > 0) /* trailing garbage */ - return -1; - break; - } - - /* malformed content e.g 'fooo\0' or 'fooo=' */ - if (key == NULL || i == strlen(key)) - return -1; - - if (setenv(key, buf + strlen(key) + 1, SETENV_OVERWRITE) == -1) - return -1; - } - return 0; -} - -/* Ensure_HOME_exists sets the HOME environment variable if it is not set. - * There are containers that don't run without HOME being set e.g 'cilium v1.9.0' - */ -int ensure_HOME_exists() -{ - struct passwd *pw; - int root_fd; - - // fast path - if (getenv("HOME") != NULL) - return 0; - - pw = getpwuid(geteuid()); - /* ignore error from getpwuid */ - errno = 0; - if (pw != NULL && pw->pw_dir != NULL) - return setenv("HOME", pw->pw_dir, 0); - - root_fd = open("/root", O_PATH | O_CLOEXEC); - errno = 0; - if (root_fd != -1) { - close(root_fd); - errno = 0; - return setenv("HOME", "/root", 0); - } - - return setenv("HOME", "/", 0); -} - -/* To avoid leaking inherited file descriptors, - * all file descriptors except stdio (0,1,2) are closed. - * File descriptor leaks may lead to serious security issues. - */ -int close_extra_fds(int errfd) -{ - int fd; - DIR *dirp = NULL; - struct dirent *entry = NULL; - - fd = open("/proc/self/fd", O_RDONLY | O_CLOEXEC); - if (fd == -1) - ERROR("open /proc/self/fd failed"); - - dirp = fdopendir(fd); - if (dirp == NULL) - ERROR("fdopendir for /proc/self/fd failed"); - - while ((entry = readdir(dirp)) != NULL) { - int xfd = atoi(entry->d_name); - if ((xfd > 2) && (xfd != fd)) - close(fd); - } - - closedir(dirp); - errno = 0; // ignore errors from close - return 0; -} - -int main(int argc, char **argv) -{ - /* Buffer for reading arguments and environment variables. - * There is not a limit per environment variable, but we limit it to 1MiB here - * https://stackoverflow.com/questions/53842574/max-size-of-environment-variables-in-kubernetes. - * - * For arguments "Additionally, the limit per string is 32 pages - * (the kernel constant MAX_ARG_STRLEN), - * and the maximum number of strings is 0x7FFFFFFF." - */ - char buf[1024 * 1024]; - - /* Null terminated list of cmline arguments. - * See 'man 2 execve' 'Limits on size of arguments and environment' - */ - char *args[256]; - - const char *container_id; - - int ret = 0; - - int errfd; - - /* write errors to error.log if it exists otherwise to stderr */ - errfd = open(error_log, O_WRONLY | O_CLOEXEC); - if (errfd == -1) { - errno = 0; - errfd = 2; - } - - if (argc != 2) - ERROR("invalid number of arguments %d\n" - "usage: %s \n", - argc, argv[0]); - - container_id = argv[1]; - - /* clear environment */ - environ = NULL; - - ret = load_environ(environ_path, buf, sizeof(buf)); - if (ret == -1) - ERROR("error reading environment file \"%s\": %s\n", - environ_path, strerror(errno)); - - ret = load_cmdline(cmdline_path, buf, sizeof(buf), args, sizeof(args)); - if (ret == -1) - ERROR("error reading cmdline file \"%s\": %s\n", cmdline_path, - strerror(errno)); - - if (ensure_HOME_exists() == -1) - ERROR("failed to set HOME environment variable: %s\n", - strerror(errno)); - - if (writefifo(syncfifo_path, container_id) == -1) - ERROR("failed to write syncfifo: %s\n", strerror(errno)); - - if (chdir("cwd") == -1) - ERROR("failed to change working directory: %s\n", - strerror(errno)); - - if (close_extra_fds(errfd) == -1) - ERROR("failed to close extra fds: %s\n", strerror(errno)); - - if (execvp(args[0], args) == -1) - ERROR("failed to exec \"%s\": %s\n", args[0], strerror(errno)); -} diff --git a/cmd/lxcri-init/main.go b/cmd/lxcri-init/main.go new file mode 100644 index 00000000..819eaacf --- /dev/null +++ b/cmd/lxcri-init/main.go @@ -0,0 +1,207 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/exec" + "os/user" + "path/filepath" + "strings" + "time" + + "github.com/drachenfels-de/lxcri/pkg/specki" + "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" +) + +func main() { + // TODO use environment variable for runtime dir + runtimeDir, err := os.Getwd() + if err != nil { + fmt.Fprintf(os.Stderr, "failed to get runtime dir: %s\n", err) + os.Exit(2) + } + + specPath := filepath.Join(runtimeDir, "config.json") + spec, err := specki.ReadSpecJSON(specPath) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err.Error()) + os.Exit(3) + } + + err = doInit(runtimeDir, spec) + if err != nil { + if err := writeTerminationLog(spec, "init failed: %s\n", err); err != nil { + fmt.Fprintf(os.Stderr, "%s", err) + } + fmt.Fprintf(os.Stderr, "init failed: %s\n", err) + os.Exit(4) + } +} + +func writeTerminationLog(spec *specs.Spec, format string, a ...interface{}) error { + var terminationLog string + if spec.Annotations != nil { + terminationLog = spec.Annotations["io.kubernetes.container.terminationMessagePath"] + } + if terminationLog == "" { + return nil + } + + f, err := os.OpenFile(terminationLog, os.O_WRONLY|os.O_APPEND, 0640) + if err != nil { + return err + } + defer f.Close() + + _, err = fmt.Fprintf(f, format, a...) + if err != nil { + return fmt.Errorf("failed to write to termination log %q: %w", terminationLog, err) + } + return nil +} + +func doInit(runtimeDir string, spec *specs.Spec) error { + statePath := filepath.Join(runtimeDir, "state.json") + state, err := specki.LoadSpecStateJSON(statePath) + if err != nil { + return fmt.Errorf("failed to read spec %q: %s", statePath, err) + } + + // remove duplicates from environment variables, + // since the behaviour of execve is undefined here. + // glibc setenv has a parameter `overwrite` to control the behaviour. see `man 3 setenv` + // previously overwrite was set to 1, the last defined variable will overwrite all + // previously defined variables. + cleanenv(spec, true) + + cmdPath := spec.Process.Args[0] + val, exist := getenv(spec.Process.Env, "PATH") + if exist { + err := os.Setenv("PATH", val) + if err != nil { + return fmt.Errorf("failed to set PATH environment variable: %s", err) + } + cmdPath, err = exec.LookPath(spec.Process.Args[0]) + if err != nil { + return fmt.Errorf("lookup path for %s failed: %w", spec.Process.Args[0], err) + } + } + + addEnvHome(spec) + + err = readSyncfifo(filepath.Join(runtimeDir, "syncfifo")) + if err != nil { + return err + } + + err = unix.Chdir(spec.Process.Cwd) + if err != nil { + return fmt.Errorf("failed to change cwd to %s: %w", spec.Process.Cwd, err) + } + + // TODO unmount the runtimeDir + + // TODO use environment variable to control timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + err = specki.RunHooks(ctx, state, spec.Hooks.StartContainer, false) + if err != nil { + return err + } + + unix.Exec(cmdPath, spec.Process.Args, spec.Process.Env) + if err != nil { + return fmt.Errorf("exec failed: %w", err) + } + return nil +} + +func readSyncfifo(filename string) error { + f, err := os.OpenFile(filename, os.O_RDONLY, 0) + if err != nil { + return fmt.Errorf("failed to open %s: %w", filename, err) + } + return f.Close() +} + +// Getenv returns the first matching value from env, +// which has a prefix of key + "=". +func getenv(env []string, key string) (string, bool) { + for _, kv := range env { + if strings.HasPrefix(kv, key+"=") { + val := strings.TrimPrefix(kv, key+"=") + return val, true + } + } + return "", false +} + +// Setenv appends the given kv to the environment. +// kv is only append if either a value with the same key +// is not yet set and overwrite is false, or if the value is +// already set and overwrite is true. +func setenv(env []string, kv string, overwrite bool) []string { + a := strings.Split(kv, "=") + key := a[0] + for i, kv := range env { + if strings.HasPrefix(kv, key+"=") { + if overwrite { + env[i] = kv + } + return env + } + } + return append(env, kv) +} + +// cleanenv removes duplicates from spec.Process.Env. +// If overwrite is false the first defined value takes precedence, +// if overwrite is true, the last defined value overwrites previously +// defined values. +func cleanenv(spec *specs.Spec, overwrite bool) { + if len(spec.Process.Env) < 2 { + return + } + newEnv := make([]string, len(spec.Process.Env)) + for _, kv := range spec.Process.Env { + newEnv = setenv(newEnv, kv, overwrite) + } + spec.Process.Env = newEnv +} + +/* +func closeExtraFds() { + os.Open("/proc/self/fd") +} +*/ + +func addEnvHome(spec *specs.Spec) { + // Use existing HOME environment variable. + for _, kv := range spec.Process.Env { + if strings.HasPrefix(kv, "HOME=") { + return + } + } + + // Or lookup users home directory in passwd. + userName := spec.Process.User.Username + if userName != "" { + u, err := user.Lookup(userName) + if err == nil && u.HomeDir != "" { + spec.Process.Env = append(spec.Process.Env, "HOME="+u.HomeDir) + return + } + } + // If user is root without entry in /etc/passwd then try /root + if spec.Process.User.UID == 0 { + stat, err := os.Stat("/root") + if err == nil && stat.IsDir() { + spec.Process.Env = append(spec.Process.Env, "HOME=/root") + return + } + } + spec.Process.Env = append(spec.Process.Env, "HOME="+spec.Process.Cwd) + return +} diff --git a/container.go b/container.go index e8a23eb6..72c70cbc 100644 --- a/container.go +++ b/container.go @@ -55,7 +55,7 @@ func (c Container) ConfigFilePath() string { } func (c Container) syncFifoPath() string { - return c.RuntimePath(initDir, "syncfifo") + return c.RuntimePath("syncfifo") } // RuntimePath returns the absolute path to the given sub path @@ -247,7 +247,7 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { // init process died or returned return specs.StateStopped, nil } - initCmdline := fmt.Sprintf("/.lxcri/init\000%s\000", c.ContainerID) + initCmdline := fmt.Sprintf("/.lxcri/lxcri-init\000") if string(cmdline) == initCmdline { return specs.StateCreated, nil } @@ -341,45 +341,17 @@ func (c *Container) Release() error { } func (c *Container) start(ctx context.Context) error { - done := make(chan error) - go func() { - // FIXME fifo must be unblocked otherwise - // this may be a goroutine leak - done <- c.readFifo() - }() - - select { - case <-ctx.Done(): - return errorf("syncfifo timeout: %w", ctx.Err()) - // TODO write to fifo here and fallthrough ? - case err := <-done: - if err != nil { - return errorf("failed to read from syncfifo: %w", err) - } - } - // wait for container state to change - return c.waitNot(ctx, specs.StateCreated) -} - -func (c *Container) readFifo() error { // #nosec - f, err := os.OpenFile(c.syncFifoPath(), os.O_RDONLY, 0) + fifo, err := os.OpenFile(c.syncFifoPath(), os.O_WRONLY, 0) if err != nil { return err } - // NOTE it's not possible to set an IO deadline on a fifo - // #nosec - defer f.Close() - - data := make([]byte, len(c.ContainerID)) - _, err = f.Read(data) - if err != nil { - return fmt.Errorf("problem reading from fifo: %w", err) - } - if c.ContainerID != string(data) { - return fmt.Errorf("bad fifo content: %s", string(data)) + if err := fifo.Close(); err != nil { + return err } - return nil + + // wait for container state to change + return c.waitNot(ctx, specs.StateCreated) } // ExecDetached executes the given process spec within the container. diff --git a/init.go b/init.go index 8b8717a9..5f6a6607 100644 --- a/init.go +++ b/init.go @@ -11,12 +11,6 @@ import ( "golang.org/x/sys/unix" ) -const ( - // initDir is the working directory for lxcri-init. - // It contains the init binary itself and all files required for it. - initDir = "/.lxcri" -) - func createFifo(dst string, mode uint32) error { if err := unix.Mkfifo(dst, mode); err != nil { return errorf("mkfifo dst:%s failed: %w", dst, err) @@ -40,23 +34,10 @@ func runAsRuntimeUser(spec *specs.Spec) bool { } func configureInit(rt *Runtime, c *Container) error { - runtimeInitDir := c.RuntimePath(initDir) - //rootfsInitDir := filepath.Join(c.Root.Path, initDir) - - /* - err := os.MkdirAll(rootfsInitDir, 0755) - if err != nil { - return fmt.Errorf("failed to create init dir in rootfs %q: %w", rootfsInitDir, err) - } - */ - // #nosec - err := os.MkdirAll(runtimeInitDir, 0755) - if err != nil { - return fmt.Errorf("failed to create runtime init dir %q: %w", runtimeInitDir, err) - } + initDir := "/.lxcri" c.Spec.Mounts = append(c.Spec.Mounts, specs.Mount{ - Source: runtimeInitDir, + Source: c.RuntimePath(), Destination: strings.TrimLeft(initDir, "/"), Type: "bind", Options: []string{"bind", "ro", "nodev", "nosuid", "create=dir"}, @@ -66,40 +47,14 @@ func configureInit(rt *Runtime, c *Container) error { return err } - // create files required for lxcri-init if runAsRuntimeUser(c.Spec) { if err := createFifo(c.syncFifoPath(), 0600); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Spec.Process.Args, 0400); err != nil { - return err - } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Spec.Process.Env, 0400); err != nil { - return err - } } else { if err := createFifo(c.syncFifoPath(), 0666); err != nil { return fmt.Errorf("failed to create sync fifo: %w", err) } - if err := createList(filepath.Join(runtimeInitDir, "cmdline"), c.Spec.Process.Args, 0444); err != nil { - return err - } - if err := createList(filepath.Join(runtimeInitDir, "environ"), c.Spec.Process.Env, 0444); err != nil { - return err - } - } - - if err := os.Symlink(c.Spec.Process.Cwd, filepath.Join(runtimeInitDir, "cwd")); err != nil { - return err - } - - if c.Spec.Annotations != nil { - msgPath := c.Spec.Annotations["io.kubernetes.container.terminationMessagePath"] - if msgPath != "" { - if err := os.Symlink(msgPath, filepath.Join(runtimeInitDir, "error.log")); err != nil { - return err - } - } } if err := configureInitUser(c); err != nil { @@ -107,19 +62,19 @@ func configureInit(rt *Runtime, c *Container) error { } // bind mount lxcri-init into the container - initCmdPath := filepath.Join(runtimeInitDir, "init") - err = touchFile(initCmdPath, 0) + initCmdPath := c.RuntimePath("lxcri-init") + err := touchFile(initCmdPath, 0) if err != nil { return fmt.Errorf("failed to create %s: %w", initCmdPath, err) } - initCmd := filepath.Join(initDir, "init") + initCmd := filepath.Join(initDir, "lxcri-init") c.Spec.Mounts = append(c.Spec.Mounts, specs.Mount{ Source: rt.libexec(ExecInit), Destination: strings.TrimLeft(initCmd, "/"), Type: "bind", Options: []string{"bind", "ro", "nosuid"}, }) - return c.SetConfigItem("lxc.init.cmd", initCmd+" "+c.ContainerID) + return c.SetConfigItem("lxc.init.cmd", initCmd) } func touchFile(filePath string, perm os.FileMode) error { @@ -131,34 +86,6 @@ func touchFile(filePath string, perm os.FileMode) error { return err } -func createList(dst string, entries []string, mode uint32) error { - // #nosec - f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) - if err != nil { - return errorf("failed to create %s: %w", dst, err) - } - - for _, arg := range entries { - _, err := f.WriteString(arg) - if err != nil { - f.Close() - return errorf("failed to write to %s: %w", dst, err) - } - _, err = f.Write([]byte{'\000'}) - if err != nil { - f.Close() - return errorf("failed to write to %s: %w", dst, err) - } - } - if err := f.Close(); err != nil { - return errorf("failed to close %s: %w", dst, err) - } - if err := unix.Chmod(dst, mode); err != nil { - return errorf("failed to chmod %s mode:%o : %w", dst, mode, err) - } - return nil -} - func configureInitUser(c *Container) error { // TODO ensure that the user namespace is enabled // See `man lxc.container.conf` lxc.idmap. diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index faa53dd0..80f5a126 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -289,6 +289,12 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { return proc } +func LoadSpecStateJSON(filename string) (*specs.State, error) { + state := new(specs.State) + err := DecodeJSONFile(filename, state) + return state, err +} + // ReadSpecStateJSON parses the JSON encoded specs.State from the given reader. func ReadSpecStateJSON(r io.Reader) (*specs.State, error) { state := new(specs.State) @@ -318,3 +324,32 @@ func InitHook(r io.Reader) (rootfs string, state *specs.State, spec *specs.Spec, } return } + +// BindMount returns a specs.Mount to bind mount src to dest. +// The given mount options opts are merged with the predefined options +// ("bind", "nosuid", "nodev", "relatime") +func BindMount(src string, dest string, opts ...string) specs.Mount { + return specs.Mount{ + Source: src, Destination: dest, Type: "bind", + Options: append([]string{"bind", "nosuid", "nodev", "relatime"}, opts...), + } +} + +func hasOption(m specs.Mount, opt string) bool { + for _, o := range m.Options { + if o == opt { + return true + } + } + return false +} + +// HasOptions returns true if the given Mount has all provided options opts. +func HasOptions(m specs.Mount, opts ...string) bool { + for _, o := range opts { + if !hasOption(m, o) { + return false + } + } + return true +} From 4947e01c75afe6cfcaf46bc04f89d51dd65303e6 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 19:09:45 +0200 Subject: [PATCH 329/373] Deduplicate spec.Process.Env in Runtime.Create Signed-off-by: Ruben Jenster --- cmd/lxcri-init/main.go | 77 +++++------------------------------------- create.go | 23 +++++++++++++ pkg/specki/specki.go | 32 ++++++++++++++++++ 3 files changed, 64 insertions(+), 68 deletions(-) diff --git a/cmd/lxcri-init/main.go b/cmd/lxcri-init/main.go index 819eaacf..3d62fe1f 100644 --- a/cmd/lxcri-init/main.go +++ b/cmd/lxcri-init/main.go @@ -7,7 +7,6 @@ import ( "os/exec" "os/user" "path/filepath" - "strings" "time" "github.com/drachenfels-de/lxcri/pkg/specki" @@ -69,15 +68,8 @@ func doInit(runtimeDir string, spec *specs.Spec) error { return fmt.Errorf("failed to read spec %q: %s", statePath, err) } - // remove duplicates from environment variables, - // since the behaviour of execve is undefined here. - // glibc setenv has a parameter `overwrite` to control the behaviour. see `man 3 setenv` - // previously overwrite was set to 1, the last defined variable will overwrite all - // previously defined variables. - cleanenv(spec, true) - cmdPath := spec.Process.Args[0] - val, exist := getenv(spec.Process.Env, "PATH") + val, exist := specki.Getenv(spec.Process.Env, "PATH") if exist { err := os.Setenv("PATH", val) if err != nil { @@ -89,11 +81,9 @@ func doInit(runtimeDir string, spec *specs.Spec) error { } } - addEnvHome(spec) - - err = readSyncfifo(filepath.Join(runtimeDir, "syncfifo")) - if err != nil { - return err + val, exist = specki.Getenv(spec.Process.Env, "HOME") + if !exist { + addEnvHome(spec) } err = unix.Chdir(spec.Process.Cwd) @@ -101,7 +91,10 @@ func doInit(runtimeDir string, spec *specs.Spec) error { return fmt.Errorf("failed to change cwd to %s: %w", spec.Process.Cwd, err) } - // TODO unmount the runtimeDir + err = readSyncfifo(filepath.Join(runtimeDir, "syncfifo")) + if err != nil { + return err + } // TODO use environment variable to control timeout ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) @@ -126,51 +119,6 @@ func readSyncfifo(filename string) error { return f.Close() } -// Getenv returns the first matching value from env, -// which has a prefix of key + "=". -func getenv(env []string, key string) (string, bool) { - for _, kv := range env { - if strings.HasPrefix(kv, key+"=") { - val := strings.TrimPrefix(kv, key+"=") - return val, true - } - } - return "", false -} - -// Setenv appends the given kv to the environment. -// kv is only append if either a value with the same key -// is not yet set and overwrite is false, or if the value is -// already set and overwrite is true. -func setenv(env []string, kv string, overwrite bool) []string { - a := strings.Split(kv, "=") - key := a[0] - for i, kv := range env { - if strings.HasPrefix(kv, key+"=") { - if overwrite { - env[i] = kv - } - return env - } - } - return append(env, kv) -} - -// cleanenv removes duplicates from spec.Process.Env. -// If overwrite is false the first defined value takes precedence, -// if overwrite is true, the last defined value overwrites previously -// defined values. -func cleanenv(spec *specs.Spec, overwrite bool) { - if len(spec.Process.Env) < 2 { - return - } - newEnv := make([]string, len(spec.Process.Env)) - for _, kv := range spec.Process.Env { - newEnv = setenv(newEnv, kv, overwrite) - } - spec.Process.Env = newEnv -} - /* func closeExtraFds() { os.Open("/proc/self/fd") @@ -178,14 +126,7 @@ func closeExtraFds() { */ func addEnvHome(spec *specs.Spec) { - // Use existing HOME environment variable. - for _, kv := range spec.Process.Env { - if strings.HasPrefix(kv, "HOME=") { - return - } - } - - // Or lookup users home directory in passwd. + // lookup users home directory in passwd. userName := spec.Process.User.Username if userName != "" { u, err := user.Lookup(userName) diff --git a/create.go b/create.go index f0121adf..a17686d5 100644 --- a/create.go +++ b/create.go @@ -36,6 +36,8 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to configure container: %w", err) } + cleanenv(c, true) + // Seralize the modified spec.Spec separately, to make it available for // runtime hooks. specPath := c.RuntimePath(BundleConfigFile) @@ -365,3 +367,24 @@ func configureHooks(rt *Runtime, c *Container) error { } return nil } + +// cleanenv removes duplicates from spec.Process.Env. +// If overwrite is false the first defined value takes precedence, +// if overwrite is true, the last defined value overwrites previously +// defined values. +func cleanenv(c *Container, overwrite bool) { + env := c.Spec.Process.Env + if len(env) < 2 { + return + } + newEnv := make([]string, len(env)) + var exist bool + for _, kv := range env { + newEnv, exist = specki.Setenv(newEnv, kv, overwrite) + if exist { + vals := strings.Split(kv, "=") + c.Log.Warn().Msgf("duplicate environment variable %s (overwrite=%t)", vals[0], overwrite) + } + } + c.Spec.Process.Env = newEnv +} diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 80f5a126..35f2c3ba 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "time" "github.com/opencontainers/runtime-spec/specs-go" @@ -353,3 +354,34 @@ func HasOptions(m specs.Mount, opts ...string) bool { } return true } + +// Getenv returns the first matching value from env, +// which has a prefix of key + "=". +func Getenv(env []string, key string) (string, bool) { + for _, kv := range env { + if strings.HasPrefix(kv, key+"=") { + val := strings.TrimPrefix(kv, key+"=") + return val, true + } + } + return "", false +} + +// Setenv appends the given kv to the environment. +// kv is only append if either a value with the same key +// is not yet set and overwrite is false, or if the value is +// already set and overwrite is true. +// It returns the changed environment and true the variable already exists. +func Setenv(env []string, val string, overwrite bool) ([]string, bool) { + a := strings.Split(val, "=") + key := a[0] + for i, kv := range env { + if strings.HasPrefix(kv, key+"=") { + if overwrite { + env[i] = val + } + return env, true + } + } + return append(env, val), false +} From feba600a3516f15953964beaf79ce47430ed4e44 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 19:15:05 +0200 Subject: [PATCH 330/373] Unmount runtime dir and lxcri-init bind mounts after exec Signed-off-by: Ruben Jenster --- cmd/lxcri-init/main.go | 5 +++++ cmd/lxcri-test/main.go | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/cmd/lxcri-init/main.go b/cmd/lxcri-init/main.go index 3d62fe1f..511fd5f5 100644 --- a/cmd/lxcri-init/main.go +++ b/cmd/lxcri-init/main.go @@ -104,6 +104,11 @@ func doInit(runtimeDir string, spec *specs.Spec) error { return err } + // unmount runtimeDir and lxcri-init bind mounts after exec + if err := unix.Unmount(runtimeDir, unix.MNT_DETACH); err != nil { + return err + } + unix.Exec(cmdPath, spec.Process.Args, spec.Process.Env) if err != nil { return fmt.Errorf("exec failed: %w", err) diff --git a/cmd/lxcri-test/main.go b/cmd/lxcri-test/main.go index 561b0af5..8be590f2 100644 --- a/cmd/lxcri-test/main.go +++ b/cmd/lxcri-test/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "os" "os/signal" "syscall" @@ -25,5 +26,11 @@ func main() { fmt.Printf("%#v\n", os.Args) println("sleeping for 30 seconds") + f, err := os.Open("/proc/self/mounts") + if err != nil { + panic(err) + } + defer f.Close() + io.Copy(os.Stdout, f) time.Sleep(time.Second * 30) } From 447c422911094ccb8b3e41e0990b95ddaf9c5b8e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 20:20:05 +0200 Subject: [PATCH 331/373] Revert "Unmount runtime dir and lxcri-init bind mounts after exec" This will only work for containers with CAP_SYS_ADMIN privileges. This reverts commit 82defd3aad555b62fe07692b9cd6908dba24d799. Signed-off-by: Ruben Jenster --- cmd/lxcri-init/main.go | 5 ----- cmd/lxcri-test/main.go | 7 ------- 2 files changed, 12 deletions(-) diff --git a/cmd/lxcri-init/main.go b/cmd/lxcri-init/main.go index 511fd5f5..3d62fe1f 100644 --- a/cmd/lxcri-init/main.go +++ b/cmd/lxcri-init/main.go @@ -104,11 +104,6 @@ func doInit(runtimeDir string, spec *specs.Spec) error { return err } - // unmount runtimeDir and lxcri-init bind mounts after exec - if err := unix.Unmount(runtimeDir, unix.MNT_DETACH); err != nil { - return err - } - unix.Exec(cmdPath, spec.Process.Args, spec.Process.Env) if err != nil { return fmt.Errorf("exec failed: %w", err) diff --git a/cmd/lxcri-test/main.go b/cmd/lxcri-test/main.go index 8be590f2..561b0af5 100644 --- a/cmd/lxcri-test/main.go +++ b/cmd/lxcri-test/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io" "os" "os/signal" "syscall" @@ -26,11 +25,5 @@ func main() { fmt.Printf("%#v\n", os.Args) println("sleeping for 30 seconds") - f, err := os.Open("/proc/self/mounts") - if err != nil { - panic(err) - } - defer f.Close() - io.Copy(os.Stdout, f) time.Sleep(time.Second * 30) } From 30acd741b3ffca5b326f64acf87c62e31f8af9e5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 20:19:38 +0200 Subject: [PATCH 332/373] Remove invalid logging statement. Signed-off-by: Ruben Jenster --- runtime.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime.go b/runtime.go index e079910e..2b50429a 100644 --- a/runtime.go +++ b/runtime.go @@ -379,9 +379,8 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e // Since every container get's it's own cgroup, we can // try to kill all processes within the containers cgroup tree. if err := drainCgroup(ctx, c.CgroupDir, unix.SIGKILL); err != nil { - rt.Log.Warn().Msgf("draining cgroup failed: %s", err) + rt.Log.Debug().Msgf("failed to drain cgroup: %s", err) } - rt.Log.Info().Msg("cgroup drained") } // From OCI runtime spec From 8e10d9516b9aa273a3ff9f94187a20c96e63bf5f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 20:33:00 +0200 Subject: [PATCH 333/373] Remove musl dependency. Signed-off-by: Ruben Jenster --- Makefile | 1 - install.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1db8ed1d..10323fd6 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,6 @@ PKG_CONFIG_PATH ?= $(PREFIX)/lib/pkgconfig export PKG_CONFIG_PATH LDFLAGS=-X main.version=$(COMMIT) -X main.libexecDir=$(LIBEXEC_DIR) CC ?= cc -MUSL_CC ?= musl-gcc SHELL_SCRIPTS = $(shell find . -name \*.sh) GO_SRC = $(shell find . -name \*.go | grep -v _test.go) diff --git a/install.sh b/install.sh index b8e70ff4..c70bf857 100755 --- a/install.sh +++ b/install.sh @@ -17,7 +17,7 @@ case "$DISTRIBUTION" in export DEBIAN_FRONTEND=noninteractive - PKGS_BUILD="automake build-essential ca-certificates git libc6-dev libtool make musl musl-tools pkg-config wget" + PKGS_BUILD="automake build-essential ca-certificates git libc6-dev libtool make pkg-config wget" PKGS_BUILD="$PKGS_BUILD libapparmor-dev libbtrfs-dev libc6-dev libcap-dev libdevmapper-dev libglib2.0-dev libseccomp-dev" PKGS_RUNTIME="libapparmor1 libbtrfs0 libcap2 libdevmapper1.02.1 libseccomp2" From ba8fb9dce66d41bf9237948977d299cd7041a902 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 20:38:46 +0200 Subject: [PATCH 334/373] Update documentation. Signed-off-by: Ruben Jenster --- pkg/specki/specki.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 35f2c3ba..4cceb24b 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -290,6 +290,7 @@ func NewSpecProcess(cmd string, args ...string) *specs.Process { return proc } +// LoadSpecStateJSON parses specs.State from the JSON encoded file filename. func LoadSpecStateJSON(filename string) (*specs.State, error) { state := new(specs.State) err := DecodeJSONFile(filename, state) @@ -367,11 +368,11 @@ func Getenv(env []string, key string) (string, bool) { return "", false } -// Setenv appends the given kv to the environment. -// kv is only append if either a value with the same key -// is not yet set and overwrite is false, or if the value is -// already set and overwrite is true. -// It returns the changed environment and true the variable already exists. +// Setenv adds the given variable to the environment env. +// The variable is only added if it is not yet defined +// or if overwrite is set to true. +// Setenv returns the modified environment and +// true the variable is already defined or false otherwise. func Setenv(env []string, val string, overwrite bool) ([]string, bool) { a := strings.Split(val, "=") key := a[0] From 3b0a65164708c89eeed6a00fbefe2d75976a29bd Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 20:59:30 +0200 Subject: [PATCH 335/373] Hide runtime test binary in pkg/internal Signed-off-by: Ruben Jenster --- Makefile | 2 +- {cmd => pkg/internal}/lxcri-test/main.go | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {cmd => pkg/internal}/lxcri-test/main.go (100%) diff --git a/Makefile b/Makefile index 10323fd6..ce3d755d 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ fmt: .PHONY: test test: build - go build ./cmd/lxcri-test + go build ./pkg/internal/lxcri-test go test --count 1 -v ./... build: $(BINS) $(LIBEXEC_BINS) diff --git a/cmd/lxcri-test/main.go b/pkg/internal/lxcri-test/main.go similarity index 100% rename from cmd/lxcri-test/main.go rename to pkg/internal/lxcri-test/main.go From 65e16988e35ea20ebc043ea83b0d51f22d78ef28 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 21:09:48 +0200 Subject: [PATCH 336/373] Remove unused code and fix staticcheck errors. Run staticcheck --unused.whole-program=true -- ./... Signed-off-by: Ruben Jenster --- cgroup.go | 9 +++------ cmd/lxcri-hook/hooks.go | 18 +++++++++--------- cmd/lxcri-init/main.go | 3 +-- cmd/lxcri/cli.go | 15 ++++++--------- cmd/lxcri/utils.go | 37 ------------------------------------- container.go | 17 +---------------- mount.go | 4 ++-- pkg/specki/specki.go | 33 +-------------------------------- seccomp.go | 2 +- utils.go | 13 ------------- 10 files changed, 24 insertions(+), 127 deletions(-) diff --git a/cgroup.go b/cgroup.go index 94e5b8ba..d6637552 100644 --- a/cgroup.go +++ b/cgroup.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "io" "os" "path/filepath" "strconv" @@ -15,10 +16,6 @@ import ( "github.com/opencontainers/runtime-spec/specs-go" ) -const ( - allControllers = "+cpuset +cpu +io +memory +hugetlb +pids +rdma" -) - var cgroupRoot string func detectCgroupRoot() string { @@ -183,7 +180,7 @@ func configureDeviceController(c *Container) error { return err } default: - return fmt.Errorf("Invalid cgroup2 device - invalid type (allow:%t %s %s:%s %s)", dev.Allow, dev.Type, maj, min, dev.Access) + return fmt.Errorf("invalid cgroup2 device - invalid type (allow:%t %s %s:%s %s)", dev.Allow, dev.Type, maj, min, dev.Access) } } return nil @@ -354,7 +351,7 @@ func drainCgroup(ctx context.Context, cgroupName string, sig unix.Signal) error return fmt.Errorf("drain group aborted: %w", ctx.Err()) default: buf.Reset() - _, err = f.Seek(0, os.SEEK_SET) + _, err = f.Seek(0, io.SeekStart) if err != nil { return err } diff --git a/cmd/lxcri-hook/hooks.go b/cmd/lxcri-hook/hooks.go index bbe99063..2763797d 100644 --- a/cmd/lxcri-hook/hooks.go +++ b/cmd/lxcri-hook/hooks.go @@ -12,15 +12,15 @@ type HookType string // List of liblxc hook types. const ( HookPreStart HookType = "pre-start" - HookPreMount = "pre-mount" - HookMount = "mount" - HookAutodev = "autodev" - HookStartHost = "start-host" - HookStart = "start" - HookStop = "stop" - HookPostStop = "post-stop" - HookClone = "clone" - HookDestroy = "destroy" + HookPreMount HookType = "pre-mount" + HookMount HookType = "mount" + HookAutodev HookType = "autodev" + HookStartHost HookType = "start-host" + HookStart HookType = "start" + HookStop HookType = "stop" + HookPostStop HookType = "post-stop" + HookClone HookType = "clone" + HookDestroy HookType = "destroy" //HookPostStart = "post-start" // not defined by liblxc ) diff --git a/cmd/lxcri-init/main.go b/cmd/lxcri-init/main.go index 3d62fe1f..0c29b453 100644 --- a/cmd/lxcri-init/main.go +++ b/cmd/lxcri-init/main.go @@ -81,7 +81,7 @@ func doInit(runtimeDir string, spec *specs.Spec) error { } } - val, exist = specki.Getenv(spec.Process.Env, "HOME") + _, exist = specki.Getenv(spec.Process.Env, "HOME") if !exist { addEnvHome(spec) } @@ -144,5 +144,4 @@ func addEnvHome(spec *specs.Spec) { } } spec.Process.Env = append(spec.Process.Env, "HOME="+spec.Process.Cwd) - return } diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index e7cf81a6..aa6afd9a 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -37,8 +37,7 @@ type app struct { Timestamp string } - command string - createHook string + command string } var clxc = app{} @@ -193,13 +192,11 @@ func main() { println(err.Error()) os.Exit(1) } - if env != nil { - for key, val := range env { - if err := setEnv(key, val, false); err != nil { - err = fmt.Errorf("failed to set environment variable \"%s=%s\": %w", key, val, err) - println(err.Error()) - os.Exit(1) - } + for key, val := range env { + if err := setEnv(key, val, false); err != nil { + err = fmt.Errorf("failed to set environment variable \"%s=%s\": %w", key, val, err) + println(err.Error()) + os.Exit(1) } } diff --git a/cmd/lxcri/utils.go b/cmd/lxcri/utils.go index 9e232b9c..9e3c622c 100644 --- a/cmd/lxcri/utils.go +++ b/cmd/lxcri/utils.go @@ -69,33 +69,6 @@ func parseSignal(sig string) unix.Signal { return unix.SignalNum(s) } -/* -func logEnv(log *zerolog.Log) - if env != nil { - stat, _ := os.Stat(envFile) - if stat != nil && (stat.Mode().Perm()^0640) != 0 { - log.Warn().Str("file", envFile).Stringer("mode", stat.Mode().Perm()).Msgf("environment file should have mode %s", os.FileMode(0640)) - } - for key, val := range env { - log.Trace().Str("env", key).Str("val", val).Msg("environment file value") - } - log.Debug().Str("file", envFile).Msg("loaded environment variables from file") - } else { - if os.IsNotExist(envErr) { - log.Warn().Str("file", envFile).Msg("environment file does not exist") - } else { - return errors.Wrapf(envErr, "failed to load env file %s", envFile) - } - } - - for _, f := range ctx.Command.Flags { - name := f.Names()[0] - log.Trace().Str("flag", name).Str("val", ctx.String(name)).Msg("flag value") - } - - } -*/ - // createPidFile atomically creates a pid file for the given pid at the given path func createPidFile(path string, pid int) error { tmpDir := filepath.Dir(path) @@ -120,13 +93,3 @@ func createPidFile(path string, pid int) error { } return nil } - -func readPidFile(path string) (int, error) { - // #nosec - data, err := os.ReadFile(path) - if err != nil { - return 0, err - } - s := strings.TrimSpace(string(data)) - return strconv.Atoi(s) -} diff --git a/container.go b/container.go index 72c70cbc..25b821c7 100644 --- a/container.go +++ b/container.go @@ -162,20 +162,6 @@ func (c *Container) waitNot(ctx context.Context, state specs.ContainerState) err } } -func (c *Container) wait(ctx context.Context, state lxc.State) bool { - for { - select { - case <-ctx.Done(): - return false - default: - if c.LinuxContainer.State() == state { - return true - } - time.Sleep(time.Millisecond * 100) - } - } -} - // State wraps specs.State and adds runtime specific state. type State struct { ContainerState string @@ -247,8 +233,7 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { // init process died or returned return specs.StateStopped, nil } - initCmdline := fmt.Sprintf("/.lxcri/lxcri-init\000") - if string(cmdline) == initCmdline { + if string(cmdline) == "/.lxcri/lxcri-init\000" { return specs.StateCreated, nil } return specs.StateRunning, nil diff --git a/mount.go b/mount.go index 0f6caf6f..ef0ef601 100644 --- a/mount.go +++ b/mount.go @@ -68,7 +68,7 @@ func configureMounts(rt *Runtime, c *Container) error { rt.Log.Trace().Err(err).Str("file", ms.Destination).Str("target", mountDest).Msg("resolve mount destination") // Check whether the resolved destination of the target link escapes the rootfs. - if !filepath.HasPrefix(mountDest, c.Spec.Root.Path) { + if !strings.HasPrefix(mountDest, c.Spec.Root.Path) { // refuses mount destinations that escape from rootfs return fmt.Errorf("resolved mount target path %s escapes from container root %s", mountDest, c.Spec.Root.Path) } @@ -155,7 +155,7 @@ func resolvePathRelative(rootfs string, currentPath string, subPath string) (str // The destination of an absolute link must be prefixed with the rootfs if filepath.IsAbs(linkDst) { - if filepath.HasPrefix(linkDst, rootfs) { + if strings.HasPrefix(linkDst, rootfs) { return p, nil } return filepath.Join(rootfs, linkDst), nil diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 4cceb24b..2d43ba9e 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -185,9 +185,7 @@ func AllowEssentialDevices(spec *specs.Spec) error { } } - for _, perm := range EssentialDevicesAllow { - spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, perm) - } + spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, EssentialDevicesAllow...) return nil } @@ -327,35 +325,6 @@ func InitHook(r io.Reader) (rootfs string, state *specs.State, spec *specs.Spec, return } -// BindMount returns a specs.Mount to bind mount src to dest. -// The given mount options opts are merged with the predefined options -// ("bind", "nosuid", "nodev", "relatime") -func BindMount(src string, dest string, opts ...string) specs.Mount { - return specs.Mount{ - Source: src, Destination: dest, Type: "bind", - Options: append([]string{"bind", "nosuid", "nodev", "relatime"}, opts...), - } -} - -func hasOption(m specs.Mount, opt string) bool { - for _, o := range m.Options { - if o == opt { - return true - } - } - return false -} - -// HasOptions returns true if the given Mount has all provided options opts. -func HasOptions(m specs.Mount, opts ...string) bool { - for _, o := range opts { - if !hasOption(m, o) { - return false - } - } - return true -} - // Getenv returns the first matching value from env, // which has a prefix of key + "=". func Getenv(env []string, key string) (string, bool) { diff --git a/seccomp.go b/seccomp.go index de57cec0..a1630b18 100644 --- a/seccomp.go +++ b/seccomp.go @@ -91,7 +91,7 @@ func seccompArchs(seccomp *specs.LinuxSeccomp) ([]string, error) { } archs := make([]string, len(seccomp.Architectures)) for _, a := range seccomp.Architectures { - s := strings.ToLower(strings.TrimLeft(string(a), "SCMP_ARCH_")) + s := strings.ToLower(strings.TrimPrefix(string(a), "SCMP_ARCH_")) if strings.ToLower(nativeArch) == s { // lxc seccomp code automatically adds syscalls to compat architectures return []string{nativeArch}, nil diff --git a/utils.go b/utils.go index d2254244..f5c961d9 100644 --- a/utils.go +++ b/utils.go @@ -6,7 +6,6 @@ import ( "os" "path/filepath" "runtime" - "strings" "golang.org/x/sys/unix" ) @@ -60,15 +59,3 @@ func errorf(sfmt string, args ...interface{}) error { prefix := fmt.Sprintf("[%s:%s:%d] ", bin, filepath.Base(file), line) return fmt.Errorf(prefix+sfmt, args...) } - -func setenv(env []string, key, val string, overwrite bool) []string { - for i, kv := range env { - if strings.HasPrefix(kv, key+"=") { - if overwrite { - env[i] = key + "=" + val - } - return env - } - } - return append(env, key+"="+val) -} From 2d3ebd52b9415d8e3bd270ad7d4b8639540434a1 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Fri, 16 Apr 2021 21:11:52 +0200 Subject: [PATCH 337/373] Update package documentation. Signed-off-by: Ruben Jenster --- pkg/log/log.go | 1 + pkg/specki/specki.go | 3 +-- runtime.go | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/log/log.go b/pkg/log/log.go index 001ad006..7662b28a 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,3 +1,4 @@ +// Package log provides logging for lxcri. package log import ( diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 2d43ba9e..831baa90 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -1,5 +1,4 @@ -// Package specki containse general-purpose helper functions that operate -// on (parts of) the runtime spec (specs.Spec). +// Package specki provides helper functions to process OCI container specs. // These functions should not contain any code that is `lxcri` specific. package specki diff --git a/runtime.go b/runtime.go index 2b50429a..c11a9bd6 100644 --- a/runtime.go +++ b/runtime.go @@ -1,3 +1,4 @@ +// Package lxcri provides an OCI specific runtime interface for lxc. package lxcri import ( From 5d9f67101b2428132625525edd704804dbda6323 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 17 Apr 2021 08:39:27 +0200 Subject: [PATCH 338/373] Rework kill cgroup procs. Use cgroup.freeze. Signed-off-by: Ruben Jenster --- cgroup.go | 273 +++++++++++++++++++++++++----------------------- container.go | 30 +----- runtime.go | 30 +++--- runtime_test.go | 3 +- 4 files changed, 162 insertions(+), 174 deletions(-) diff --git a/cgroup.go b/cgroup.go index d6637552..171561fd 100644 --- a/cgroup.go +++ b/cgroup.go @@ -1,19 +1,18 @@ package lxcri import ( - "bytes" "context" "fmt" - "io" + "io/fs" "os" "path/filepath" "strconv" "strings" "time" - "golang.org/x/sys/unix" - + //"github.com/fsnotify/fsnotify" "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" ) var cgroupRoot string @@ -87,46 +86,35 @@ func configureCgroupPath(rt *Runtime, c *Container) error { c.CgroupDir = c.Spec.Linux.CgroupsPath } - c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") - if err := c.SetConfigItem("lxc.cgroup.relative", "0"); err != nil { return err } - if err := c.SetConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { - return err + // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb + // checking for on of the config items shuld be enough, because they were introduced together ... + // lxc.cgroup.dir.payload and lxc.cgroup.dir.monitor + splitCgroup := c.SupportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") + + if !splitCgroup || rt.MonitorCgroup == "" { + return c.SetConfigItem("lxc.cgroup.dir", c.CgroupDir) } - /* - if c.SupportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroupDir); err != nil { - return err - } - } - */ + c.MonitorCgroupDir = filepath.Join(rt.MonitorCgroup, c.ContainerID+".scope") - /* - // @since lxc @a900cbaf257c6a7ee9aa73b09c6d3397581d38fb - // checking for on of the config items shuld be enough, because they were introduced together ... - if supportsConfigItem("lxc.cgroup.dir.container", "lxc.cgroup.dir.monitor") { - if err := c.SetConfigItem("lxc.cgroup.dir.container", c.CgroupDir); err != nil { - return err - } - if err := c.SetConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroupDir); err != nil { - return err - } - } else { - if err := c.SetConfigItem("lxc.cgroup.dir", c.CgroupDir); err != nil { - return err - } - } - if supportsConfigItem("lxc.cgroup.dir.monitor.pivot") { - if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", c.MonitorCgroup); err != nil { - return err - } + if err := c.SetConfigItem("lxc.cgroup.dir.container", c.CgroupDir); err != nil { + return err + } + if err := c.SetConfigItem("lxc.cgroup.dir.monitor", c.MonitorCgroupDir); err != nil { + return err + } + + if c.SupportsConfigItem("lxc.cgroup.dir.monitor.pivot") { + if err := c.SetConfigItem("lxc.cgroup.dir.monitor.pivot", rt.MonitorCgroup); err != nil { + return err } - */ + } return nil + } func configureDeviceController(c *Container) error { @@ -250,137 +238,157 @@ func parseSystemdCgroupPath(s string) string { return filepath.Join(cgPath...) } -type cgroupInfo struct { - Name string - Procs []int - // controllers -} +// killCgroup freezes the cgroups of the given container +// and sends the given signal sig to all cgroup members. +func killCgroup(ctx context.Context, c *Container, sig unix.Signal) error { + if c.CgroupDir == "" { + return nil + } + rootDir := filepath.Join(cgroupRoot, c.CgroupDir) + eventsFile := filepath.Join(rootDir, "cgroup.events") -func (cg *cgroupInfo) loadProcs() error { - cgroupProcsPath := filepath.Join(cgroupRoot, cg.Name, "cgroup.procs") - // #nosec - procsData, err := os.ReadFile(cgroupProcsPath) + ev, err := parseCgroupEvents(eventsFile) if err != nil { - return fmt.Errorf("failed to read cgroup.procs: %w", err) + return err } - // cgroup.procs contains one PID per line and is newline separated. - // A trailing newline is always present. - s := strings.TrimSpace(string(procsData)) - if s == "" { + if !ev.populated { return nil } - pidStrings := strings.Split(s, "\n") - cg.Procs = make([]int, 0, len(pidStrings)) - for _, s := range pidStrings { - pid, err := strconv.Atoi(s) - if err != nil { - return fmt.Errorf("failed to convert PID %q to number: %w", s, err) - } - cg.Procs = append(cg.Procs, pid) - } - return nil -} -func loadCgroup(cgName string) (*cgroupInfo, error) { - info := &cgroupInfo{Name: cgName} - if err := info.loadProcs(); err != nil { - return nil, err + freezer := filepath.Join(rootDir, "cgroup.freeze") + + err = cgroupFreeze(freezer, true) + if err != nil { + return err } - return info, nil -} -func killCgroupProcs(cgroupName string, sig unix.Signal) error { - cg, err := loadCgroup(cgroupName) + err = pollCgroupEvents(ctx, eventsFile, func(ev cgroupEvents) bool { + return ev.frozen + }) if err != nil { - return fmt.Errorf("failed to load cgroup %s: %w", cgroupName, err) + return err } - for _, pid := range cg.Procs { - err := unix.Kill(pid, sig) - if err != nil && err != unix.ESRCH { - return fmt.Errorf("failed to kill %d: %w", pid, err) + + err = filepath.Walk(rootDir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err } - } + if info.Name() != "cgroup.procs" { + return nil + } + procsData, err := os.ReadFile(path) + if err != nil { + return err + } + // cgroup.procs contains one PID per line and is newline separated. + // A trailing newline is always present. + s := strings.TrimSpace(string(procsData)) + if s == "" { + return nil + } + vals := strings.Split(s, "\n") - dirName := filepath.Join(cgroupRoot, cgroupName) - // #nosec - dir, err := os.Open(dirName) - if os.IsNotExist(err) { + c.Log.Debug().Msgf("killing %d cgroup procs: %s", len(vals), vals) + for _, s := range vals { + pid, err := strconv.Atoi(s) + if err != nil { + c.Log.Error().Msgf("failed to convert PID %q to number: %s", s, err) + continue + } + // do not kill the monitor process + if pid == c.Pid { + continue + } + err = unix.Kill(pid, sig) + if err != nil && err != unix.ESRCH { + c.Log.Error().Msgf("failed to kill %d: %s", pid, err) + continue + } + } return nil - } + }) + if err != nil { return err } - entries, err := dir.Readdir(-1) - if err := dir.Close(); err != nil { - return err - } + + err = cgroupFreeze(freezer, false) if err != nil { return err } - for _, i := range entries { - if i.IsDir() && i.Name() != "." && i.Name() != ".." { - err := killCgroupProcs(filepath.Join(cgroupName, i.Name()), sig) - if err != nil { - return err - } - } - } + return nil } -// see http://morningcoffee.io/killing-a-process-and-all-of-its-descendants.html -// TODO maybe use polling instead -// fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} -// n, err := unix.Poll(fds, timeout) -func drainCgroup(ctx context.Context, cgroupName string, sig unix.Signal) error { - p := filepath.Join(cgroupRoot, cgroupName, "cgroup.events") - f, err := os.OpenFile(p, os.O_RDONLY, 0) - if os.IsNotExist(err) { - return nil +type cgroupEvents struct { + frozen bool + populated bool +} + +func parseCgroupEvents(filename string) (cgroupEvents, error) { + ev := cgroupEvents{} + data, err := os.ReadFile(filename) + if err != nil { + return ev, err + } + lines := strings.Split(string(data), "\n") + for _, line := range lines { + switch line { + case "populated 0": + ev.populated = false + case "populated 1": + ev.populated = true + case "frozen 0": + ev.frozen = false + case "frozen 1": + ev.frozen = true + } } + return ev, nil +} + +func cgroupFreeze(filename string, freeze bool) error { + f, err := os.OpenFile(filename, os.O_WRONLY, 0) if err != nil { return err } + defer f.Close() + if freeze { + _, err = f.Write([]byte("1")) + } else { + _, err = f.Write([]byte("0")) + } + return err +} - var buf bytes.Buffer - buf.Grow(64) - +func pollCgroupEvents(ctx context.Context, eventsFile string, fn func(ev cgroupEvents) bool) error { for { select { case <-ctx.Done(): - return fmt.Errorf("drain group aborted: %w", ctx.Err()) + return ctx.Err() default: - buf.Reset() - _, err = f.Seek(0, io.SeekStart) + ev, err := parseCgroupEvents(eventsFile) if err != nil { return err } - _, err := buf.ReadFrom(f) - if err != nil { - return err + if fn(ev) { + return nil } - - for _, line := range strings.Split(buf.String(), "\n") { - if line == "populated 0" { - return nil - } - } - err = killCgroupProcs(cgroupName, sig) - if err != nil { - return fmt.Errorf("failed to kill cgroup procs: %w", err) - } - time.Sleep(time.Millisecond * 50) + time.Sleep(time.Millisecond * 5) } } } func deleteCgroup(cgroupName string) error { + return deleteCgroupRecursive(cgroupName, 0, 10) +} + +func deleteCgroupRecursive(cgroupName string, level, max int) error { + if level == max { + return fmt.Errorf("reached max recursion of %d", max) + } dirName := filepath.Join(cgroupRoot, cgroupName) - // #nosec dir, err := os.Open(dirName) - if os.IsNotExist(err) { - return nil - } if err != nil { return err } @@ -392,12 +400,17 @@ func deleteCgroup(cgroupName string) error { return err } for _, i := range entries { - if i.IsDir() && i.Name() != "." && i.Name() != ".." { - p := filepath.Join(dirName, i.Name()) - err := unix.Rmdir(p) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to rmdir %s: %w", p, err) - } + if !i.IsDir() { + continue + } + name := i.Name() + if name == "." || name == ".." { + continue + } + childGroup := filepath.Join(cgroupName, name) + err := deleteCgroupRecursive(childGroup, level+1, max) + if err != nil { + return err } } return unix.Rmdir(dirName) diff --git a/container.go b/container.go index 25b821c7..0089a764 100644 --- a/container.go +++ b/container.go @@ -242,38 +242,14 @@ func (c *Container) getContainerInitState() (specs.ContainerState, error) { func (c *Container) kill(ctx context.Context, signum unix.Signal) error { c.Log.Info().Int("signum", int(signum)).Msg("killing container process") - // TODO(race condition) check whether it is save to signal InitPid() - // To avoid that the PID of the init process is recycled we aquire the pidfd of it. - // The container init process may have already died here and if the PID is already recycled, - // the wrong process will be signaled. If the kernel is recent enough. - // to support pidfd_send_signal (only kernel > 5.6 ?) - pidfd, err := c.LinuxContainer.InitPidFd() - if err != nil { - // since this is best-effort we won't return an error - c.Log.Warn().Msgf("failed to get init pidfd: %s", err) - } else { - defer pidfd.Close() - } - // From `man pid_namespaces`: If the "init" process of a PID namespace terminates, the kernel // terminates all of the processes in the namespace via a SIGKILL signal. - // So there is nothing more to do here than to signal the init process. // NOTE: The liblxc monitor process `lxcri-start` doesn't propagate all signals to the init process, // but handles some signals on its own. E.g SIGHUP tells the monitor process to hang up the terminal // and terminate the init process with SIGTERM. - pid := c.LinuxContainer.InitPid() - if pid <= 1 { - return nil - } - - c.Log.Info().Int("pid", pid).Int("signal", int(signum)).Msg("sending signal") - err = unix.Kill(pid, signum) - if err == unix.ESRCH { - // init already died before sending the signal - not an error - return nil - } - if err != nil { - return fmt.Errorf("failed to send signal %d to container process %d: %w", signum, pid, err) + err := killCgroup(ctx, c, signum) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to kill group: %s", err) } return nil } diff --git a/runtime.go b/runtime.go index c11a9bd6..4014a19c 100644 --- a/runtime.go +++ b/runtime.go @@ -373,17 +373,6 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e } } - // FIXME move this to lxcri-hook ? - if c.CgroupDir != "" { - // In rare cases processes might escape from kill. - // This could happens if the container does not use pid_namespaces. - // Since every container get's it's own cgroup, we can - // try to kill all processes within the containers cgroup tree. - if err := drainCgroup(ctx, c.CgroupDir, unix.SIGKILL); err != nil { - rt.Log.Debug().Msgf("failed to drain cgroup: %s", err) - } - } - // From OCI runtime spec // "Note that resources associated with the container, but not // created by this container, MUST NOT be deleted." @@ -392,11 +381,20 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e if err := c.LinuxContainer.Destroy(); err != nil { return fmt.Errorf("failed to destroy container: %w", err) } - if c.CgroupDir != "" { - err := deleteCgroup(c.CgroupDir) - if err != nil && !os.IsNotExist(err) { - return err - } + + // the monitor might be part of the cgroup so wait for it to exit + eventsFile := filepath.Join(cgroupRoot, c.CgroupDir, "cgroup.events") + err = pollCgroupEvents(ctx, eventsFile, func(ev cgroupEvents) bool { + return !ev.populated + }) + if err != nil && !os.IsNotExist(err) { + // try to delete the cgroup anyways + c.Log.Warn().Msgf("failed to wait until cgroup.events populated=0: %s", err) + } + + err = deleteCgroup(c.CgroupDir) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to delete cgroup: %s", err) } if c.Spec.Hooks != nil { diff --git a/runtime_test.go b/runtime_test.go index 7a195613..b045feba 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -34,6 +34,7 @@ func newRuntime(t *testing.T) *Runtime { Log: log.ConsoleLogger(true), Root: runtimeRoot, LibexecDir: os.Getenv("LIBEXEC_DIR"), + //MonitorCgroup: "lxcri-monitor.slice", } if rt.LibexecDir == "" { rt.LibexecDir = "/usr/local/libexec/lxcri" @@ -55,7 +56,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { spec := specki.NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true)} - cfg.Spec.Linux.CgroupsPath = "" // use /proc/self/cgroup" + cfg.Spec.Linux.CgroupsPath = id + ".slice" // use /proc/self/cgroup" cfg.LogFile = "/dev/stderr" cfg.LogLevel = "trace" From 9dcd37b5ef4aa982905c72743ca34ab18d343c82 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 17 Apr 2021 13:02:47 +0200 Subject: [PATCH 339/373] cli: Fix delete timeout. Signed-off-by: Ruben Jenster --- cmd/lxcri/cli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lxcri/cli.go b/cmd/lxcri/cli.go index aa6afd9a..41deeadd 100644 --- a/cmd/lxcri/cli.go +++ b/cmd/lxcri/cli.go @@ -457,7 +457,7 @@ var deleteCmd = cli.Command{ Name: "force", Usage: "force deletion", }, - &cli.DurationFlag{ + &cli.UintFlag{ Name: "timeout", Usage: "maximum duration in seconds for delete to complete", EnvVars: []string{"LXCRI_DELETE_TIMEOUT"}, From ca37f3020a6ce3d88907505715f9c5721ad9a30e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sat, 17 Apr 2021 13:03:56 +0200 Subject: [PATCH 340/373] Initialize Container.Log with Runtime.Log on Load. Signed-off-by: Ruben Jenster --- runtime.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime.go b/runtime.go index 4014a19c..7ae2e652 100644 --- a/runtime.go +++ b/runtime.go @@ -101,7 +101,6 @@ func (rt *Runtime) hasCapability(s string) bool { // Unsupported runtime features are disabled and a warning message is logged. // Init must be called once for a runtime instance before calling any other method. func (rt *Runtime) Init() error { - caps, err := capability.NewPid2(0) if err != nil { return errorf("failed to create capabilities object: %w", err) @@ -197,14 +196,17 @@ func (rt *Runtime) keepEnv(names ...string) { // Load loads a container from the runtime directory. // The container must have been created with Runtime.Create. +// The logger Container.Log is set to Runtime.Log by default. func (rt *Runtime) Load(containerID string) (*Container, error) { dir := filepath.Join(rt.Root, containerID) if _, err := os.Stat(dir); os.IsNotExist(err) { return nil, ErrNotExist } c := &Container{ - ContainerConfig: &ContainerConfig{}, - runtimeDir: dir, + ContainerConfig: &ContainerConfig{ + Log: rt.Log, + }, + runtimeDir: dir, } if err := c.load(); err != nil { return nil, err From 9238c1486971ea7308f6375a2807fffb5d84bf85 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 18 Apr 2021 10:36:50 +0200 Subject: [PATCH 341/373] Ensure hostname is not set if uts namepace is shared with host. Signed-off-by: Ruben Jenster --- create.go | 42 +++++++++++++++++++++++++++++++----------- namespaces.go | 39 +++++++++++++++++++++++++-------------- runtime.go | 6 +++--- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/create.go b/create.go index a17686d5..366deb6f 100644 --- a/create.go +++ b/create.go @@ -73,17 +73,8 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container } func configureContainer(rt *Runtime, c *Container) error { - if c.Spec.Hostname != "" { - if err := c.SetConfigItem("lxc.uts.name", c.Spec.Hostname); err != nil { - return err - } - - uts := getNamespace(specs.UTSNamespace, c.Spec.Linux.Namespaces) - if uts != nil && uts.Path != "" { - if err := setHostname(uts.Path, c.Spec.Hostname); err != nil { - return fmt.Errorf("failed to set hostname: %w", err) - } - } + if err := configureHostname(rt, c); err != nil { + return err } if err := configureRootfs(rt, c); err != nil { @@ -238,6 +229,35 @@ func configureContainer(rt *Runtime, c *Container) error { return nil } +func configureHostname(rt *Runtime, c *Container) error { + if c.Spec.Hostname == "" { + return nil + } + if err := c.SetConfigItem("lxc.uts.name", c.Spec.Hostname); err != nil { + return err + } + + // Check if UTS namespace is shared, but not with the host. + uts := getNamespace(c.Spec, specs.UTSNamespace) + if uts == nil { + return nil + } + + yes, err := isNamespaceSharedWithHost(uts) + if err != nil { + return errorf("failed to check if uts namespace is shared with host: %w", err) + } + if yes { + return nil + } + + // Set the hostname on shared UTS namespace, since liblxc doesn't do it. + if err := setHostname(uts.Path, c.Spec.Hostname); err != nil { + return fmt.Errorf("failed to set hostname: %w", err) + } + return nil +} + func configureRootfs(rt *Runtime, c *Container) error { rootfs := c.Spec.Root.Path if !filepath.IsAbs(rootfs) { diff --git a/namespaces.go b/namespaces.go index ab2a1916..63ca6cbc 100644 --- a/namespaces.go +++ b/namespaces.go @@ -90,11 +90,31 @@ func isNamespaceEnabled(spec *specs.Spec, nsType specs.LinuxNamespaceType) bool return false } -// isHostNamespaceUsed returns true if a container created with the given list of -// namespaces will use the host namespace of the given namespace type. -func isHostNamespaceShared(namespaces []specs.LinuxNamespace, nsType specs.LinuxNamespaceType) (bool, error) { - ns := getNamespace(nsType, namespaces) - // no namespace with this name defined in list +func getNamespace(spec *specs.Spec, nsType specs.LinuxNamespaceType) *specs.LinuxNamespace { + for _, n := range spec.Linux.Namespaces { + if n.Type == nsType { + return &n + } + } + return nil +} + +// isNamespaceCloned returns true if the given namespace +// is not nil and the namespace path it not empty. +func isNamespaceCloned(ns *specs.LinuxNamespace) bool { + if ns == nil { + return false + } + return ns.Path == "" +} + +// isNamespaceSharedWithHost returns true if the given namespace is nil. +// If the given namespace is not nil then the namespace then true is +// returned if the namespace path refers to the host namespace and +// false otherwise. +// Should be used with isNamespaceSharedWithHost(getNamespace(...)) +func isNamespaceSharedWithHost(ns *specs.LinuxNamespace) (bool, error) { + // no namespace with this name defined if ns == nil { return true, nil } @@ -127,15 +147,6 @@ func isHostNamespaceShared(namespaces []specs.LinuxNamespace, nsType specs.Linux return sameNS, nil } -func getNamespace(nsType specs.LinuxNamespaceType, namespaces []specs.LinuxNamespace) *specs.LinuxNamespace { - for _, n := range namespaces { - if n.Type == nsType { - return &n - } - } - return nil -} - // lxc does not set the hostname on shared namespaces func setHostname(nsPath string, hostname string) error { // setns only affects the current thread diff --git a/runtime.go b/runtime.go index 7ae2e652..774d4027 100644 --- a/runtime.go +++ b/runtime.go @@ -166,7 +166,7 @@ func (rt *Runtime) checkSpec(spec *specs.Spec) error { spec.Process.Cwd = "/" } - yes, err := isHostNamespaceShared(spec.Linux.Namespaces, specs.MountNamespace) + yes, err := isNamespaceSharedWithHost(getNamespace(spec, specs.MountNamespace)) if err != nil { return err } @@ -176,12 +176,12 @@ func (rt *Runtime) checkSpec(spec *specs.Spec) error { // It should be best practise not to do so, but there are containers that // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set - yes, err = isHostNamespaceShared(spec.Linux.Namespaces, specs.PIDNamespace) + yes, err = isNamespaceSharedWithHost(getNamespace(spec, specs.PIDNamespace)) if err != nil { return err } if yes { - rt.Log.Info().Msg("container wil share the hosts PID namespace") + rt.Log.Warn().Msg("container wil share the hosts PID namespace") } return nil } From 0603214c362243b88843030119fb0fd77bc5f525 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 18 Apr 2021 11:28:12 +0200 Subject: [PATCH 342/373] Wait for lxc.STOPPED if deleting container with force=yes Signed-off-by: Ruben Jenster --- container.go | 14 ++++++++++++++ runtime.go | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/container.go b/container.go index 0089a764..b54b10c0 100644 --- a/container.go +++ b/container.go @@ -123,6 +123,20 @@ func (c *Container) load() error { return nil } +func (c *Container) wait(ctx context.Context, state lxc.State) bool { + for { + select { + case <-ctx.Done(): + return false + default: + if c.LinuxContainer.State() == state { + return true + } + time.Sleep(time.Millisecond * 100) + } + } +} + func (c *Container) waitCreated(ctx context.Context) error { for { select { diff --git a/runtime.go b/runtime.go index 774d4027..3d4de0bb 100644 --- a/runtime.go +++ b/runtime.go @@ -373,6 +373,10 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e if err := c.kill(ctx, unix.SIGKILL); err != nil { return errorf("failed to kill container: %w", err) } + // wait until stopped + if !c.wait(ctx, lxc.STOPPED) { + return errorf("container not stopped") + } } // From OCI runtime spec From e63c034a7269aa4b4ccaef926a0a651e7c29394f Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 18 Apr 2021 11:56:15 +0200 Subject: [PATCH 343/373] Refuse to create container if cgroup is non-empty. Signed-off-by: Ruben Jenster --- cgroup.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cgroup.go b/cgroup.go index 171561fd..f1497192 100644 --- a/cgroup.go +++ b/cgroup.go @@ -39,6 +39,15 @@ func configureCgroup(rt *Runtime, c *Container) error { return err } + // refuse to run in a non-empty cgroup + ev, err := parseCgroupEvents(filepath.Join(cgroupRoot, c.CgroupDir, "cgroup.events")) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to parse cgroup events: %w", err) + } + if err == nil && ev.populated { + return fmt.Errorf("container cgroup %s is not empty", c.CgroupDir) + } + if devices := c.Spec.Linux.Resources.Devices; devices != nil { if rt.Features.CgroupDevices { if err := configureDeviceController(c); err != nil { From 157aed503345fbc3008c00f668e4de7be278d349 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Sun, 18 Apr 2021 11:57:30 +0200 Subject: [PATCH 344/373] Add more runtime tests. Signed-off-by: Ruben Jenster --- runtime_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index b045feba..30221920 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -44,6 +44,9 @@ func newRuntime(t *testing.T) *Runtime { return rt } +// NOTE a container that was created successfully must always be +// deleted, otherwise the go test runner will hang because it waits +// for the container process to exit. func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { rootfs, err := mkdirTemp() require.NoError(t, err) @@ -79,17 +82,66 @@ func TestEmptyNamespaces(t *testing.T) { c, err := rt.Create(ctx, cfg) require.Error(t, err) + t.Logf("create error: %s", err) require.Nil(t, c) +} + +func TestSharedPIDNamespace(t *testing.T) { + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Spec.Root.Path) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() pidns := specs.LinuxNamespace{ Type: specs.PIDNamespace, Path: fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()), } - cfg.Spec.Linux.Namespaces = append(cfg.Spec.Linux.Namespaces, pidns) - c, err = rt.Create(ctx, cfg) + for i, ns := range cfg.Spec.Linux.Namespaces { + if ns.Type == specs.PIDNamespace { + cfg.Spec.Linux.Namespaces[i] = pidns + } + } + + c, err := rt.Create(ctx, cfg) + require.Nil(t, err) + require.NotNil(t, c) + + err = rt.Delete(ctx, c.ContainerID, true) + require.NoError(t, err) +} + +// TODO test uts namespace (shared with host) + +func TestNonEmptyCgroup(t *testing.T) { + rt := newRuntime(t) + defer os.RemoveAll(rt.Root) + + cfg := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Spec.Root.Path) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + c, err := rt.Create(ctx, cfg) + require.NoError(t, err) + require.NotNil(t, c) + + cfg2 := newConfig(t, "lxcri-test") + defer os.RemoveAll(cfg.Spec.Root.Path) + cfg2.Spec.Linux.CgroupsPath = cfg.Spec.Linux.CgroupsPath + + c2, err := rt.Create(ctx, cfg2) require.Error(t, err) - require.Nil(t, c) + t.Logf("create error: %s", err) + require.NotNil(t, c2) + + err = rt.Delete(ctx, c.ContainerID, true) + require.NoError(t, err) } func TestRuntimePrivileged(t *testing.T) { From 7d54680da47c692f15f85ee9a803ef680072756e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 08:49:58 +0200 Subject: [PATCH 345/373] actions: Run staticcheck Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2082269..f2493e1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,6 +32,11 @@ jobs: GO111MODULE=off go get -u golang.org/x/lint/golint golint -set_exit_status ./... + - name: Run staticcheck + run: | + GO111MODULE=off go get -u honnef.co/go/tools/cmd/staticcheck + staticcheck --unused.whole-program=true -- ./... + - name: Install dependencies run: | sudo add-apt-repository ppa:ubuntu-lxc/daily -y From ebd98549b89dc12d958319c776cc62bf06cf5e92 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 08:50:13 +0200 Subject: [PATCH 346/373] actions: Remove musl build dependency Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2493e1b..49d447eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: - name: Install dependencies run: | sudo add-apt-repository ppa:ubuntu-lxc/daily -y - sudo apt-get install -qq lxc-dev musl musl-tools libc6-dev pkg-config make + sudo apt-get install -qq lxc-dev libc6-dev pkg-config make - name: Build run: | From 8db1419136e76f4f84abd3547e544c348bcf154a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 09:50:00 +0200 Subject: [PATCH 347/373] Fix namespace check if runtime is unprivileged. Signed-off-by: Ruben Jenster --- create.go | 2 +- namespaces.go | 4 ++-- runtime.go | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/create.go b/create.go index 366deb6f..a09e0c91 100644 --- a/create.go +++ b/create.go @@ -243,7 +243,7 @@ func configureHostname(rt *Runtime, c *Container) error { return nil } - yes, err := isNamespaceSharedWithHost(uts) + yes, err := isNamespaceSharedWithRuntime(uts) if err != nil { return errorf("failed to check if uts namespace is shared with host: %w", err) } diff --git a/namespaces.go b/namespaces.go index 63ca6cbc..c573e2da 100644 --- a/namespaces.go +++ b/namespaces.go @@ -113,7 +113,7 @@ func isNamespaceCloned(ns *specs.LinuxNamespace) bool { // returned if the namespace path refers to the host namespace and // false otherwise. // Should be used with isNamespaceSharedWithHost(getNamespace(...)) -func isNamespaceSharedWithHost(ns *specs.LinuxNamespace) (bool, error) { +func isNamespaceSharedWithRuntime(ns *specs.LinuxNamespace) (bool, error) { // no namespace with this name defined if ns == nil { return true, nil @@ -138,7 +138,7 @@ func isNamespaceSharedWithHost(ns *specs.LinuxNamespace) (bool, error) { } var stat1 unix.Stat_t - err = unix.Stat("/proc/1/ns/pid", &stat1) + err = unix.Stat("/proc/self/ns/pid", &stat1) if err != nil { return false, err } diff --git a/runtime.go b/runtime.go index 3d4de0bb..f10fb320 100644 --- a/runtime.go +++ b/runtime.go @@ -166,9 +166,9 @@ func (rt *Runtime) checkSpec(spec *specs.Spec) error { spec.Process.Cwd = "/" } - yes, err := isNamespaceSharedWithHost(getNamespace(spec, specs.MountNamespace)) + yes, err := isNamespaceSharedWithRuntime(getNamespace(spec, specs.MountNamespace)) if err != nil { - return err + return errorf("failed to mount namespace: %s", err) } if yes { return errorf("container wants to share the hosts mount namespace") @@ -176,9 +176,9 @@ func (rt *Runtime) checkSpec(spec *specs.Spec) error { // It should be best practise not to do so, but there are containers that // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set - yes, err = isNamespaceSharedWithHost(getNamespace(spec, specs.PIDNamespace)) + yes, err = isNamespaceSharedWithRuntime(getNamespace(spec, specs.PIDNamespace)) if err != nil { - return err + return errorf("failed to check PID namespace: %s", err) } if yes { rt.Log.Warn().Msg("container wil share the hosts PID namespace") From afe6522dd8ae37c8f435c0117ad7eada280b0e4a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:12:10 +0200 Subject: [PATCH 348/373] fix serialization. Signed-off-by: Ruben Jenster --- create.go | 6 ------ runtime.go | 13 ++++++++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/create.go b/create.go index a09e0c91..92ab5cfe 100644 --- a/create.go +++ b/create.go @@ -63,12 +63,6 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to run container process: %w", err) } - p := c.RuntimePath("lxcri.json") - err = specki.EncodeJSONFile(p, c, os.O_EXCL|os.O_CREATE, 0440) - if err != nil { - return c, err - } - return c, err } diff --git a/runtime.go b/runtime.go index f10fb320..c90aa8c7 100644 --- a/runtime.go +++ b/runtime.go @@ -279,6 +279,16 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { return err } + c.CreatedAt = time.Now() + c.Pid = cmd.Process.Pid + rt.Log.Info().Int("pid", cmd.Process.Pid).Msg("monitor process started") + + p := c.RuntimePath("lxcri.json") + err = specki.EncodeJSONFile(p, c, os.O_EXCL|os.O_CREATE, 0440) + if err != nil { + return err + } + ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -287,9 +297,6 @@ func (rt *Runtime) runStartCmd(ctx context.Context, c *Container) (err error) { return err } - rt.Log.Info().Int("pid", cmd.Process.Pid).Msg("init process is running, container is created") - c.CreatedAt = time.Now() - c.Pid = cmd.Process.Pid return nil } From 8acd003fe007dfb09f2317fd1f607cc434e1e45d Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:13:49 +0200 Subject: [PATCH 349/373] Improve logging of SetConfigItem Signed-off-by: Ruben Jenster --- container.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/container.go b/container.go index b54b10c0..cdcb52ae 100644 --- a/container.go +++ b/container.go @@ -290,7 +290,7 @@ func (c *Container) SetConfigItem(key, value string) error { if err != nil { return fmt.Errorf("failed to set config item '%s=%s': %w", key, value, err) } - c.Log.Debug().Str("lxc.config", key).Str("val", value).Msg("set config item") + c.Log.Debug().Str(key, value).Msg("set config item") return nil } From 87bad9c0643c75983762a8ce5bfb82d08630eed2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:15:06 +0200 Subject: [PATCH 350/373] Mirror zerolog log levels. Add log level to ConsoleLogger. Signed-off-by: Ruben Jenster --- pkg/log/log.go | 15 +++++++++++++-- runtime_test.go | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/log/log.go b/pkg/log/log.go index 7662b28a..18118723 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -13,6 +13,17 @@ import ( "github.com/rs/zerolog" ) +// zerlog log levels are mirrored for convenience. +const ( + TraceLevel = zerolog.TraceLevel + DebugLevel = zerolog.DebugLevel + InfoLevel = zerolog.InfoLevel + WarnLevel = zerolog.WarnLevel + ErrorLevel = zerolog.ErrorLevel + FatalLevel = zerolog.FatalLevel + PanicLevel = zerolog.PanicLevel +) + func init() { zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" @@ -56,6 +67,6 @@ func NewLogger(out io.Writer, level zerolog.Level) zerolog.Context { } // ConsoleLogger returns a new zerlog.Logger suited for console usage (e.g unit tests) -func ConsoleLogger(color bool) zerolog.Logger { - return zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: !color}).Level(zerolog.DebugLevel).With().Timestamp().Caller().Logger() +func ConsoleLogger(color bool, level zerolog.Level) zerolog.Logger { + return zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: !color}).Level(level).With().Timestamp().Caller().Logger() } diff --git a/runtime_test.go b/runtime_test.go index 30221920..c6d8bba8 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -31,7 +31,7 @@ func newRuntime(t *testing.T) *Runtime { require.NoError(t, err) rt := &Runtime{ - Log: log.ConsoleLogger(true), + Log: log.ConsoleLogger(true, log.TraceLevel), Root: runtimeRoot, LibexecDir: os.Getenv("LIBEXEC_DIR"), //MonitorCgroup: "lxcri-monitor.slice", @@ -58,7 +58,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { spec := specki.NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) - cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true)} + cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true, log.TraceLevel)} cfg.Spec.Linux.CgroupsPath = id + ".slice" // use /proc/self/cgroup" cfg.LogFile = "/dev/stderr" cfg.LogLevel = "trace" From 0b1a9d1c103704f733b4f1a78b49074b0c4347c7 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:23:23 +0200 Subject: [PATCH 351/373] Consume process state of exited child processes. Signed-off-by: Ruben Jenster --- runtime.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/runtime.go b/runtime.go index c90aa8c7..665c0fcd 100644 --- a/runtime.go +++ b/runtime.go @@ -7,6 +7,7 @@ import ( "net" "os" "os/exec" + "os/signal" "path/filepath" "time" @@ -19,6 +20,39 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) +// waitForChildren consumes the process state of any exited child processes. +// +// Background: +// The `lxcri-start` process is reparented if the runtime process dies. +// It is reparented to either a parent subreaper process (see `man prctl` PR_SET_CHILD_SUBREAPER), +// e.g conmon if the runtime was executed from cri-o, or directly to init (pid 1, e.g systemd). +// Any (`lxcri-start`) child process that exits before the runtime will become orphaned / a zombie process. +// The runtime has consume the process state of any (`lxcri-start`) child processes which exited +// to avoid this. +// +// NOTE that unix.Kill(, 0) will return with success as long as the process state +// of `` was not consumed with wait4|waitpid. +func waitForChildren() { + // Set up channel on which to send signal notifications. + // We must use a buffered channel or risk missing the signal + // if we're not ready to receive when the signal is sent. + c := make(chan os.Signal, 1) + signal.Notify(c, unix.SIGCHLD) + + for range c { + // The manpage for 'wait4' suggests to use waitpid or waitid instead, but + // golang/x/sys/unix only implements 'Wait4'. See https://github.com/golang/go/issues/9176 + // since lxcri-start creates a new session / process group with setsid + // we have to wait for any child process ('-1') + //var ws unix.WaitStatus + unix.Wait4(-1, nil, unix.WNOHANG, nil) + } +} + +func init() { + go waitForChildren() +} + const ( // BundleConfigFile is the name of the OCI container bundle config file. // The content is the JSON encoded specs.Spec. From 2f458fcd2c467b04254f3097d8c00f53a7d54e70 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:24:15 +0200 Subject: [PATCH 352/373] Check if container process died in Create and Start. Signed-off-by: Ruben Jenster --- container.go | 18 +++++++++++------- runtime.go | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/container.go b/container.go index cdcb52ae..64668c3f 100644 --- a/container.go +++ b/container.go @@ -123,13 +123,13 @@ func (c *Container) load() error { return nil } -func (c *Container) wait(ctx context.Context, state lxc.State) bool { +func (c *Container) waitStopped(ctx context.Context) bool { for { select { case <-ctx.Done(): return false default: - if c.LinuxContainer.State() == state { + if c.LinuxContainer.State() == lxc.STOPPED { return true } time.Sleep(time.Millisecond * 100) @@ -143,6 +143,9 @@ func (c *Container) waitCreated(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() default: + if err := unix.Kill(c.Pid, 0); err != nil { + return err + } state := c.LinuxContainer.State() if !(state == lxc.RUNNING) { c.Log.Debug().Stringer("state", state).Msg("wait for state lxc.RUNNING") @@ -161,14 +164,17 @@ func (c *Container) waitCreated(ctx context.Context) error { } } -func (c *Container) waitNot(ctx context.Context, state specs.ContainerState) error { +func (c *Container) waitStarted(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: + if err := unix.Kill(c.Pid, 0); err != nil { + return err + } initState, _ := c.getContainerInitState() - if initState != state { + if initState != specs.StateCreated { return nil } time.Sleep(time.Millisecond * 10) @@ -324,9 +330,7 @@ func (c *Container) start(ctx context.Context) error { if err := fifo.Close(); err != nil { return err } - - // wait for container state to change - return c.waitNot(ctx, specs.StateCreated) + return c.waitStarted(ctx) } // ExecDetached executes the given process spec within the container. diff --git a/runtime.go b/runtime.go index 665c0fcd..6c241403 100644 --- a/runtime.go +++ b/runtime.go @@ -415,7 +415,7 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e return errorf("failed to kill container: %w", err) } // wait until stopped - if !c.wait(ctx, lxc.STOPPED) { + if !c.waitStopped(ctx) { return errorf("container not stopped") } } From 7463064ae3ad34ecfdac78ebd05c7ebec33d4081 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 18:29:45 +0200 Subject: [PATCH 353/373] Fix runtime tests Signed-off-by: Ruben Jenster --- pkg/internal/lxcri-test/main.go | 2 +- runtime_test.go | 30 ++++++++++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/pkg/internal/lxcri-test/main.go b/pkg/internal/lxcri-test/main.go index 561b0af5..b7ce5d9a 100644 --- a/pkg/internal/lxcri-test/main.go +++ b/pkg/internal/lxcri-test/main.go @@ -25,5 +25,5 @@ func main() { fmt.Printf("%#v\n", os.Args) println("sleeping for 30 seconds") - time.Sleep(time.Second * 30) + time.Sleep(time.Second * 3) } diff --git a/runtime_test.go b/runtime_test.go index c6d8bba8..b3dfa7aa 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -60,7 +60,17 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { id := filepath.Base(rootfs) cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true, log.TraceLevel)} cfg.Spec.Linux.CgroupsPath = id + ".slice" // use /proc/self/cgroup" - cfg.LogFile = "/dev/stderr" + + // FIXME /dev/stderr has perms 600 + // If container process user is not equal to the + // runtime process user then setting lxc log file will fail + // because of missing permissions. + if runAsRuntimeUser(cfg.Spec) { + cfg.LogFile = "/dev/stderr" + } else { + cfg.LogFile = filepath.Join(rootfs, "log") + } + t.Logf("liblxc log output is written to %s", cfg.LogFile) cfg.LogLevel = "trace" return &cfg @@ -108,7 +118,7 @@ func TestSharedPIDNamespace(t *testing.T) { } c, err := rt.Create(ctx, cfg) - require.Nil(t, err) + require.NoError(t, err) require.NotNil(t, c) err = rt.Delete(ctx, c.ContainerID, true) @@ -168,9 +178,6 @@ func TestRuntimePrivileged(t *testing.T) { // sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) // func TestRuntimeUnprivileged(t *testing.T) { - if os.Getuid() == 0 { - t.Skipf("this test is only run as non-root") - } rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -199,9 +206,6 @@ func TestRuntimeUnprivileged(t *testing.T) { } func TestRuntimeUnprivileged2(t *testing.T) { - if os.Getuid() == 0 { - t.Skipf("this test is only run as non-root") - } rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -275,14 +279,4 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { err = c.Release() require.NoError(t, err) - - // manpage for 'wait4' suggests to use waitpid or waitid instead, but - // golang/x/sys/unix only implements 'Wait4'. See https://github.com/golang/go/issues/9176 - var ws unix.WaitStatus - _, err = unix.Wait4(c.Pid, &ws, 0, nil) - require.NoError(t, err) - fmt.Printf("ws:0x%x exited:%t exit_status:%d signaled:%t signal:%d\n", ws, ws.Exited(), ws.ExitStatus(), ws.Signaled(), ws.Signal()) - - // NOTE it seems that the go test framework reaps all remaining children. - // It's reasonable that no process started from the tests will survive the test run. } From faff7a1ccc05c05ff6b73a30bbb5567074e6637b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 19:20:29 +0200 Subject: [PATCH 354/373] Improve error logging. Signed-off-by: Ruben Jenster --- cmd/lxcri-start/lxcri-start.c | 2 +- container.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/lxcri-start/lxcri-start.c b/cmd/lxcri-start/lxcri-start.c index 34078370..41e84cef 100644 --- a/cmd/lxcri-start/lxcri-start.c +++ b/cmd/lxcri-start/lxcri-start.c @@ -65,7 +65,7 @@ int main(int argc, char **argv) c->daemonize = false; if (!c->start(c, ENABLE_LXCINIT, NULL)) - ERROR("failed to start container\n"); + ERROR("monitor process pid=%d failed (container error_num:%d)\n", getpid(), c->error_num); /* Try to die with the same signal the task did. */ /* FIXME error_num is zero if init was killed with SIGHUP */ diff --git a/container.go b/container.go index 64668c3f..9d7b3cd3 100644 --- a/container.go +++ b/container.go @@ -144,7 +144,7 @@ func (c *Container) waitCreated(ctx context.Context) error { return ctx.Err() default: if err := unix.Kill(c.Pid, 0); err != nil { - return err + return fmt.Errorf("failed to get container process %d: %w", c.Pid, err) } state := c.LinuxContainer.State() if !(state == lxc.RUNNING) { @@ -171,7 +171,7 @@ func (c *Container) waitStarted(ctx context.Context) error { return ctx.Err() default: if err := unix.Kill(c.Pid, 0); err != nil { - return err + return fmt.Errorf("failed to get container process %d: %w", c.Pid, err) } initState, _ := c.getContainerInitState() if initState != specs.StateCreated { From bfb8e451fd586042e86f76a74575f19ef582857c Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 19:20:43 +0200 Subject: [PATCH 355/373] Use --failfast for test target. Signed-off-by: Ruben Jenster --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ce3d755d..bdf8454c 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ fmt: .PHONY: test test: build go build ./pkg/internal/lxcri-test - go test --count 1 -v ./... + go test --failfast --count 1 -v ./... build: $(BINS) $(LIBEXEC_BINS) From e5c7d4ad49492104ae16b4f13540536bd0b6d0fe Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Mon, 19 Apr 2021 19:21:28 +0200 Subject: [PATCH 356/373] Improve runtime tests. Signed-off-by: Ruben Jenster --- runtime_test.go | 53 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index b3dfa7aa..23a780ec 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -16,10 +16,27 @@ import ( "golang.org/x/sys/unix" ) +var logLevel = "info" +var libexecDir = "/usr/local/libexec/lxcri" +var tmpRoot = "." + +func init() { + // NOTE keep environment variables in sync with `lxcri` cli + if val, ok := os.LookupEnv("LXCRI_LOG_LEVEL"); ok { + logLevel = val + } + if val, ok := os.LookupEnv("LXCRI_LIBEXEC"); ok { + libexecDir = val + } + if val, ok := os.LookupEnv("HOME"); ok { + tmpRoot = val + } +} + func mkdirTemp() (string, error) { // /tmp has permissions 1777 // it should never be used as runtime or rootfs parent - return os.MkdirTemp(os.Getenv("HOME"), "lxcri-test") + return os.MkdirTemp(tmpRoot, "lxcri-test") } func newRuntime(t *testing.T) *Runtime { @@ -30,16 +47,16 @@ func newRuntime(t *testing.T) *Runtime { err = unix.Chmod(runtimeRoot, 0755) require.NoError(t, err) + level, err := log.ParseLevel(logLevel) + require.NoError(t, err) + rt := &Runtime{ - Log: log.ConsoleLogger(true, log.TraceLevel), + Log: log.ConsoleLogger(true, level), Root: runtimeRoot, - LibexecDir: os.Getenv("LIBEXEC_DIR"), + LibexecDir: libexecDir, //MonitorCgroup: "lxcri-monitor.slice", } - if rt.LibexecDir == "" { - rt.LibexecDir = "/usr/local/libexec/lxcri" - } - //ExecInit = "lxcri-debug" + require.NoError(t, rt.Init()) return rt } @@ -56,9 +73,15 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { err = exec.Command("cp", cmd, rootfs).Run() require.NoError(t, err) + level, err := log.ParseLevel(logLevel) + require.NoError(t, err) + spec := specki.NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) id := filepath.Base(rootfs) - cfg := ContainerConfig{ContainerID: id, Spec: spec, Log: log.ConsoleLogger(true, log.TraceLevel)} + cfg := ContainerConfig{ + ContainerID: id, Spec: spec, + Log: log.ConsoleLogger(true, level), + } cfg.Spec.Linux.CgroupsPath = id + ".slice" // use /proc/self/cgroup" // FIXME /dev/stderr has perms 600 @@ -71,7 +94,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { cfg.LogFile = filepath.Join(rootfs, "log") } t.Logf("liblxc log output is written to %s", cfg.LogFile) - cfg.LogLevel = "trace" + cfg.LogLevel = logLevel return &cfg } @@ -97,6 +120,9 @@ func TestEmptyNamespaces(t *testing.T) { } func TestSharedPIDNamespace(t *testing.T) { + if os.Getuid() != 0 { + t.Skipf("PID namespace sharing is only permitted as root.") + } rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -178,6 +204,11 @@ func TestRuntimePrivileged(t *testing.T) { // sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) // func TestRuntimeUnprivileged(t *testing.T) { + + if os.Getuid() == 0 { + t.Skipf("This test only runs as non-root") + } + rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -215,11 +246,11 @@ func TestRuntimeUnprivileged2(t *testing.T) { if os.Getuid() != 0 { cfg.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } cfg.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, - specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } } From a665d10d285224cbc482a5629da8414df9892300 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 09:50:05 +0200 Subject: [PATCH 357/373] Rework wait for monitor process. Signed-off-by: Ruben Jenster --- container.go | 50 ++++++++++++++++++++++++++++++++++++++++++-------- create.go | 4 ++++ runtime.go | 44 ++++++-------------------------------------- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/container.go b/container.go index 9d7b3cd3..aae65c52 100644 --- a/container.go +++ b/container.go @@ -123,28 +123,62 @@ func (c *Container) load() error { return nil } -func (c *Container) waitStopped(ctx context.Context) bool { +func (c *Container) waitMonitorStopped(ctx context.Context) error { for { select { case <-ctx.Done(): - return false + return ctx.Err() default: - if c.LinuxContainer.State() == lxc.STOPPED { - return true + if !c.isMonitorRunning() { + return nil } time.Sleep(time.Millisecond * 100) } } } +func (c *Container) isMonitorRunning() bool { + if c.Pid < 2 { + return false + } + + var ws unix.WaitStatus + pid, err := unix.Wait4(c.Pid, &ws, unix.WNOHANG, nil) + if pid == c.Pid { + c.Log.Info().Msgf("monitor %d died: exited:%t exit_status:%d signaled:%t signal:%s", + c.Pid, ws.Exited(), ws.ExitStatus(), ws.Signaled(), ws.Signal()) + return false + } + + // if WNOHANG was specified and one or more child(ren) specified by pid exist, + // but have not yet changed state, then 0 is returned + if pid == 0 { + return true + } + + // This runtime process may not be the parent of the monitor process + if err == unix.ECHILD { + // check if the process is still runnning + err := unix.Kill(c.Pid, 0) + if err == nil { + return true + } + // it's not running + if err == unix.ESRCH { + return false + } + } + return false +} + func (c *Container) waitCreated(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: - if err := unix.Kill(c.Pid, 0); err != nil { - return fmt.Errorf("failed to get container process %d: %w", c.Pid, err) + if !c.isMonitorRunning() { + return fmt.Errorf("monitor already died") } state := c.LinuxContainer.State() if !(state == lxc.RUNNING) { @@ -170,8 +204,8 @@ func (c *Container) waitStarted(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() default: - if err := unix.Kill(c.Pid, 0); err != nil { - return fmt.Errorf("failed to get container process %d: %w", c.Pid, err) + if !c.isMonitorRunning() { + return fmt.Errorf("monitor already died") } initState, _ := c.getContainerInitState() if initState != specs.StateCreated { diff --git a/create.go b/create.go index 92ab5cfe..c5a8ce5f 100644 --- a/create.go +++ b/create.go @@ -63,6 +63,10 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container return c, errorf("failed to run container process: %w", err) } + if err != nil { + c.isMonitorRunning() + } + return c, err } diff --git a/runtime.go b/runtime.go index 6c241403..073fae1f 100644 --- a/runtime.go +++ b/runtime.go @@ -7,7 +7,6 @@ import ( "net" "os" "os/exec" - "os/signal" "path/filepath" "time" @@ -20,39 +19,6 @@ import ( "gopkg.in/lxc/go-lxc.v2" ) -// waitForChildren consumes the process state of any exited child processes. -// -// Background: -// The `lxcri-start` process is reparented if the runtime process dies. -// It is reparented to either a parent subreaper process (see `man prctl` PR_SET_CHILD_SUBREAPER), -// e.g conmon if the runtime was executed from cri-o, or directly to init (pid 1, e.g systemd). -// Any (`lxcri-start`) child process that exits before the runtime will become orphaned / a zombie process. -// The runtime has consume the process state of any (`lxcri-start`) child processes which exited -// to avoid this. -// -// NOTE that unix.Kill(, 0) will return with success as long as the process state -// of `` was not consumed with wait4|waitpid. -func waitForChildren() { - // Set up channel on which to send signal notifications. - // We must use a buffered channel or risk missing the signal - // if we're not ready to receive when the signal is sent. - c := make(chan os.Signal, 1) - signal.Notify(c, unix.SIGCHLD) - - for range c { - // The manpage for 'wait4' suggests to use waitpid or waitid instead, but - // golang/x/sys/unix only implements 'Wait4'. See https://github.com/golang/go/issues/9176 - // since lxcri-start creates a new session / process group with setsid - // we have to wait for any child process ('-1') - //var ws unix.WaitStatus - unix.Wait4(-1, nil, unix.WNOHANG, nil) - } -} - -func init() { - go waitForChildren() -} - const ( // BundleConfigFile is the name of the OCI container bundle config file. // The content is the JSON encoded specs.Spec. @@ -408,16 +374,18 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e return err } if state != specs.StateStopped { + c.Log.Debug().Msgf("delete state:%s", state) if !force { return errorf("container is not not stopped (current state %s)", state) } if err := c.kill(ctx, unix.SIGKILL); err != nil { return errorf("failed to kill container: %w", err) } - // wait until stopped - if !c.waitStopped(ctx) { - return errorf("container not stopped") - } + } + + if err := c.waitMonitorStopped(ctx); err != nil { + c.Log.Error().Msgf("failed to stop monitor process %d", c.Pid) + // unix.Kill(c.Pid, unix.SIGKILL) } // From OCI runtime spec From b104cd66671a15ef20e915474efebe07a2a156fb Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 09:50:53 +0200 Subject: [PATCH 358/373] runtime test fixes Signed-off-by: Ruben Jenster --- runtime_test.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index 23a780ec..b1aa7334 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -16,7 +16,7 @@ import ( "golang.org/x/sys/unix" ) -var logLevel = "info" +var logLevel = "debug" var libexecDir = "/usr/local/libexec/lxcri" var tmpRoot = "." @@ -91,7 +91,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { if runAsRuntimeUser(cfg.Spec) { cfg.LogFile = "/dev/stderr" } else { - cfg.LogFile = filepath.Join(rootfs, "log") + cfg.LogFile = filepath.Join("/tmp", "log") } t.Logf("liblxc log output is written to %s", cfg.LogFile) cfg.LogLevel = logLevel @@ -160,6 +160,17 @@ func TestNonEmptyCgroup(t *testing.T) { cfg := newConfig(t, "lxcri-test") defer os.RemoveAll(cfg.Spec.Root.Path) + if os.Getuid() != 0 { + cfg.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, + //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + cfg.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, + //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, + } + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() From d28e973e956de4f063d3ea61aa8881facfbb1037 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 12:28:49 +0200 Subject: [PATCH 359/373] Fix cgroup root detection for unprivileged runtime. Signed-off-by: Ruben Jenster --- cgroup.go | 55 ++++++++++++++++++++++++++++++++++++++++-------------- runtime.go | 7 +++++-- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/cgroup.go b/cgroup.go index f1497192..29d87a21 100644 --- a/cgroup.go +++ b/cgroup.go @@ -15,20 +15,52 @@ import ( "golang.org/x/sys/unix" ) -var cgroupRoot string +var cgroupRoot = "/sys/fs/cgroup" -func detectCgroupRoot() string { +func detectCgroupRoot() (string, error) { + var cgroupRoot string if err := isFilesystem("/sys/fs/cgroup", "cgroup2"); err == nil { - return "/sys/fs/cgroup" + cgroupRoot = "/sys/fs/cgroup" } if err := isFilesystem("/sys/fs/cgroup/unified", "cgroup2"); err == nil { - return "/sys/fs/cgroup/unified" + cgroupRoot = "/sys/fs/cgroup/unified" } - return "" + + // TODO use /proc/self/mounts to detect cgroupv2 root ! + + if os.Getuid() == 0 { + if cgroupRoot == "" { + return "", fmt.Errorf("failed to detect cgroupv2 root") + } + return cgroupRoot, nil + } + + // Use the cgroup path of the runtime user if unprivileged. + data, err := os.ReadFile("/proc/self/cgroup") + if err != nil { + return cgroupRoot, fmt.Errorf("Failed to load /proc/self/cgroup: %s", err) + } + lines := strings.Split(string(data), "\n") + // get cgroup path from '0::/user.slice/user-0.slice/session-52.scope' + for _, line := range lines { + vals := strings.SplitN(line, ":", 3) + if len(vals) == 3 && vals[0] == "0" { + return filepath.Join(cgroupRoot, vals[2]), nil + } + } + return cgroupRoot, fmt.Errorf("Failed to parse cgroup from /proc/self/cgroup") } -func init() { - cgroupRoot = detectCgroupRoot() +// checkCgroup checks if the cgroup of the container is non-empty. +func checkCgroup(c *Container) error { + ev, err := parseCgroupEvents(filepath.Join(cgroupRoot, c.CgroupDir, "cgroup.events")) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to parse cgroup events: %w", err) + } + if err == nil && ev.populated { + return fmt.Errorf("container cgroup %s is not empty", c.CgroupDir) + } + return nil } // https://github.com/opencontainers/runtime-spec/blob/v1.0.2/config-linux.md @@ -39,13 +71,8 @@ func configureCgroup(rt *Runtime, c *Container) error { return err } - // refuse to run in a non-empty cgroup - ev, err := parseCgroupEvents(filepath.Join(cgroupRoot, c.CgroupDir, "cgroup.events")) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to parse cgroup events: %w", err) - } - if err == nil && ev.populated { - return fmt.Errorf("container cgroup %s is not empty", c.CgroupDir) + if err := checkCgroup(c); err != nil { + return err } if devices := c.Spec.Linux.Resources.Devices; devices != nil { diff --git a/runtime.go b/runtime.go index 073fae1f..ac0e1e79 100644 --- a/runtime.go +++ b/runtime.go @@ -120,9 +120,12 @@ func (rt *Runtime) Init() error { if err := isFilesystem("/proc", "proc"); err != nil { return errorf("procfs not mounted on /proc: %w", err) } - if err := isFilesystem(cgroupRoot, "cgroup2"); err != nil { - return errorf("ccgroup2 not mounted on %s: %w", cgroupRoot, err) + + cgroupRoot, err = detectCgroupRoot() + if err != nil { + rt.Log.Warn().Msgf("cgroup root detection failed: %s", err) } + rt.Log.Info().Msgf("using cgroup root %s", cgroupRoot) if !lxc.VersionAtLeast(3, 1, 0) { return errorf("liblxc runtime version is %s, but >= 3.1.0 is required", lxc.Version()) From 80a57d532883eb37154935c8f95f5869d71e85c8 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:10:23 +0200 Subject: [PATCH 360/373] Fix regression with empty environment variables. Signed-off-by: Ruben Jenster --- create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create.go b/create.go index c5a8ce5f..ab0e5c8d 100644 --- a/create.go +++ b/create.go @@ -395,7 +395,7 @@ func cleanenv(c *Container, overwrite bool) { if len(env) < 2 { return } - newEnv := make([]string, len(env)) + newEnv := make([]string, 0, len(env)) var exist bool for _, kv := range env { newEnv, exist = specki.Setenv(newEnv, kv, overwrite) From 4caa05401b9f7bfcbbd5443c2949de2fb4ff06d9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:12:53 +0200 Subject: [PATCH 361/373] create: Configure liblxc logging first. Setting lxc config items may already write output to the logfile. Therefore logging has to be configured first otherwise the output is lost. Signed-off-by: Ruben Jenster --- create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/create.go b/create.go index ab0e5c8d..b45c14c9 100644 --- a/create.go +++ b/create.go @@ -71,6 +71,10 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container } func configureContainer(rt *Runtime, c *Container) error { + if err := setLog(c); err != nil { + return errorf("failed to configure container log: %w", err) + } + if err := configureHostname(rt, c); err != nil { return err } @@ -212,10 +216,6 @@ func configureContainer(rt *Runtime, c *Container) error { } } - if err := setLog(c); err != nil { - return errorf("failed to configure container log: %w", err) - } - if err := configureMounts(rt, c); err != nil { return fmt.Errorf("failed to configure mounts: %w", err) } From e7e1df2e019edc10e2bd9c27f6afce9c7e02bcc4 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:17:20 +0200 Subject: [PATCH 362/373] Improve some comments and log output. Signed-off-by: Ruben Jenster --- runtime.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime.go b/runtime.go index ac0e1e79..038b25af 100644 --- a/runtime.go +++ b/runtime.go @@ -97,7 +97,7 @@ func (rt *Runtime) hasCapability(s string) bool { } // Init initializes the runtime instance. -// It creates required directories and checks the hosts system configuration. +// It creates required directories and checks the runtimes system configuration. // Unsupported runtime features are disabled and a warning message is logged. // Init must be called once for a runtime instance before calling any other method. func (rt *Runtime) Init() error { @@ -174,17 +174,17 @@ func (rt *Runtime) checkSpec(spec *specs.Spec) error { return errorf("failed to mount namespace: %s", err) } if yes { - return errorf("container wants to share the hosts mount namespace") + return errorf("container wants to share the runtimes mount namespace") } // It should be best practise not to do so, but there are containers that - // want to share the hosts PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set + // want to share the runtimes PID namespaces. e.g sonobuoy/sonobuoy-systemd-logs-daemon-set yes, err = isNamespaceSharedWithRuntime(getNamespace(spec, specs.PIDNamespace)) if err != nil { return errorf("failed to check PID namespace: %s", err) } if yes { - rt.Log.Warn().Msg("container wil share the hosts PID namespace") + rt.Log.Warn().Msg("container shares the PID namespace with the runtime") } return nil } From 89035adcd3f549965f10e21c5db50cc21d957c73 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:19:17 +0200 Subject: [PATCH 363/373] Improve runtime tests. Signed-off-by: Ruben Jenster --- pkg/internal/lxcri-test/main.go | 42 ++++++++++++++++++++++++++++----- runtime.go | 1 - runtime_test.go | 21 ++++++++++++++--- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/pkg/internal/lxcri-test/main.go b/pkg/internal/lxcri-test/main.go index b7ce5d9a..50c11bb2 100644 --- a/pkg/internal/lxcri-test/main.go +++ b/pkg/internal/lxcri-test/main.go @@ -2,14 +2,25 @@ package main import ( "fmt" + "io" "os" "os/signal" + "strconv" "syscall" "time" ) -func main() { +var logPrefix string + +func init() { + logPrefix = fmt.Sprintf(">> %s(pid:%d) ", os.Args[0], os.Getpid()) +} + +func logf(format string, args ...interface{}) { + fmt.Printf(logPrefix+format+"\n", args...) +} +func main() { sigs := make(chan os.Signal, 1) // SIGHUP by default terminates the process, if the process does not catch it. @@ -19,11 +30,30 @@ func main() { go func() { sig := <-sigs - fmt.Println() - fmt.Println("received signal:", sig) + logf("received signal %q", sig) }() - fmt.Printf("%#v\n", os.Args) - println("sleeping for 30 seconds") - time.Sleep(time.Second * 3) + logf("begin") + + sec := 3 + if s, ok := os.LookupEnv("SLEEP"); ok { + n, err := strconv.Atoi(s) + if err != nil { + panic(err) + } + logf("using env SLEEP value %s", s) + sec = n + } + + f, err := os.Open("/proc/self/mounts") + if err != nil { + panic(err) + } + logf("writing /proc/self/mounts") + io.Copy(os.Stdout, f) + + logf("sleeping for %d seconds", sec) + time.Sleep(time.Second * time.Duration(sec)) + + logf("end") } diff --git a/runtime.go b/runtime.go index 038b25af..564700d2 100644 --- a/runtime.go +++ b/runtime.go @@ -388,7 +388,6 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e if err := c.waitMonitorStopped(ctx); err != nil { c.Log.Error().Msgf("failed to stop monitor process %d", c.Pid) - // unix.Kill(c.Pid, unix.SIGKILL) } // From OCI runtime spec diff --git a/runtime_test.go b/runtime_test.go index b1aa7334..6b4d6f79 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -153,6 +153,8 @@ func TestSharedPIDNamespace(t *testing.T) { // TODO test uts namespace (shared with host) +// NOTE works only if cgroup root is writable +// sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup/$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) func TestNonEmptyCgroup(t *testing.T) { rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -163,11 +165,9 @@ func TestNonEmptyCgroup(t *testing.T) { if os.Getuid() != 0 { cfg.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, - //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } cfg.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, - //specs.LinuxIDMapping{ContainerID: 1, HostID: 20000, Size: 65536}, } } @@ -178,17 +178,32 @@ func TestNonEmptyCgroup(t *testing.T) { require.NoError(t, err) require.NotNil(t, c) + //t.Logf("sleeping for a minute") + //time.Sleep(60*time.Second) + cfg2 := newConfig(t, "lxcri-test") defer os.RemoveAll(cfg.Spec.Root.Path) cfg2.Spec.Linux.CgroupsPath = cfg.Spec.Linux.CgroupsPath + if os.Getuid() != 0 { + cfg2.Spec.Linux.UIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getuid()), Size: 1}, + } + cfg2.Spec.Linux.GIDMappings = []specs.LinuxIDMapping{ + specs.LinuxIDMapping{ContainerID: 0, HostID: uint32(os.Getgid()), Size: 1}, + } + } + c2, err := rt.Create(ctx, cfg2) require.Error(t, err) t.Logf("create error: %s", err) - require.NotNil(t, c2) err = rt.Delete(ctx, c.ContainerID, true) require.NoError(t, err) + + require.NotNil(t, c2) + err = rt.Delete(ctx, c2.ContainerID, true) + require.NoError(t, err) } func TestRuntimePrivileged(t *testing.T) { From 62fc405c30c0791032d8f91c4182b72beaa78880 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:46:04 +0200 Subject: [PATCH 364/373] Fix staticcheck. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 2 +- Makefile | 2 ++ cgroup.go | 4 ++-- namespaces.go | 9 --------- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49d447eb..ca4400ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: - name: Run staticcheck run: | GO111MODULE=off go get -u honnef.co/go/tools/cmd/staticcheck - staticcheck --unused.whole-program=true -- ./... + staticcheck ./... - name: Install dependencies run: | diff --git a/Makefile b/Makefile index bdf8454c..a480ed7e 100644 --- a/Makefile +++ b/Makefile @@ -21,12 +21,14 @@ all: fmt test update-tools: GO111MODULE=off go get -u mvdan.cc/sh/v3/cmd/shfmt GO111MODULE=off go get -u golang.org/x/lint/golint + GO111MODULE=off go get -u honnef.co/go/tools/cmd/staticcheck fmt: go fmt ./... shfmt -w $(SHELL_SCRIPTS) golint ./... go mod tidy + staticcheck ./... .PHONY: test test: build diff --git a/cgroup.go b/cgroup.go index 29d87a21..c9e5e6d0 100644 --- a/cgroup.go +++ b/cgroup.go @@ -38,7 +38,7 @@ func detectCgroupRoot() (string, error) { // Use the cgroup path of the runtime user if unprivileged. data, err := os.ReadFile("/proc/self/cgroup") if err != nil { - return cgroupRoot, fmt.Errorf("Failed to load /proc/self/cgroup: %s", err) + return cgroupRoot, fmt.Errorf("failed to load /proc/self/cgroup: %s", err) } lines := strings.Split(string(data), "\n") // get cgroup path from '0::/user.slice/user-0.slice/session-52.scope' @@ -48,7 +48,7 @@ func detectCgroupRoot() (string, error) { return filepath.Join(cgroupRoot, vals[2]), nil } } - return cgroupRoot, fmt.Errorf("Failed to parse cgroup from /proc/self/cgroup") + return cgroupRoot, fmt.Errorf("failed to parse cgroup from /proc/self/cgroup") } // checkCgroup checks if the cgroup of the container is non-empty. diff --git a/namespaces.go b/namespaces.go index c573e2da..e7fc0c02 100644 --- a/namespaces.go +++ b/namespaces.go @@ -99,15 +99,6 @@ func getNamespace(spec *specs.Spec, nsType specs.LinuxNamespaceType) *specs.Linu return nil } -// isNamespaceCloned returns true if the given namespace -// is not nil and the namespace path it not empty. -func isNamespaceCloned(ns *specs.LinuxNamespace) bool { - if ns == nil { - return false - } - return ns.Path == "" -} - // isNamespaceSharedWithHost returns true if the given namespace is nil. // If the given namespace is not nil then the namespace then true is // returned if the namespace path refers to the host namespace and From f9e5083498705b84447ecd327dbf4d50629162f3 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 16:50:41 +0200 Subject: [PATCH 365/373] actions: Run staticcheck after build. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca4400ee..1057b800 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,11 +32,6 @@ jobs: GO111MODULE=off go get -u golang.org/x/lint/golint golint -set_exit_status ./... - - name: Run staticcheck - run: | - GO111MODULE=off go get -u honnef.co/go/tools/cmd/staticcheck - staticcheck ./... - - name: Install dependencies run: | sudo add-apt-repository ppa:ubuntu-lxc/daily -y @@ -47,6 +42,12 @@ jobs: make build sudo -E "PATH=$PATH" make install + - name: Run staticcheck + run: | + GO111MODULE=off go get -u honnef.co/go/tools/cmd/staticcheck + staticcheck ./... + + - name: Test unprivileged run: | # keep PATH to use go installed through actions/setup-go@v2 From d487ee5b572ff00e208ed4849be214625db632f7 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 17:03:23 +0200 Subject: [PATCH 366/373] Remove unused files. Signed-off-by: Ruben Jenster --- TODO.md | 17 ------ deployment/README.md | 67 ------------------------ deployment/debian.buster-slim.Dockerfile | 9 ---- deployment/old.sh | 11 ---- deployment/ubuntu.20.04.Dockerfile | 10 ---- deployment/ubuntu.21.04.Dockerfile | 9 ---- deployment/ubuntu.lxcri.Dockerfile | 7 --- deployment/ubuntu.node.Dockerfile | 5 -- 8 files changed, 135 deletions(-) delete mode 100644 TODO.md delete mode 100644 deployment/README.md delete mode 100644 deployment/debian.buster-slim.Dockerfile delete mode 100644 deployment/old.sh delete mode 100644 deployment/ubuntu.20.04.Dockerfile delete mode 100644 deployment/ubuntu.21.04.Dockerfile delete mode 100644 deployment/ubuntu.lxcri.Dockerfile delete mode 100644 deployment/ubuntu.node.Dockerfile diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 20e59adb..00000000 --- a/TODO.md +++ /dev/null @@ -1,17 +0,0 @@ ---> move to separate file -## TODO - -### OCI runtime spec - -* Apply Cgroup resource limits - -* - -### Infrastructure - -* CI - - -### -* Command to generate environment file. - diff --git a/deployment/README.md b/deployment/README.md deleted file mode 100644 index 1daf392b..00000000 --- a/deployment/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Packaging - - docker build . - - docker build --no-cache -t helloap:0.1 -f ./Dockerfile . - -Run with buildah as fast as docker - - buildah bud ubuntu.20.04.Dockerfile - - buildah bud --no-cache --pull-never Dockerfile - -## TODO - -* Build Images with Github ? -* Automate script formatting with [shfmt](https://github.com/mvdan/sh) - - ~/go/bin/shfmt -w ubuntu-install-lxc.sh ubuntu-install-lxc.sh - - -## Buildah Oneliners - -#### Remove all working containers - - buildah containers -q | xargs buildah delete - -#### Remove all images without a name - - buildah images | grep '' | tr -s ' ' | cut -d ' ' -f 3 | xargs buildah rmi - -#### Select images by name with jq - - buildah images --json | jq '[ .[] | select( .names[] | contains("localhost")) ]' - - -## Resources - -* [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) -* [Reducing the size of the Debian Installation Footprint](https://wiki.debian.org/ReduceDebian) - - -## Container Changlog - -Provide some information about what has changed in an container upgrade. - -* Changelog for package upgrades -* List of Modified files (mode and size, maybe rsync like output ?) - -## apt Package Changelog for debian/ubuntu - -Create a list of installed packages and versions. - -https://man7.org/linux/man-pages/man1/dpkg-query.1.html - -dpkg-query -W -f='{Pkg:"${binary:Package}", Version:"${Version}",Category:"${Section}"}\n' - -## List changed files - -### Packages installed from source ? - -* Are handled by the image layer -* Before squashing the image changes in the image layer should be listed - -### Track file changes with overlay - -* mount overlay on rootfs, make install, unmount, tar overlay and create package from it. -* similar to archlinux `makepkg` ... diff --git a/deployment/debian.buster-slim.Dockerfile b/deployment/debian.buster-slim.Dockerfile deleted file mode 100644 index 2463e888..00000000 --- a/deployment/debian.buster-slim.Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM debian:buster-slim - -LABEL distribution=debian lxc_from=git lxc_version=master - -ENV LXC_INSTALL_FROM=git - -COPY ubuntu-install-lxc.sh /tmp -RUN /tmp/ubuntu-install-lxc.sh -RUN rm /tmp/ubuntu-install-lxc.sh diff --git a/deployment/old.sh b/deployment/old.sh deleted file mode 100644 index 11d1f271..00000000 --- a/deployment/old.sh +++ /dev/null @@ -1,11 +0,0 @@ -LXC_PPA=${LXC_PPA:-http://ppa.launchpad.net/ubuntu-lxc/lxc-git-master/ubuntu} -LXC_PPA_KEY=${LXC_PPA_KEY:-93763AC528C8C52568951BE0D5495F657635B973} -LXC_PPA_KEYURL="${LXC_PPA_KEYURL:-http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$LXC_PPA_KEY}" -LXC_PPA_DEPS="curl gnupg2 ca-certificates" - -install_lxc_ppa() { - curl -sSL "$LXC_PPA_KEYURL" | apt-key add - >/dev/null - echo "deb $LXC_PPA $UBUNTU_CODENAME main" >/etc/apt/sources.list.d/lxc-git-master.list - apt-get update - apt_install lxc -} diff --git a/deployment/ubuntu.20.04.Dockerfile b/deployment/ubuntu.20.04.Dockerfile deleted file mode 100644 index ab0663e5..00000000 --- a/deployment/ubuntu.20.04.Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:20.04 - -LABEL distribution=ubuntu lxc_from=git lxc_version=master - -ENV LXC_INSTALL_FROM=git -ENV LXC_GIT_VERSION=35a68d6df2c240b6604625bd34979ba64db25de7 - -COPY ubuntu-install-lxc.sh utils.sh /tmp -RUN /tmp/ubuntu-install-lxc.sh -RUN rm /tmp/ubuntu-install-lxc.sh /tmp/utils.sh diff --git a/deployment/ubuntu.21.04.Dockerfile b/deployment/ubuntu.21.04.Dockerfile deleted file mode 100644 index 01ec20a6..00000000 --- a/deployment/ubuntu.21.04.Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM ubuntu:21.04 - -LABEL distribution=ubuntu lxc_from=git lxc_version=master - -ENV LXC_INSTALL_FROM=git - -COPY ubuntu-install-lxc.sh /tmp -RUN /tmp/ubuntu-install-lxc.sh -RUN rm /tmp/ubuntu-install-lxc.sh diff --git a/deployment/ubuntu.lxcri.Dockerfile b/deployment/ubuntu.lxcri.Dockerfile deleted file mode 100644 index 9635b2e9..00000000 --- a/deployment/ubuntu.lxcri.Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM lxc:0.1 - -ENV LXCRI_GIT_VERSION=origin/master - -COPY install-lxcri.sh utils.sh /tmp -RUN /tmp/install-lxcri.sh -RUN rm /tmp/install-lxcri.sh /tmp/utils.sh diff --git a/deployment/ubuntu.node.Dockerfile b/deployment/ubuntu.node.Dockerfile deleted file mode 100644 index 49cbb02f..00000000 --- a/deployment/ubuntu.node.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM localhost/criolxc:0.4 - -COPY install-node.sh utils.sh /tmp -RUN /tmp/install-node.sh -RUN rm /tmp/install-node.sh /tmp/utils.sh From 5ddc315c5a7245e0cb69f80d0253abfff83b3fae Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 17:05:49 +0200 Subject: [PATCH 367/373] doc: First cleanup Signed-off-by: Ruben Jenster --- README.md | 171 +---------------------------------- INSTALL.md => doc/install.md | 0 K8S.md => doc/kubernetes.md | 0 doc/setup.md | 111 +++++++++++++++++++++++ 4 files changed, 115 insertions(+), 167 deletions(-) rename INSTALL.md => doc/install.md (100%) rename K8S.md => doc/kubernetes.md (100%) create mode 100644 doc/setup.md diff --git a/README.md b/README.md index 687a7755..fa972b86 100644 --- a/README.md +++ b/README.md @@ -3,27 +3,15 @@ `lxcri` is a wrapper around [LXC](https://github.com/lxc/lxc) which can be used as a drop-in container runtime replacement for use by [CRI-O](https://github.com/kubernetes-sigs/cri-o). -### History - -The project started as a fork of lxc/crio-lxc but has undergone several refactorings -and yet shares very little code with lxc/crio-lxc and was therefore renamed to `lxcri` - ### OCI compliance -With liblxc >= https://github.com/lxc/lxc/commit/b5daeddc5afce1cad4915aef3e71fdfe0f428709 it passes all sonobuoy conformance tests. +With liblxc >= https://github.com/lxc/lxc/commit/b5daeddc5afce1cad4915aef3e71fdfe0f428709 +it passes all sonobuoy conformance tests. ## Installation -For the installation of the runtime see [INSTALL.md](INSTALL.md)
-For the installation and initialization of a kubernetes cluster see [K8S.md](K8S.md) - -## Glossary - -* `runtime` the lxcri binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) -* `container process` the process that starts and runs the container using liblxc (lxcri-start) -* `container config` the LXC config file -* `bundle config` the lxcri container state (bundle path, pidfile ....) -* `runtime spec` the OCI runtime spec from the bundle +For the installation of the runtime see [install.md](doc/install.md)
+For the installation and initialization of a kubernetes cluster see [kubernetes.md](doc/kubernetes.md) ## Bugs @@ -38,154 +26,3 @@ For the installation and initialization of a kubernetes cluster see [K8S.md](K8S * [runtime: Implement POSIX platform hooks](https://github.com/Drachenfels-GmbH/lxcri/issues/10) * [runtime: Implement cgroup2 resource limits](https://github.com/Drachenfels-GmbH/lxcri/issues/11) - -## Configuration - -The runtime binary implements flags that are required by the `OCI runtime spec`,
-and flags that are runtime specific (timeouts, hooks, logging ...). - -Most of the runtime specific flags have corresponding environment variables. See `lxcri --help`.
-The runtime evaluates the flag value in the following order (lower order takes precedence). - -1. cmdline flag from process arguments (overwrites process environment) -2. process environment variable (overwrites environment file) -3. environment file (overwrites cmdline flag default) -4. cmdline flag default - -### Environment variables - -Currently you have to compile to environment file yourself.
-To list all available variables: - -``` -grep EnvVars cmd/cli.go | grep -o LXCRI_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" -``` - -### Environment file - -The default path to the environment file is `/etc/defaults/lxcri`.
-It is loaded on every start of the `lxcri` binary, so changes take immediate effect.
-Empty lines and those commented with a leading *#* are ignored.
- -A malformed environment will let the next runtime call fail.
-In production it's recommended that you replace the environment file atomically.
- -E.g the environment file `/etc/default/lxcri` could look like this: - -```sh -LXCRI_LOG_LEVEL=debug -LXCRI_CONTAINER_LOG_LEVEL=debug -#LXCRI_LOG_FILE= -#LXCRI_LOG_TIMESTAMP= -#LXCRI_MONITOR_CGROUP= -#LXCRI_LIBEXEC= -#LXCRI_APPARMOR= -#LXCRI_CAPABILITIES= -#LXCRI_CGROUP_DEVICES= -#LXCRI_SECCOMP= -#LXCRI_CREATE_TIMEOUT= -#LXCRI_CREATE_HOOK=/usr/local/bin/lxcri-backup.sh -#LXCRI_CREATE_HOOK_TIMEOUT= -#LXCRI_START_TIMEOUT= -#LXCRI_KILL_TIMEOUT= -#LXCRI_DELETE_TIMEOUT= -``` - -### Runtime (security) features - -All supported runtime security features are enabled by default.
-The following runtime (security) features can optionally be disabled.
-Details see `lxcri --help` - -* apparmor -* capabilities -* cgroup-devices -* seccomp - -### Logging - -There is only a single log file for runtime and container process log output.
-The log-level for the runtime and the container process can be set independently. - -* containers are ephemeral, but the log file should not be -* a single logfile is easy to rotate and monitor -* a single logfile is easy to tail (watch for errors / events ...) -* robust implementation is easy - -#### Log Filtering - -Runtime log lines are written in JSON using [zerolog](https://github.com/rs/zerolog).
-The log file can be easily filtered with [jq](https://stedolan.github.io/jq/).
-For filtering with `jq` you must strip the container process logs with `grep -v '^lxc'`
- -E.g Filter show only errors and warnings for runtime `create` command: - -```sh - grep -v '^lxc ' /var/log/lxcri.log |\ - jq -c 'select(.cmd == "create" and ( .l == "error or .l == "warn")' -``` - -#### Runtime log fields - -Fields that are always present: - -* `l` log level -* `m` log message -* `c` caller (source file and line number) -* `cid` container ID -* `cmd` runtime command -* `t` timestamp in UTC (format matches container process output) - -Log message specific fields: - -* `pid` a process ID -* `file` a path to a file -* `lxc.config` the key of a container process config item -* `env` the key of an environment variable - - -### Debugging - -Apart from the logfile following resources are useful: - -* Systemd journal for cri-o and kubelet services -* `coredumpctl` if runtime or container process segfaults. - -#### Create Hook - -If a create hook is defined, it is executed before the `create` command returns.
-You can use it to backup the runtime spec and container process config for further analysis.
- -The create hook executable must - -* not use the standard file descriptors (stdin/stdout/stderr) although they are nulled. -* not exceed `LXCRI_CREATE_HOOK_TIMEOUT` or it is killed. -* not modify/delete any resources created by the runtime or container process - -The process environment contains the following variables: - -* `CONTAINER_ID` the container ID -* `LXC_CONFIG` the path to runtime process config -* `RUNTIME_CMD` the runtime command which executed the runtime hook -* `RUNTIME_PATH` the path to the container runtime directory -* `BUNDLE_PATH` the absolute path to the container bundle -* `LOG_FILE` the path to the log file -* `RUNTIME_ERROR` (optional) the error message if the runtime cmd return with error - -Example script `lxcri-backup.sh` that backs up any container runtime directory: - -```sh -#!/bin/sh - -LOGDIR=$(dirname $LOG_FILE) -OUT=$LOGDIR/$CONTAINER_ID - -# backup container runtime directory to log directory -cp -r $RUNTIME_PATH $OUT -# copy OCI runtime spec to container runtime directory - -# remove non `grep` friendly runtime files (symlinks, binaries, fifos) -rm $OUT/.lxcri/cwd -rm $OUT/.lxcri/init -rm $OUT/.lxcri/syncfifo -``` diff --git a/INSTALL.md b/doc/install.md similarity index 100% rename from INSTALL.md rename to doc/install.md diff --git a/K8S.md b/doc/kubernetes.md similarity index 100% rename from K8S.md rename to doc/kubernetes.md diff --git a/doc/setup.md b/doc/setup.md new file mode 100644 index 00000000..b6a4b3f9 --- /dev/null +++ b/doc/setup.md @@ -0,0 +1,111 @@ +## Glossary + +* `runtime` the lxcri binary and the command set that implement the [OCI runtime spec](https://github.com/opencontainers/runtime-spec/releases/download/v1.0.2/oci-runtime-spec-v1.0.2.html) +* `container process` the process that starts and runs the container using liblxc (lxcri-start) +* `container config` the LXC config file +* `bundle config` the lxcri container state (bundle path, pidfile ....) +* `runtime spec` the OCI runtime spec from the bundle + +## Setup + +The runtime binary implements flags that are required by the `OCI runtime spec`,
+and flags that are runtime specific (timeouts, hooks, logging ...). + +Most of the runtime specific flags have corresponding environment variables. See `lxcri --help`.
+The runtime evaluates the flag value in the following order (lower order takes precedence). + +1. cmdline flag from process arguments (overwrites process environment) +2. process environment variable (overwrites environment file) +3. environment file (overwrites cmdline flag default) +4. cmdline flag default + +### Environment variables + +Currently you have to compile to environment file yourself.
+To list all available variables: + +``` +grep EnvVars cmd/cli.go | grep -o LXCRI_[A-Za-z_]* | xargs -n1 -I'{}' echo "#{}=" +``` + +### Environment file + +The default path to the environment file is `/etc/defaults/lxcri`.
+It is loaded on every start of the `lxcri` binary, so changes take immediate effect.
+Empty lines and those commented with a leading *#* are ignored.
+ +A malformed environment will let the next runtime call fail.
+In production it's recommended that you replace the environment file atomically.
+ +E.g the environment file `/etc/default/lxcri` could look like this: + +```sh +LXCRI_LOG_LEVEL=debug +LXCRI_CONTAINER_LOG_LEVEL=debug +#LXCRI_LOG_FILE= +#LXCRI_LOG_TIMESTAMP= +#LXCRI_MONITOR_CGROUP= +#LXCRI_LIBEXEC= +#LXCRI_APPARMOR= +#LXCRI_CAPABILITIES= +#LXCRI_CGROUP_DEVICES= +#LXCRI_SECCOMP= +#LXCRI_CREATE_TIMEOUT= +#LXCRI_CREATE_HOOK=/usr/local/bin/lxcri-backup.sh +#LXCRI_CREATE_HOOK_TIMEOUT= +#LXCRI_START_TIMEOUT= +#LXCRI_KILL_TIMEOUT= +#LXCRI_DELETE_TIMEOUT= +``` + +### Runtime (security) features + +All supported runtime security features are enabled by default.
+The following runtime (security) features can optionally be disabled.
+Details see `lxcri --help` + +* apparmor +* capabilities +* cgroup-devices +* seccomp + +### Logging + +There is only a single log file for runtime and container process log output.
+The log-level for the runtime and the container process can be set independently. + +* containers are ephemeral, but the log file should not be +* a single logfile is easy to rotate and monitor +* a single logfile is easy to tail (watch for errors / events ...) +* robust implementation is easy + +#### Log Filtering + +Runtime log lines are written in JSON using [zerolog](https://github.com/rs/zerolog).
+The log file can be easily filtered with [jq](https://stedolan.github.io/jq/).
+For filtering with `jq` you must strip the container process logs with `grep -v '^lxc'`
+ +E.g Filter show only errors and warnings for runtime `create` command: + +```sh + grep -v '^lxc ' /var/log/lxcri.log |\ + jq -c 'select(.cmd == "create" and ( .l == "error or .l == "warn")' +``` + +#### Runtime log fields + +Fields that are always present: + +* `l` log level +* `m` log message +* `c` caller (source file and line number) +* `cid` container ID +* `cmd` runtime command +* `t` timestamp in UTC (format matches container process output) + +### Debugging + +Apart from the logfile following resources are useful: + +* Systemd journal for cri-o and kubelet services +* `coredumpctl` if runtime or container process segfaults. From dbe7681924bd8d312b6319ebb6789c44fd5b08e5 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 19:06:08 +0200 Subject: [PATCH 368/373] tests: Bind mount test binary. Signed-off-by: Ruben Jenster --- pkg/specki/specki.go | 10 ++++++++++ runtime_test.go | 15 +++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pkg/specki/specki.go b/pkg/specki/specki.go index 831baa90..b9b65589 100644 --- a/pkg/specki/specki.go +++ b/pkg/specki/specki.go @@ -354,3 +354,13 @@ func Setenv(env []string, val string, overwrite bool) ([]string, bool) { } return append(env, val), false } + +// BindMount returns a specs.Mount to bind mount src to dest. +// The given mount options opts are merged with the predefined options +// ("bind", "nosuid", "nodev", "relatime") +func BindMount(src string, dest string, opts ...string) specs.Mount { + return specs.Mount{ + Source: src, Destination: dest, Type: "bind", + Options: append([]string{"bind", "nosuid", "nodev", "relatime"}, opts...), + } +} diff --git a/runtime_test.go b/runtime_test.go index 6b4d6f79..9fd5dedc 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "os" - "os/exec" "path/filepath" "testing" "time" @@ -70,13 +69,17 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { t.Logf("container rootfs: %s", rootfs) // copy test binary to rootfs - err = exec.Command("cp", cmd, rootfs).Run() - require.NoError(t, err) + //err = exec.Command("cp", cmd, rootfs).Run() + //require.NoError(t, err) level, err := log.ParseLevel(logLevel) require.NoError(t, err) - spec := specki.NewSpec(rootfs, filepath.Join("/"+filepath.Base(cmd))) + cmdAbs, err := filepath.Abs(cmd) + require.NoError(t, err) + cmdDest := "/" + filepath.Base(cmdAbs) + + spec := specki.NewSpec(rootfs, cmdDest) id := filepath.Base(rootfs) cfg := ContainerConfig{ ContainerID: id, Spec: spec, @@ -84,6 +87,10 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { } cfg.Spec.Linux.CgroupsPath = id + ".slice" // use /proc/self/cgroup" + cfg.Spec.Mounts = append(cfg.Spec.Mounts, + specki.BindMount(cmdAbs, cmdDest), + ) + // FIXME /dev/stderr has perms 600 // If container process user is not equal to the // runtime process user then setting lxc log file will fail From 4549d907ca8a455f7dec9a15ce0f28f0e023c6a9 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 23:10:54 +0200 Subject: [PATCH 369/373] Release container in Runtime.Destroy. Signed-off-by: Ruben Jenster --- create.go | 13 ++++--------- runtime.go | 4 ++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/create.go b/create.go index b45c14c9..51aa546c 100644 --- a/create.go +++ b/create.go @@ -13,8 +13,9 @@ import ( // Create creates a single container instance from the given ContainerConfig. // Create is the first runtime method to call within the lifecycle of a container. -// You may have to call Runtime.Delete to cleanup container runtime state, -// if Create returns with an error. +// A created Container must be released with Container.Release after use. +// You should call Runtime.Delete to cleanup container runtime state, even +// if the Create returned with an error. func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container, error) { if err := rt.checkConfig(cfg); err != nil { return nil, err @@ -62,12 +63,7 @@ func (rt *Runtime) Create(ctx context.Context, cfg *ContainerConfig) (*Container if err := rt.runStartCmd(ctx, c); err != nil { return c, errorf("failed to run container process: %w", err) } - - if err != nil { - c.isMonitorRunning() - } - - return c, err + return c, nil } func configureContainer(rt *Runtime, c *Container) error { @@ -223,7 +219,6 @@ func configureContainer(rt *Runtime, c *Container) error { if err := configureReadonlyPaths(c); err != nil { return fmt.Errorf("failed to configure read-only paths: %w", err) } - return nil } diff --git a/runtime.go b/runtime.go index 564700d2..8346262f 100644 --- a/runtime.go +++ b/runtime.go @@ -200,6 +200,7 @@ func (rt *Runtime) keepEnv(names ...string) { // Load loads a container from the runtime directory. // The container must have been created with Runtime.Create. // The logger Container.Log is set to Runtime.Log by default. +// A loaded Container must be released with Container.Release after use. func (rt *Runtime) Load(containerID string) (*Container, error) { dir := filepath.Join(rt.Root, containerID) if _, err := os.Stat(dir); os.IsNotExist(err) { @@ -372,6 +373,9 @@ func (rt *Runtime) Delete(ctx context.Context, containerID string, force bool) e rt.Log.Warn().Msgf("deleting runtime dir for unloadable container: %s", err) return os.RemoveAll(filepath.Join(rt.Root, containerID)) } + + defer c.Release() + state, err := c.ContainerState() if err != nil { return err From 8b7ebbee5ae46c0fc2bc925db0891cee8483069b Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 23:13:29 +0200 Subject: [PATCH 370/373] actions: Multiple test runs. Limit open filedescriptors. Tests for races and file descriptor leaks. Signed-off-by: Ruben Jenster --- .github/workflows/build.yml | 5 +++-- Makefile | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1057b800..635bbbb5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,11 +57,12 @@ jobs: sudo /bin/sh -c "echo '$(whoami):1000:1' >> /etc/subgid" sudo /bin/sh -c "echo '$(whoami):20000:65536' >> /etc/subgid" sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup/unified$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) - make test + # detect file descriptor leaks + ulimit -n 30 + TESTCOUNT=10 make test - name: Test privileged run: | # keep PATH to use go installed through actions/setup-go@v2 # and not the system version (which is currently go 1.15.x) - sudo -E "PATH=$PATH" make install sudo -E "PATH=$PATH" make test diff --git a/Makefile b/Makefile index a480ed7e..5f3a0723 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ LDFLAGS=-X main.version=$(COMMIT) -X main.libexecDir=$(LIBEXEC_DIR) CC ?= cc SHELL_SCRIPTS = $(shell find . -name \*.sh) GO_SRC = $(shell find . -name \*.go | grep -v _test.go) +TESTCOUNT ?= 1 all: fmt test @@ -33,7 +34,7 @@ fmt: .PHONY: test test: build go build ./pkg/internal/lxcri-test - go test --failfast --count 1 -v ./... + go test --failfast --count $(TESTCOUNT) -v ./... build: $(BINS) $(LIBEXEC_BINS) From 72cf77a007663c708f28b8355aa7eb1fa027ee7a Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 23:15:15 +0200 Subject: [PATCH 371/373] Allow parallel test execution. Signed-off-by: Ruben Jenster --- runtime_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index 9fd5dedc..ee577e47 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -107,6 +107,7 @@ func newConfig(t *testing.T, cmd string, args ...string) *ContainerConfig { } func TestEmptyNamespaces(t *testing.T) { + t.Parallel() rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -127,6 +128,7 @@ func TestEmptyNamespaces(t *testing.T) { } func TestSharedPIDNamespace(t *testing.T) { + t.Parallel() if os.Getuid() != 0 { t.Skipf("PID namespace sharing is only permitted as root.") } @@ -163,6 +165,7 @@ func TestSharedPIDNamespace(t *testing.T) { // NOTE works only if cgroup root is writable // sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup/$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) func TestNonEmptyCgroup(t *testing.T) { + t.Parallel() rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -214,6 +217,7 @@ func TestNonEmptyCgroup(t *testing.T) { } func TestRuntimePrivileged(t *testing.T) { + t.Parallel() if os.Getuid() != 0 { t.Skipf("This tests only runs as root") } @@ -237,7 +241,7 @@ func TestRuntimePrivileged(t *testing.T) { // sudo chown -R $(whoami):$(whoami) /sys/fs/cgroup$(cat /proc/self/cgroup | grep '^0:' | cut -d: -f3) // func TestRuntimeUnprivileged(t *testing.T) { - + t.Parallel() if os.Getuid() == 0 { t.Skipf("This test only runs as non-root") } @@ -270,6 +274,7 @@ func TestRuntimeUnprivileged(t *testing.T) { } func TestRuntimeUnprivileged2(t *testing.T) { + t.Parallel() rt := newRuntime(t) defer os.RemoveAll(rt.Root) @@ -309,9 +314,6 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { require.NoError(t, err) require.Equal(t, specs.StateRunning, state.SpecState.Status) - // Must wait otherwise init process signal handlers may not - // yet be established and then sending SIGHUP will kill the container - // err = rt.Kill(ctx, c, unix.SIGUSR1) require.NoError(t, err) From b7ee3cecfe0bde74e3637a6dc1b3110b0105d77e Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 23:16:10 +0200 Subject: [PATCH 372/373] Fix filedescriptor leaks in runtime tests. Signed-off-by: Ruben Jenster --- runtime_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/runtime_test.go b/runtime_test.go index ee577e47..4574600a 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -156,6 +156,9 @@ func TestSharedPIDNamespace(t *testing.T) { require.NoError(t, err) require.NotNil(t, c) + err = c.Release() + require.NoError(t, err) + err = rt.Delete(ctx, c.ContainerID, true) require.NoError(t, err) } @@ -208,9 +211,15 @@ func TestNonEmptyCgroup(t *testing.T) { require.Error(t, err) t.Logf("create error: %s", err) + err = c.Release() + require.NoError(t, err) + err = rt.Delete(ctx, c.ContainerID, true) require.NoError(t, err) + err = c2.Release() + require.NoError(t, err) + require.NotNil(t, c2) err = rt.Delete(ctx, c2.ContainerID, true) require.NoError(t, err) From 14909d85c59b53e826fe93a2c7f6fe070cba08e2 Mon Sep 17 00:00:00 2001 From: Ruben Jenster Date: Tue, 20 Apr 2021 23:16:52 +0200 Subject: [PATCH 373/373] Cleanup runtime tests. Signed-off-by: Ruben Jenster --- runtime_test.go | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/runtime_test.go b/runtime_test.go index 4574600a..f67faa27 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -330,28 +330,13 @@ func testRuntime(t *testing.T, rt *Runtime, cfg *ContainerConfig) { require.NoError(t, err) require.Equal(t, specs.StateRunning, state.SpecState.Status) - time.Sleep(time.Millisecond * 500) - - // SIGHUP by default terminates a process if it is not ignored or catched by - // a signal handler - err = rt.Kill(ctx, c, unix.SIGKILL) - require.NoError(t, err) - - time.Sleep(time.Millisecond * 50) - - state, err = c.State() - require.NoError(t, err) - require.Equal(t, specs.StateStopped, state.SpecState.Status) - - err = rt.Delete(ctx, c.ContainerID, false) + err = rt.Delete(ctx, c.ContainerID, true) require.NoError(t, err) state, err = c.State() require.NoError(t, err) require.Equal(t, specs.StateStopped, state.SpecState.Status) - t.Log("done") - err = c.Release() require.NoError(t, err) }