From d51727642603ba160a7898ee4597d0f071cdea44 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Tue, 14 Apr 2020 11:00:40 -0700 Subject: Add support for the global flags and config files Note: This PR doesn't provide full rootless support that will be addressed in a future PR Signed-off-by: Jhon Honce --- pkg/domain/entities/engine.go | 319 +++++++++++++++++++++++++------- pkg/domain/entities/engine_container.go | 2 + pkg/domain/entities/engine_image.go | 3 + pkg/domain/infra/abi/containers.go | 6 + pkg/domain/infra/abi/images.go | 6 + pkg/domain/infra/abi/system.go | 154 +++++++++++++++ pkg/domain/infra/runtime_abi.go | 4 +- pkg/domain/infra/runtime_image_proxy.go | 2 +- pkg/domain/infra/runtime_libpod.go | 58 +++--- pkg/domain/infra/runtime_proxy.go | 2 +- pkg/domain/infra/runtime_tunnel.go | 4 +- pkg/domain/infra/tunnel/containers.go | 5 + pkg/domain/infra/tunnel/images.go | 5 + pkg/util/utils.go | 2 + 14 files changed, 467 insertions(+), 105 deletions(-) (limited to 'pkg') diff --git a/pkg/domain/entities/engine.go b/pkg/domain/entities/engine.go index c14348529..3b971a1e8 100644 --- a/pkg/domain/entities/engine.go +++ b/pkg/domain/entities/engine.go @@ -1,13 +1,23 @@ package entities import ( - "os/user" - "path/filepath" + "context" + "fmt" + "io" + "os" + "github.com/containers/buildah/pkg/parse" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/sysinfo" + "github.com/containers/libpod/pkg/apparmor" + "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/rootless" + "github.com/opencontainers/selinux/go-selinux" + "github.com/opentracing/opentracing-go" "github.com/spf13/pflag" ) +// EngineMode is the connection type podman is using to access libpod type EngineMode string const ( @@ -15,78 +25,243 @@ const ( TunnelMode = EngineMode("tunnel") ) +// Convert EngineMode to String func (m EngineMode) String() string { return string(m) } -type EngineOptions struct { - Uri string - Identities []string - FlagSet *pflag.FlagSet - EngineMode EngineMode - - CGroupManager string - CniConfigDir string - ConmonPath string - DefaultMountsFile string - EventsBackend string - HooksDir []string - MaxWorks int - Namespace string - Root string - Runroot string - Runtime string - StorageDriver string - StorageOpts []string - Syslog bool - Trace bool - NetworkCmdPath string - - Config string - CpuProfile string - LogLevel string - TmpDir string - - RemoteUserName string - RemoteHost string - VarlinkAddress string - ConnectionName string - RemoteConfigFilePath string - Port int - IdentityFile string - IgnoreHosts bool -} - -func NewEngineOptions() (EngineOptions, error) { - u, _ := user.Current() - return EngineOptions{ - CGroupManager: config.SystemdCgroupsManager, - CniConfigDir: "", - Config: "", - ConmonPath: filepath.Join("usr", "bin", "conmon"), - ConnectionName: "", - CpuProfile: "", - DefaultMountsFile: "", - EventsBackend: "", - HooksDir: nil, - IdentityFile: "", - IgnoreHosts: false, - LogLevel: "", - MaxWorks: 0, - Namespace: "", - NetworkCmdPath: "", - Port: 0, - RemoteConfigFilePath: "", - RemoteHost: "", - RemoteUserName: "", - Root: "", - Runroot: filepath.Join("run", "user", u.Uid), - Runtime: "", - StorageDriver: "overlayfs", - StorageOpts: nil, - Syslog: false, - TmpDir: filepath.Join("run", "user", u.Uid, "libpod", "tmp"), - Trace: false, - VarlinkAddress: "", - }, nil +// PodmanConfig combines the defaults and settings from the file system with the +// flags given in os.Args. Some runtime state is also stored here. +type PodmanConfig struct { + *config.Config + *pflag.FlagSet + + CGroupUsage string // rootless code determines Usage message + ConmonPath string // --conmon flag will set Engine.ConmonPath + CpuProfile string // Hidden: Should CPU profile be taken + EngineMode EngineMode // ABI or Tunneling mode + Identities []string // ssh identities for connecting to server + MaxWorks int // maximum number of parallel threads + RuntimePath string // --runtime flag will set Engine.RuntimePath + SpanCloser io.Closer // Close() for tracing object + SpanCtx context.Context // context to use when tracing + Span opentracing.Span // tracing object + Syslog bool // write to StdOut and Syslog, not supported when tunneling + Trace bool // Hidden: Trace execution + Uri string // URI to API Service + + Runroot string + StorageDriver string + StorageOpts []string +} + +// DefaultSecurityOptions: getter for security options from configuration +func (c PodmanConfig) DefaultSecurityOptions() []string { + securityOpts := []string{} + if c.Containers.SeccompProfile != "" && c.Containers.SeccompProfile != parse.SeccompDefaultPath { + securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", c.Containers.SeccompProfile)) + } + if apparmor.IsEnabled() && c.Containers.ApparmorProfile != "" { + securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", c.Containers.ApparmorProfile)) + } + if selinux.GetEnabled() && !c.Containers.EnableLabeling { + securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0])) + } + return securityOpts +} + +// DefaultSysctls +func (c PodmanConfig) DefaultSysctls() []string { + return c.Containers.DefaultSysctls +} + +func (c PodmanConfig) DefaultVolumes() []string { + return c.Containers.Volumes +} + +func (c PodmanConfig) DefaultDevices() []string { + return c.Containers.Devices +} + +func (c PodmanConfig) DefaultDNSServers() []string { + return c.Containers.DNSServers +} + +func (c PodmanConfig) DefaultDNSSearches() []string { + return c.Containers.DNSSearches +} + +func (c PodmanConfig) DefaultDNSOptions() []string { + return c.Containers.DNSOptions +} + +func (c PodmanConfig) DefaultEnv() []string { + return c.Containers.Env +} + +func (c PodmanConfig) DefaultInitPath() string { + return c.Containers.InitPath +} + +func (c PodmanConfig) DefaultIPCNS() string { + return c.Containers.IPCNS } + +func (c PodmanConfig) DefaultPidNS() string { + return c.Containers.PidNS +} + +func (c PodmanConfig) DefaultNetNS() string { + if c.Containers.NetNS == "private" && rootless.IsRootless() { + return "slirp4netns" + } + return c.Containers.NetNS +} + +func (c PodmanConfig) DefaultCgroupNS() string { + return c.Containers.CgroupNS +} + +func (c PodmanConfig) DefaultUTSNS() string { + return c.Containers.UTSNS +} + +func (c PodmanConfig) DefaultShmSize() string { + return c.Containers.ShmSize +} + +func (c PodmanConfig) DefaultUlimits() []string { + return c.Containers.DefaultUlimits +} + +func (c PodmanConfig) DefaultUserNS() string { + if v, found := os.LookupEnv("PODMAN_USERNS"); found { + return v + } + return c.Containers.UserNS +} + +func (c PodmanConfig) DefaultPidsLimit() int64 { + if rootless.IsRootless() { + cgroup2, _ := cgroups.IsCgroup2UnifiedMode() + if cgroup2 { + return c.Containers.PidsLimit + } + } + return sysinfo.GetDefaultPidsLimit() +} + +func (c PodmanConfig) DefaultPidsDescription() string { + return "Tune container pids limit (set 0 for unlimited)" +} + +func (c PodmanConfig) DefaultDetachKeys() string { + return c.Engine.DetachKeys +} + +// TODO: Remove in rootless support PR +// // EngineOptions holds the environment for running the engines +// type EngineOptions struct { +// // Introduced with V2 +// Uri string +// Identities []string +// FlagSet *pflag.FlagSet +// EngineMode EngineMode +// CGroupUsage string +// +// // Introduced with V1 +// CGroupManager string // config.EngineConfig +// CniConfigDir string // config.NetworkConfig.NetworkConfigDir +// ConmonPath string // config.EngineConfig +// DefaultMountsFile string // config.ContainersConfig +// EventsBackend string // config.EngineConfig.EventsLogger +// HooksDir []string // config.EngineConfig +// MaxWorks int +// Namespace string // config.EngineConfig +// Root string // +// Runroot string // config.EngineConfig.StorageConfigRunRootSet?? +// Runtime string // config.EngineConfig.OCIRuntime +// StorageDriver string // config.EngineConfig.StorageConfigGraphDriverNameSet?? +// StorageOpts []string +// Syslog bool +// Trace bool +// NetworkCmdPath string // config.EngineConfig +// +// Config string +// CpuProfile string +// LogLevel string +// TmpDir string // config.EngineConfig +// +// RemoteUserName string // deprecated +// RemoteHost string // deprecated +// VarlinkAddress string // deprecated +// ConnectionName string +// RemoteConfigFilePath string +// Port int // deprecated +// IdentityFile string // deprecated +// IgnoreHosts bool +// } +// +// func NewEngineOptions(opts EngineOptions) (EngineOptions, error) { +// ctnrCfg, err := config.Default() +// if err != nil { +// logrus.Error(err) +// os.Exit(1) +// } +// +// cgroupManager := ctnrCfg.Engine.CgroupManager +// cgroupUsage := `Cgroup manager to use ("cgroupfs"|"systemd")` +// cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() +// cniPluginDir := ctnrCfg.Network.CNIPluginDirs[0] +// +// cfg, err := config.NewConfig("") +// if err != nil { +// logrus.Errorf("Error loading container config %v\n", err) +// os.Exit(1) +// } +// cfg.CheckCgroupsAndAdjustConfig() +// +// if rootless.IsRootless() { +// if !cgroupv2 { +// cgroupManager = "" +// cgroupUsage = "Cgroup manager is not supported in rootless mode" +// } +// cniPluginDir = "" +// } +// +// return EngineOptions{ +// CGroupManager: cgroupManager, +// CGroupUsage: cgroupUsage, +// CniConfigDir: cniPluginDir, +// Config: opts.Config, // TODO: deprecate +// ConmonPath: opts.ConmonPath, +// ConnectionName: opts.ConnectionName, +// CpuProfile: opts.CpuProfile, +// DefaultMountsFile: ctnrCfg.Containers.DefaultMountsFile, +// EngineMode: opts.EngineMode, +// EventsBackend: ctnrCfg.Engine.EventsLogger, +// FlagSet: opts.FlagSet, // TODO: deprecate +// HooksDir: append(ctnrCfg.Engine.HooksDir[:0:0], ctnrCfg.Engine.HooksDir...), +// Identities: append(opts.Identities[:0:0], opts.Identities...), +// IdentityFile: opts.IdentityFile, // TODO: deprecate +// IgnoreHosts: opts.IgnoreHosts, +// LogLevel: opts.LogLevel, +// MaxWorks: opts.MaxWorks, +// Namespace: ctnrCfg.Engine.Namespace, +// NetworkCmdPath: ctnrCfg.Engine.NetworkCmdPath, +// Port: opts.Port, +// RemoteConfigFilePath: opts.RemoteConfigFilePath, +// RemoteHost: opts.RemoteHost, // TODO: deprecate +// RemoteUserName: opts.RemoteUserName, // TODO: deprecate +// Root: opts.Root, +// Runroot: opts.Runroot, +// Runtime: opts.Runtime, +// StorageDriver: opts.StorageDriver, +// StorageOpts: append(opts.StorageOpts[:0:0], opts.StorageOpts...), +// Syslog: opts.Syslog, +// TmpDir: opts.TmpDir, +// Trace: opts.Trace, +// Uri: opts.Uri, +// VarlinkAddress: opts.VarlinkAddress, +// }, nil +// } diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index cf66f6ac2..2001ab49c 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -3,11 +3,13 @@ package entities import ( "context" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/specgen" ) type ContainerEngine interface { + Config(ctx context.Context) (*config.Config, error) ContainerAttach(ctx context.Context, nameOrId string, options AttachOptions) error ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error) ContainerCleanup(ctx context.Context, namesOrIds []string, options ContainerCleanupOptions) ([]*ContainerCleanupReport, error) diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index 3110898a8..3a051ab9b 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -2,9 +2,12 @@ package entities import ( "context" + + "github.com/containers/common/pkg/config" ) type ImageEngine interface { + Config(ctx context.Context) (*config.Config, error) Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error) Diff(ctx context.Context, nameOrId string, options DiffOptions) (*DiffReport, error) Exists(ctx context.Context, nameOrId string) (*BoolReport, error) diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 92668190c..f464df3ac 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -12,6 +12,7 @@ import ( "sync" "github.com/containers/buildah" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/manifest" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" @@ -893,3 +894,8 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []str } return reports, nil } + +// GetConfig returns a copy of the configuration used by the runtime +func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) { + return ic.Libpod.GetConfig() +} diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 402bbb45e..a69a136a6 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -9,6 +9,7 @@ import ( "os" "strings" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker" dockerarchive "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" @@ -460,3 +461,8 @@ func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.Im return reports, nil } + +// GetConfig returns a copy of the configuration used by the runtime +func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { + return ir.Libpod.GetConfig() +} diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index adec94f6c..10872144b 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -4,17 +4,28 @@ package abi import ( "context" + "fmt" + "io/ioutil" "net" + "os" + "strconv" "strings" + "syscall" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod/define" api "github.com/containers/libpod/pkg/api/server" + "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" iopodman "github.com/containers/libpod/pkg/varlink" iopodmanAPI "github.com/containers/libpod/pkg/varlinkapi" + "github.com/containers/libpod/utils" "github.com/containers/libpod/version" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/varlink/go/varlink" ) @@ -88,3 +99,146 @@ func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.Servi } return nil } + +func (ic *ContainerEngine) SetupRootless(cmd *cobra.Command) error { + // do it only after podman has already re-execed and running with uid==0. + if os.Geteuid() == 0 { + ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup() + if err != nil { + logrus.Warnf("Failed to detect the owner for the current cgroup: %v", err) + } + if !ownsCgroup { + conf, err := ic.Config(context.Background()) + if err != nil { + return err + } + unitName := fmt.Sprintf("podman-%d.scope", os.Getpid()) + if err := utils.RunUnderSystemdScope(os.Getpid(), "user.slice", unitName); err != nil { + if conf.Engine.CgroupManager == config.SystemdCgroupsManager { + logrus.Warnf("Failed to add podman to systemd sandbox cgroup: %v", err) + } else { + logrus.Debugf("Failed to add podman to systemd sandbox cgroup: %v", err) + } + } + } + } + + if !executeCommandInUserNS(cmd) { + return nil + } + + pausePidPath, err := util.GetRootlessPauseProcessPidPath() + if err != nil { + return errors.Wrapf(err, "could not get pause process pid file path") + } + + became, ret, err := rootless.TryJoinPauseProcess(pausePidPath) + if err != nil { + return err + } + if became { + os.Exit(ret) + } + + // if there is no pid file, try to join existing containers, and create a pause process. + ctrs, err := ic.Libpod.GetRunningContainers() + if err != nil { + logrus.WithError(err).Fatal("") + } + + paths := []string{} + for _, ctr := range ctrs { + paths = append(paths, ctr.Config().ConmonPidFile) + } + + became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths) + if err := movePauseProcessToScope(); err != nil { + conf, err := ic.Config(context.Background()) + if err != nil { + return err + } + if conf.Engine.CgroupManager == config.SystemdCgroupsManager { + logrus.Warnf("Failed to add pause process to systemd sandbox cgroup: %v", err) + } else { + logrus.Debugf("Failed to add pause process to systemd sandbox cgroup: %v", err) + } + } + if err != nil { + logrus.WithError(err).Fatal("") + } + if became { + os.Exit(ret) + } + return nil +} + +// Most podman commands when run in rootless mode, need to be executed in the +// users usernamespace. This function is updated with a list of commands that +// should NOT be run within the user namespace. +func executeCommandInUserNS(cmd *cobra.Command) bool { + return os.Geteuid() == 0 + // if os.Geteuid() == 0 { + // return false + // } + // switch cmd { + // case _migrateCommand, + // _mountCommand, + // _renumberCommand, + // _searchCommand, + // _versionCommand: + // return false + // } + // return true +} + +func movePauseProcessToScope() error { + pausePidPath, err := util.GetRootlessPauseProcessPidPath() + if err != nil { + return errors.Wrapf(err, "could not get pause process pid file path") + } + + data, err := ioutil.ReadFile(pausePidPath) + if err != nil { + return errors.Wrapf(err, "cannot read pause pid file") + } + pid, err := strconv.ParseUint(string(data), 10, 0) + if err != nil { + return errors.Wrapf(err, "cannot parse pid file %s", pausePidPath) + } + + return utils.RunUnderSystemdScope(int(pid), "user.slice", "podman-pause.scope") +} + +func setRLimits() error { // nolint:deadcode,unused + rlimits := new(syscall.Rlimit) + rlimits.Cur = 1048576 + rlimits.Max = 1048576 + if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, rlimits); err != nil { + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, rlimits); err != nil { + return errors.Wrapf(err, "error getting rlimits") + } + rlimits.Cur = rlimits.Max + if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, rlimits); err != nil { + return errors.Wrapf(err, "error setting new rlimits") + } + } + return nil +} + +func setUMask() { // nolint:deadcode,unused + // Be sure we can create directories with 0755 mode. + syscall.Umask(0022) +} + +// checkInput can be used to verify any of the globalopt values +func checkInput() error { // nolint:deadcode,unused + return nil +} + +// func getCNIPluginsDir() string { +// if rootless.IsRootless() { +// return "" +// } +// +// return registry.PodmanOptions.Network.CNIPluginDirs[0] +// } diff --git a/pkg/domain/infra/runtime_abi.go b/pkg/domain/infra/runtime_abi.go index f11026571..0dbcf2ad2 100644 --- a/pkg/domain/infra/runtime_abi.go +++ b/pkg/domain/infra/runtime_abi.go @@ -12,7 +12,7 @@ import ( ) // NewContainerEngine factory provides a libpod runtime for container-related operations -func NewContainerEngine(facts entities.EngineOptions) (entities.ContainerEngine, error) { +func NewContainerEngine(facts entities.PodmanConfig) (entities.ContainerEngine, error) { switch facts.EngineMode { case entities.ABIMode: r, err := NewLibpodRuntime(facts.FlagSet, facts) @@ -25,7 +25,7 @@ func NewContainerEngine(facts entities.EngineOptions) (entities.ContainerEngine, } // NewContainerEngine factory provides a libpod runtime for image-related operations -func NewImageEngine(facts entities.EngineOptions) (entities.ImageEngine, error) { +func NewImageEngine(facts entities.PodmanConfig) (entities.ImageEngine, error) { switch facts.EngineMode { case entities.ABIMode: r, err := NewLibpodImageRuntime(facts.FlagSet, facts) diff --git a/pkg/domain/infra/runtime_image_proxy.go b/pkg/domain/infra/runtime_image_proxy.go index befc66b9a..45c5425a3 100644 --- a/pkg/domain/infra/runtime_image_proxy.go +++ b/pkg/domain/infra/runtime_image_proxy.go @@ -12,7 +12,7 @@ import ( // ContainerEngine Image Proxy will be EOL'ed after podmanV2 is separated from libpod repo -func NewLibpodImageRuntime(flags *pflag.FlagSet, opts entities.EngineOptions) (entities.ImageEngine, error) { +func NewLibpodImageRuntime(flags *pflag.FlagSet, opts entities.PodmanConfig) (entities.ImageEngine, error) { r, err := GetRuntime(context.Background(), flags, opts) if err != nil { return nil, err diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go index d59759707..9cf374e2e 100644 --- a/pkg/domain/infra/runtime_libpod.go +++ b/pkg/domain/infra/runtime_libpod.go @@ -1,3 +1,5 @@ +// build: ABISupport + package infra import ( @@ -22,68 +24,70 @@ type engineOpts struct { migrate bool noStore bool withFDS bool - flags entities.EngineOptions + config entities.PodmanConfig } // GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers -func GetRuntimeMigrate(ctx context.Context, fs *flag.FlagSet, ef entities.EngineOptions, newRuntime string) (*libpod.Runtime, error) { +func GetRuntimeMigrate(ctx context.Context, fs *flag.FlagSet, cfg entities.PodmanConfig, newRuntime string) (*libpod.Runtime, error) { return getRuntime(ctx, fs, &engineOpts{ name: newRuntime, renumber: false, migrate: true, noStore: false, withFDS: true, - flags: ef, + config: cfg, }) } // GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify -func GetRuntimeDisableFDs(ctx context.Context, fs *flag.FlagSet, ef entities.EngineOptions) (*libpod.Runtime, error) { +func GetRuntimeDisableFDs(ctx context.Context, fs *flag.FlagSet, cfg entities.PodmanConfig) (*libpod.Runtime, error) { return getRuntime(ctx, fs, &engineOpts{ renumber: false, migrate: false, noStore: false, withFDS: false, - flags: ef, + config: cfg, }) } // GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber -func GetRuntimeRenumber(ctx context.Context, fs *flag.FlagSet, ef entities.EngineOptions) (*libpod.Runtime, error) { +func GetRuntimeRenumber(ctx context.Context, fs *flag.FlagSet, cfg entities.PodmanConfig) (*libpod.Runtime, error) { return getRuntime(ctx, fs, &engineOpts{ renumber: true, migrate: false, noStore: false, withFDS: true, - flags: ef, + config: cfg, }) } // GetRuntime generates a new libpod runtime configured by command line options -func GetRuntime(ctx context.Context, flags *flag.FlagSet, ef entities.EngineOptions) (*libpod.Runtime, error) { +func GetRuntime(ctx context.Context, flags *flag.FlagSet, cfg entities.PodmanConfig) (*libpod.Runtime, error) { return getRuntime(ctx, flags, &engineOpts{ renumber: false, migrate: false, noStore: false, withFDS: true, - flags: ef, + config: cfg, }) } // GetRuntimeNoStore generates a new libpod runtime configured by command line options -func GetRuntimeNoStore(ctx context.Context, fs *flag.FlagSet, ef entities.EngineOptions) (*libpod.Runtime, error) { +func GetRuntimeNoStore(ctx context.Context, fs *flag.FlagSet, cfg entities.PodmanConfig) (*libpod.Runtime, error) { return getRuntime(ctx, fs, &engineOpts{ renumber: false, migrate: false, noStore: true, withFDS: true, - flags: ef, + config: cfg, }) } func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpod.Runtime, error) { options := []libpod.RuntimeOption{} storageOpts := storage.StoreOptions{} + cfg := opts.config + storageSet := false uidmapFlag := fs.Lookup("uidmap") @@ -109,25 +113,25 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo if fs.Changed("root") { storageSet = true - storageOpts.GraphRoot = opts.flags.Root + storageOpts.GraphRoot = cfg.Engine.StaticDir } if fs.Changed("runroot") { storageSet = true - storageOpts.RunRoot = opts.flags.Runroot + storageOpts.RunRoot = cfg.Runroot } if len(storageOpts.RunRoot) > 50 { return nil, errors.New("the specified runroot is longer than 50 characters") } if fs.Changed("storage-driver") { storageSet = true - storageOpts.GraphDriverName = opts.flags.StorageDriver + storageOpts.GraphDriverName = cfg.StorageDriver // Overriding the default storage driver caused GraphDriverOptions from storage.conf to be ignored storageOpts.GraphDriverOptions = []string{} } // This should always be checked after storage-driver is checked - if len(opts.flags.StorageOpts) > 0 { + if len(cfg.StorageOpts) > 0 { storageSet = true - storageOpts.GraphDriverOptions = opts.flags.StorageOpts + storageOpts.GraphDriverOptions = cfg.StorageOpts } if opts.migrate { options = append(options, libpod.WithMigrate()) @@ -151,30 +155,30 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo // TODO CLI flags for image config? // TODO CLI flag for signature policy? - if len(opts.flags.Namespace) > 0 { - options = append(options, libpod.WithNamespace(opts.flags.Namespace)) + if len(cfg.Engine.Namespace) > 0 { + options = append(options, libpod.WithNamespace(cfg.Engine.Namespace)) } if fs.Changed("runtime") { - options = append(options, libpod.WithOCIRuntime(opts.flags.Runtime)) + options = append(options, libpod.WithOCIRuntime(cfg.RuntimePath)) } if fs.Changed("conmon") { - options = append(options, libpod.WithConmonPath(opts.flags.ConmonPath)) + options = append(options, libpod.WithConmonPath(cfg.ConmonPath)) } if fs.Changed("tmpdir") { - options = append(options, libpod.WithTmpDir(opts.flags.TmpDir)) + options = append(options, libpod.WithTmpDir(cfg.Engine.TmpDir)) } if fs.Changed("network-cmd-path") { - options = append(options, libpod.WithNetworkCmdPath(opts.flags.NetworkCmdPath)) + options = append(options, libpod.WithNetworkCmdPath(cfg.Engine.NetworkCmdPath)) } if fs.Changed("events-backend") { - options = append(options, libpod.WithEventsLogger(opts.flags.EventsBackend)) + options = append(options, libpod.WithEventsLogger(cfg.Engine.EventsLogger)) } if fs.Changed("cgroup-manager") { - options = append(options, libpod.WithCgroupManager(opts.flags.CGroupManager)) + options = append(options, libpod.WithCgroupManager(cfg.Engine.CgroupManager)) } else { unified, err := cgroups.IsCgroup2UnifiedMode() if err != nil { @@ -189,13 +193,13 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo // TODO flag to set libpod tmp dir? if fs.Changed("cni-config-dir") { - options = append(options, libpod.WithCNIConfigDir(opts.flags.CniConfigDir)) + options = append(options, libpod.WithCNIConfigDir(cfg.Network.NetworkConfigDir)) } if fs.Changed("default-mounts-file") { - options = append(options, libpod.WithDefaultMountsFile(opts.flags.DefaultMountsFile)) + options = append(options, libpod.WithDefaultMountsFile(cfg.Containers.DefaultMountsFile)) } if fs.Changed("hooks-dir") { - options = append(options, libpod.WithHooksDir(opts.flags.HooksDir...)) + options = append(options, libpod.WithHooksDir(cfg.Engine.HooksDir...)) } // TODO flag to set CNI plugins dir? diff --git a/pkg/domain/infra/runtime_proxy.go b/pkg/domain/infra/runtime_proxy.go index 2e38c74b9..18f716ea0 100644 --- a/pkg/domain/infra/runtime_proxy.go +++ b/pkg/domain/infra/runtime_proxy.go @@ -12,7 +12,7 @@ import ( // ContainerEngine Proxy will be EOL'ed after podmanV2 is separated from libpod repo -func NewLibpodRuntime(flags *flag.FlagSet, opts entities.EngineOptions) (entities.ContainerEngine, error) { +func NewLibpodRuntime(flags *flag.FlagSet, opts entities.PodmanConfig) (entities.ContainerEngine, error) { r, err := GetRuntime(context.Background(), flags, opts) if err != nil { return nil, err diff --git a/pkg/domain/infra/runtime_tunnel.go b/pkg/domain/infra/runtime_tunnel.go index dc04b4e53..129fdeb2c 100644 --- a/pkg/domain/infra/runtime_tunnel.go +++ b/pkg/domain/infra/runtime_tunnel.go @@ -11,7 +11,7 @@ import ( "github.com/containers/libpod/pkg/domain/infra/tunnel" ) -func NewContainerEngine(facts entities.EngineOptions) (entities.ContainerEngine, error) { +func NewContainerEngine(facts entities.PodmanConfig) (entities.ContainerEngine, error) { switch facts.EngineMode { case entities.ABIMode: return nil, fmt.Errorf("direct runtime not supported") @@ -23,7 +23,7 @@ func NewContainerEngine(facts entities.EngineOptions) (entities.ContainerEngine, } // NewImageEngine factory provides a libpod runtime for image-related operations -func NewImageEngine(facts entities.EngineOptions) (entities.ImageEngine, error) { +func NewImageEngine(facts entities.PodmanConfig) (entities.ImageEngine, error) { switch facts.EngineMode { case entities.ABIMode: return nil, fmt.Errorf("direct image runtime not supported") diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index f59d4eb0a..05b62efcf 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -5,6 +5,7 @@ import ( "io" "os" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/bindings/containers" @@ -362,3 +363,7 @@ func (ic *ContainerEngine) ContainerMount(ctx context.Context, nameOrIds []strin func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []string, options entities.ContainerUnmountOptions) ([]*entities.ContainerUnmountReport, error) { return nil, errors.New("unmounting containers is not supported for remote clients") } + +func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) { + return config.Default() +} diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 54f2e8334..7d40e0327 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" images "github.com/containers/libpod/pkg/bindings/images" "github.com/containers/libpod/pkg/domain/entities" @@ -254,3 +255,7 @@ func (ir *ImageEngine) Diff(ctx context.Context, nameOrId string, _ entities.Dif func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) { return images.Search(ir.ClientCxt, term, opts) } + +func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { + return config.Default() +} diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 372c7c53b..1051ed311 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -516,6 +516,8 @@ func ParseInputTime(inputTime string) (time.Time, error) { } // GetGlobalOpts checks all global flags and generates the command string +// FIXME: Port input to config.Config +// TODO: Is there a "better" way to reverse values to flags? This seems brittle. func GetGlobalOpts(c *cliconfig.RunlabelValues) string { globalFlags := map[string]bool{ "cgroup-manager": true, "cni-config-dir": true, "conmon": true, "default-mounts-file": true, -- cgit v1.2.3-54-g00ecf