Merge pull request #5812 from jwhonce/wip/options

Add support for the global flags and config files
This commit is contained in:
OpenShift Merge Robot
2020-04-15 01:48:52 +02:00
committed by GitHub
22 changed files with 683 additions and 188 deletions

View File

@ -31,6 +31,9 @@ var (
Args: func(cmd *cobra.Command, args []string) error { Args: func(cmd *cobra.Command, args []string) error {
return parse.CheckAllLatestAndCIDFile(cmd, args, true, false) return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
}, },
Annotations: map[string]string{
registry.RootRequired: "true",
},
} }
) )

View File

@ -46,7 +46,7 @@ func init() {
flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file")
flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.UintVarP(&stopTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") flags.UintVarP(&stopTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
if registry.EngineOptions.EngineMode == entities.ABIMode { if registry.PodmanOptions.EngineMode == entities.ABIMode {
_ = flags.MarkHidden("latest") _ = flags.MarkHidden("latest")
_ = flags.MarkHidden("cidfile") _ = flags.MarkHidden("cidfile")
_ = flags.MarkHidden("ignore") _ = flags.MarkHidden("ignore")

View File

@ -44,7 +44,7 @@ func init() {
flags.DurationVarP(&waitOptions.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion") flags.DurationVarP(&waitOptions.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion")
flags.BoolVarP(&waitOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVarP(&waitOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.StringVar(&waitCondition, "condition", "stopped", "Condition to wait on") flags.StringVar(&waitCondition, "condition", "stopped", "Condition to wait on")
if registry.EngineOptions.EngineMode == entities.ABIMode { if registry.PodmanOptions.EngineMode == entities.ABIMode {
// TODO: This is the same as V1. We could skip creating the flag altogether in V2... // TODO: This is the same as V1. We could skip creating the flag altogether in V2...
_ = flags.MarkHidden("latest") _ = flags.MarkHidden("latest")
} }

View File

@ -3,8 +3,6 @@ package main
import ( import (
"os" "os"
"reflect" "reflect"
"runtime"
"strings"
_ "github.com/containers/libpod/cmd/podmanV2/containers" _ "github.com/containers/libpod/cmd/podmanV2/containers"
_ "github.com/containers/libpod/cmd/podmanV2/healthcheck" _ "github.com/containers/libpod/cmd/podmanV2/healthcheck"
@ -14,36 +12,13 @@ import (
"github.com/containers/libpod/cmd/podmanV2/registry" "github.com/containers/libpod/cmd/podmanV2/registry"
_ "github.com/containers/libpod/cmd/podmanV2/system" _ "github.com/containers/libpod/cmd/podmanV2/system"
_ "github.com/containers/libpod/cmd/podmanV2/volumes" _ "github.com/containers/libpod/cmd/podmanV2/volumes"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/storage/pkg/reexec" "github.com/containers/storage/pkg/reexec"
"github.com/sirupsen/logrus"
) )
func init() { func init() {
if err := libpod.SetXdgDirs(); err != nil { // This is the bootstrap configuration, if user gives
logrus.Errorf(err.Error()) // CLI flags parts of this configuration may be overwritten
os.Exit(1) registry.PodmanOptions = registry.NewPodmanConfig()
}
switch runtime.GOOS {
case "darwin":
fallthrough
case "windows":
registry.EngineOptions.EngineMode = entities.TunnelMode
case "linux":
registry.EngineOptions.EngineMode = entities.ABIMode
default:
logrus.Errorf("%s is not a supported OS", runtime.GOOS)
os.Exit(1)
}
// TODO: Is there a Cobra way to "peek" at os.Args?
for _, v := range os.Args {
if strings.HasPrefix(v, "--remote") {
registry.EngineOptions.EngineMode = entities.TunnelMode
}
}
} }
func main() { func main() {
@ -53,7 +28,7 @@ func main() {
return return
} }
for _, c := range registry.Commands { for _, c := range registry.Commands {
if Contains(registry.EngineOptions.EngineMode, c.Mode) { if Contains(registry.PodmanOptions.EngineMode, c.Mode) {
parent := rootCmd parent := rootCmd
if c.Parent != nil { if c.Parent != nil {
parent = c.Parent parent = c.Parent

View File

@ -0,0 +1,59 @@
package registry
import (
"os"
"runtime"
"strings"
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/sirupsen/logrus"
)
const (
RootRequired = "RootRequired"
)
var (
PodmanOptions entities.PodmanConfig
)
// NewPodmanConfig creates a PodmanConfig from the environment
func NewPodmanConfig() entities.PodmanConfig {
if err := libpod.SetXdgDirs(); err != nil {
logrus.Errorf(err.Error())
os.Exit(1)
}
var mode entities.EngineMode
switch runtime.GOOS {
case "darwin":
fallthrough
case "windows":
mode = entities.TunnelMode
case "linux":
mode = entities.ABIMode
default:
logrus.Errorf("%s is not a supported OS", runtime.GOOS)
os.Exit(1)
}
// cobra.Execute() may not be called yet, so we peek at os.Args.
for _, v := range os.Args {
// Prefix checking works because of how default EngineMode's
// have been defined.
if strings.HasPrefix(v, "--remote=") {
mode = entities.TunnelMode
}
}
// FIXME: for rootless, where to get the path
// TODO:
cfg, err := config.NewConfig("")
if err != nil {
logrus.Error("Failed to obtain podman configuration")
os.Exit(1)
}
return entities.PodmanConfig{Config: cfg, EngineMode: mode}
}

View File

@ -29,8 +29,9 @@ var (
exitCode = ExecErrorCodeGeneric exitCode = ExecErrorCodeGeneric
imageEngine entities.ImageEngine imageEngine entities.ImageEngine
Commands []CliCommand // Commands holds the cobra.Commands to present to the user, including
EngineOptions entities.EngineOptions // parent if not a child of "root"
Commands []CliCommand
) )
func SetExitCode(code int) { func SetExitCode(code int) {
@ -83,8 +84,8 @@ func ImageEngine() entities.ImageEngine {
// NewImageEngine is a wrapper for building an ImageEngine to be used for PreRunE functions // NewImageEngine is a wrapper for building an ImageEngine to be used for PreRunE functions
func NewImageEngine(cmd *cobra.Command, args []string) (entities.ImageEngine, error) { func NewImageEngine(cmd *cobra.Command, args []string) (entities.ImageEngine, error) {
if imageEngine == nil { if imageEngine == nil {
EngineOptions.FlagSet = cmd.Flags() PodmanOptions.FlagSet = cmd.Flags()
engine, err := infra.NewImageEngine(EngineOptions) engine, err := infra.NewImageEngine(PodmanOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -100,8 +101,8 @@ func ContainerEngine() entities.ContainerEngine {
// NewContainerEngine is a wrapper for building an ContainerEngine to be used for PreRunE functions // NewContainerEngine is a wrapper for building an ContainerEngine to be used for PreRunE functions
func NewContainerEngine(cmd *cobra.Command, args []string) (entities.ContainerEngine, error) { func NewContainerEngine(cmd *cobra.Command, args []string) (entities.ContainerEngine, error) {
if containerEngine == nil { if containerEngine == nil {
EngineOptions.FlagSet = cmd.Flags() PodmanOptions.FlagSet = cmd.Flags()
engine, err := infra.NewContainerEngine(EngineOptions) engine, err := infra.NewContainerEngine(PodmanOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -125,24 +126,17 @@ func IdOrLatestArgs(cmd *cobra.Command, args []string) error {
return nil return nil
} }
type podmanContextKey string
var podmanFactsKey = podmanContextKey("engineOptions")
func NewOptions(ctx context.Context, facts *entities.EngineOptions) context.Context {
return context.WithValue(ctx, podmanFactsKey, facts)
}
func Options(cmd *cobra.Command) (*entities.EngineOptions, error) {
if f, ok := cmd.Context().Value(podmanFactsKey).(*entities.EngineOptions); ok {
return f, errors.New("Command Context ")
}
return nil, nil
}
func GetContext() context.Context { func GetContext() context.Context {
if cliCtx == nil { if cliCtx == nil {
cliCtx = context.TODO() cliCtx = context.Background()
} }
return cliCtx return cliCtx
} }
type ContextOptionsKey string
const PodmanOptionsKey ContextOptionsKey = "PodmanOptions"
func GetContextWithOptions() context.Context {
return context.WithValue(GetContext(), PodmanOptionsKey, PodmanOptions)
}

View File

@ -5,5 +5,5 @@ import (
) )
func IsRemote() bool { func IsRemote() bool {
return EngineOptions.EngineMode == entities.TunnelMode return PodmanOptions.EngineMode == entities.TunnelMode
} }

View File

@ -1,29 +1,37 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"log/syslog" "log/syslog"
"os" "os"
"path" "path"
"runtime/pprof"
"github.com/containers/libpod/cmd/podmanV2/registry" "github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/tracing"
"github.com/containers/libpod/version" "github.com/containers/libpod/version"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
logrusSyslog "github.com/sirupsen/logrus/hooks/syslog" logrusSyslog "github.com/sirupsen/logrus/hooks/syslog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
) )
var ( var (
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: path.Base(os.Args[0]), Use: path.Base(os.Args[0]),
Long: "Manage pods, containers and images", Long: "Manage pods, containers and images",
SilenceUsage: true, SilenceUsage: true,
SilenceErrors: true, SilenceErrors: true,
TraverseChildren: true, TraverseChildren: true,
PersistentPreRunE: preRunE, PersistentPreRunE: preRunE,
RunE: registry.SubCommandExists, RunE: registry.SubCommandExists,
Version: version.Version, PersistentPostRunE: postRunE,
Version: version.Version,
} }
logLevels = entities.NewStringSet("debug", "info", "warn", "error", "fatal", "panic") logLevels = entities.NewStringSet("debug", "info", "warn", "error", "fatal", "panic")
@ -32,30 +40,73 @@ var (
) )
func init() { func init() {
// Override default --help information of `--version` global flag}
var dummyVersion bool
// TODO had to disable shorthand -v for version due to -v rm with volume
rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version of Podman")
rootCmd.PersistentFlags().StringVarP(&registry.EngineOptions.Uri, "remote", "r", "", "URL to access Podman service")
rootCmd.PersistentFlags().StringSliceVar(&registry.EngineOptions.Identities, "identity", []string{}, "path to SSH identity file")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "error", fmt.Sprintf("Log messages above specified level (%s)", logLevels.String()))
rootCmd.PersistentFlags().BoolVar(&useSyslog, "syslog", false, "Output logging information to syslog as well as the console (default false)")
cobra.OnInitialize( cobra.OnInitialize(
logging, rootlessHook,
loggingHook,
syslogHook, syslogHook,
) )
rootFlags(registry.PodmanOptions, rootCmd.PersistentFlags())
} }
func preRunE(cmd *cobra.Command, args []string) error { func Execute() {
if err := rootCmd.ExecuteContext(registry.GetContextWithOptions()); err != nil {
logrus.Error(err)
} else if registry.GetExitCode() == registry.ExecErrorCodeGeneric {
// The exitCode modified from registry.ExecErrorCodeGeneric,
// indicates an application
// running inside of a container failed, as opposed to the
// podman command failed. Must exit with that exit code
// otherwise command exited correctly.
registry.SetExitCode(0)
}
os.Exit(registry.GetExitCode())
}
func preRunE(cmd *cobra.Command, _ []string) error {
// Update PodmanOptions now that we "know" more
// TODO: pass in path overriding configuration file
registry.PodmanOptions = registry.NewPodmanConfig()
cmd.SetHelpTemplate(registry.HelpTemplate()) cmd.SetHelpTemplate(registry.HelpTemplate())
cmd.SetUsageTemplate(registry.UsageTemplate()) cmd.SetUsageTemplate(registry.UsageTemplate())
if cmd.Flag("cpu_profile").Changed {
f, err := os.Create(registry.PodmanOptions.CpuProfile)
if err != nil {
return errors.Wrapf(err, "unable to create cpu profiling file %s",
registry.PodmanOptions.CpuProfile)
}
if err := pprof.StartCPUProfile(f); err != nil {
return err
}
}
if cmd.Flag("trace").Changed {
tracer, closer := tracing.Init("podman")
opentracing.SetGlobalTracer(tracer)
registry.PodmanOptions.SpanCloser = closer
registry.PodmanOptions.Span = tracer.StartSpan("before-context")
registry.PodmanOptions.SpanCtx = opentracing.ContextWithSpan(context.Background(), registry.PodmanOptions.Span)
}
return nil return nil
} }
func logging() { func postRunE(cmd *cobra.Command, args []string) error {
if cmd.Flag("cpu-profile").Changed {
pprof.StopCPUProfile()
}
if cmd.Flag("trace").Changed {
registry.PodmanOptions.Span.Finish()
registry.PodmanOptions.SpanCloser.Close()
}
return nil
}
func loggingHook() {
if !logLevels.Contains(logLevel) { if !logLevels.Contains(logLevel) {
fmt.Fprintf(os.Stderr, "Log Level \"%s\" is not supported, choose from: %s\n", logLevel, logLevels.String()) logrus.Errorf("Log Level \"%s\" is not supported, choose from: %s", logLevel, logLevels.String())
os.Exit(1) os.Exit(1)
} }
@ -83,17 +134,68 @@ func syslogHook() {
} }
} }
func Execute() { func rootlessHook() {
o := registry.NewOptions(rootCmd.Context(), &registry.EngineOptions) if rootless.IsRootless() {
if err := rootCmd.ExecuteContext(o); err != nil { logrus.Error("rootless mode is currently not supported. Support will return ASAP.")
fmt.Fprintln(os.Stderr, "Error:", err.Error())
} else if registry.GetExitCode() == registry.ExecErrorCodeGeneric {
// The exitCode modified from registry.ExecErrorCodeGeneric,
// indicates an application
// running inside of a container failed, as opposed to the
// podman command failed. Must exit with that exit code
// otherwise command exited correctly.
registry.SetExitCode(0)
} }
os.Exit(registry.GetExitCode()) // ce, err := registry.NewContainerEngine(rootCmd, []string{})
// if err != nil {
// logrus.WithError(err).Fatal("failed to obtain container engine")
// }
// ce.SetupRootLess(rootCmd)
}
func rootFlags(opts entities.PodmanConfig, flags *pflag.FlagSet) {
// V2 flags
flags.StringVarP(&opts.Uri, "remote", "r", "", "URL to access Podman service")
flags.StringSliceVar(&opts.Identities, "identity", []string{}, "path to SSH identity file")
// Override default --help information of `--version` global flag
// TODO: restore -v option for version without breaking -v for volumes
var dummyVersion bool
flags.BoolVar(&dummyVersion, "version", false, "Version of Podman")
cfg := opts.Config
flags.StringVar(&cfg.Engine.CgroupManager, "cgroup-manager", cfg.Engine.CgroupManager, opts.CGroupUsage)
flags.StringVar(&opts.CpuProfile, "cpu-profile", "", "Path for the cpu profiling results")
flags.StringVar(&opts.ConmonPath, "conmon", "", "Path of the conmon binary")
flags.StringVar(&cfg.Engine.NetworkCmdPath, "network-cmd-path", cfg.Engine.NetworkCmdPath, "Path to the command for configuring the network")
flags.StringVar(&cfg.Network.NetworkConfigDir, "cni-config-dir", cfg.Network.NetworkConfigDir, "Path of the configuration directory for CNI networks")
flags.StringVar(&cfg.Containers.DefaultMountsFile, "default-mounts-file", cfg.Containers.DefaultMountsFile, "Path to default mounts file")
flags.StringVar(&cfg.Engine.EventsLogger, "events-backend", cfg.Engine.EventsLogger, `Events backend to use ("file"|"journald"|"none")`)
flags.StringSliceVar(&cfg.Engine.HooksDir, "hooks-dir", cfg.Engine.HooksDir, "Set the OCI hooks directory path (may be set multiple times)")
flags.IntVar(&opts.MaxWorks, "max-workers", 0, "The maximum number of workers for parallel operations")
flags.StringVar(&cfg.Engine.Namespace, "namespace", cfg.Engine.Namespace, "Set the libpod namespace, used to create separate views of the containers and pods on the system")
flags.StringVar(&cfg.Engine.StaticDir, "root", "", "Path to the root directory in which data, including images, is stored")
flags.StringVar(&opts.Runroot, "runroot", "", "Path to the 'run directory' where all state information is stored")
flags.StringVar(&opts.RuntimePath, "runtime", "", "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc")
// -s is deprecated due to conflict with -s on subcommands
flags.StringVar(&opts.StorageDriver, "storage-driver", "", "Select which storage driver is used to manage storage of images and containers (default is overlay)")
flags.StringArrayVar(&opts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver")
flags.StringVar(&opts.Engine.TmpDir, "tmpdir", "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n")
flags.BoolVar(&opts.Trace, "trace", false, "Enable opentracing output (default false)")
// Override default --help information of `--help` global flag
var dummyHelp bool
flags.BoolVar(&dummyHelp, "help", false, "Help for podman")
flags.StringVar(&logLevel, "log-level", logLevel, fmt.Sprintf("Log messages above specified level (%s)", logLevels.String()))
// Hide these flags for both ABI and Tunneling
for _, f := range []string{
"cpu-profile",
"default-mounts-file",
"max-workers",
"trace",
} {
if err := flags.MarkHidden(f); err != nil {
logrus.Warnf("unable to mark %s flag as hidden", f)
}
}
// Only create these flags for ABI connections
if !registry.IsRemote() {
flags.BoolVar(&useSyslog, "syslog", false, "Output logging information to syslog as well as the console (default false)")
}
} }

View File

@ -1,13 +1,23 @@
package entities package entities
import ( import (
"os/user" "context"
"path/filepath" "fmt"
"io"
"os"
"github.com/containers/buildah/pkg/parse"
"github.com/containers/common/pkg/config" "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" "github.com/spf13/pflag"
) )
// EngineMode is the connection type podman is using to access libpod
type EngineMode string type EngineMode string
const ( const (
@ -15,78 +25,243 @@ const (
TunnelMode = EngineMode("tunnel") TunnelMode = EngineMode("tunnel")
) )
// Convert EngineMode to String
func (m EngineMode) String() string { func (m EngineMode) String() string {
return string(m) return string(m)
} }
type EngineOptions struct { // PodmanConfig combines the defaults and settings from the file system with the
Uri string // flags given in os.Args. Some runtime state is also stored here.
Identities []string type PodmanConfig struct {
FlagSet *pflag.FlagSet *config.Config
EngineMode EngineMode *pflag.FlagSet
CGroupManager string CGroupUsage string // rootless code determines Usage message
CniConfigDir string ConmonPath string // --conmon flag will set Engine.ConmonPath
ConmonPath string CpuProfile string // Hidden: Should CPU profile be taken
DefaultMountsFile string EngineMode EngineMode // ABI or Tunneling mode
EventsBackend string Identities []string // ssh identities for connecting to server
HooksDir []string MaxWorks int // maximum number of parallel threads
MaxWorks int RuntimePath string // --runtime flag will set Engine.RuntimePath
Namespace string SpanCloser io.Closer // Close() for tracing object
Root string SpanCtx context.Context // context to use when tracing
Runroot string Span opentracing.Span // tracing object
Runtime string Syslog bool // write to StdOut and Syslog, not supported when tunneling
StorageDriver string Trace bool // Hidden: Trace execution
StorageOpts []string Uri string // URI to API Service
Syslog bool
Trace bool
NetworkCmdPath string
Config string Runroot string
CpuProfile string StorageDriver string
LogLevel string StorageOpts []string
TmpDir string
RemoteUserName string
RemoteHost string
VarlinkAddress string
ConnectionName string
RemoteConfigFilePath string
Port int
IdentityFile string
IgnoreHosts bool
} }
func NewEngineOptions() (EngineOptions, error) { // DefaultSecurityOptions: getter for security options from configuration
u, _ := user.Current() func (c PodmanConfig) DefaultSecurityOptions() []string {
return EngineOptions{ securityOpts := []string{}
CGroupManager: config.SystemdCgroupsManager, if c.Containers.SeccompProfile != "" && c.Containers.SeccompProfile != parse.SeccompDefaultPath {
CniConfigDir: "", securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", c.Containers.SeccompProfile))
Config: "", }
ConmonPath: filepath.Join("usr", "bin", "conmon"), if apparmor.IsEnabled() && c.Containers.ApparmorProfile != "" {
ConnectionName: "", securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", c.Containers.ApparmorProfile))
CpuProfile: "", }
DefaultMountsFile: "", if selinux.GetEnabled() && !c.Containers.EnableLabeling {
EventsBackend: "", securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0]))
HooksDir: nil, }
IdentityFile: "", return securityOpts
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
} }
// 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
// }

View File

@ -3,11 +3,13 @@ package entities
import ( import (
"context" "context"
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/specgen" "github.com/containers/libpod/pkg/specgen"
) )
type ContainerEngine interface { type ContainerEngine interface {
Config(ctx context.Context) (*config.Config, error)
ContainerAttach(ctx context.Context, nameOrId string, options AttachOptions) error ContainerAttach(ctx context.Context, nameOrId string, options AttachOptions) error
ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error) ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error)
ContainerCleanup(ctx context.Context, namesOrIds []string, options ContainerCleanupOptions) ([]*ContainerCleanupReport, error) ContainerCleanup(ctx context.Context, namesOrIds []string, options ContainerCleanupOptions) ([]*ContainerCleanupReport, error)

View File

@ -2,9 +2,12 @@ package entities
import ( import (
"context" "context"
"github.com/containers/common/pkg/config"
) )
type ImageEngine interface { type ImageEngine interface {
Config(ctx context.Context) (*config.Config, error)
Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error) Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error)
Diff(ctx context.Context, nameOrId string, options DiffOptions) (*DiffReport, error) Diff(ctx context.Context, nameOrId string, options DiffOptions) (*DiffReport, error)
Exists(ctx context.Context, nameOrId string) (*BoolReport, error) Exists(ctx context.Context, nameOrId string) (*BoolReport, error)

View File

@ -12,6 +12,7 @@ import (
"sync" "sync"
"github.com/containers/buildah" "github.com/containers/buildah"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
@ -893,3 +894,8 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []str
} }
return reports, nil 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()
}

View File

@ -9,6 +9,7 @@ import (
"os" "os"
"strings" "strings"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker"
dockerarchive "github.com/containers/image/v5/docker/archive" dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference" "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 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()
}

View File

@ -4,17 +4,28 @@ package abi
import ( import (
"context" "context"
"fmt"
"io/ioutil"
"net" "net"
"os"
"strconv"
"strings" "strings"
"syscall"
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
api "github.com/containers/libpod/pkg/api/server" 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/domain/entities"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
iopodman "github.com/containers/libpod/pkg/varlink" iopodman "github.com/containers/libpod/pkg/varlink"
iopodmanAPI "github.com/containers/libpod/pkg/varlinkapi" iopodmanAPI "github.com/containers/libpod/pkg/varlinkapi"
"github.com/containers/libpod/utils"
"github.com/containers/libpod/version" "github.com/containers/libpod/version"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/varlink/go/varlink" "github.com/varlink/go/varlink"
) )
@ -88,3 +99,146 @@ func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.Servi
} }
return nil 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]
// }

View File

@ -12,7 +12,7 @@ import (
) )
// NewContainerEngine factory provides a libpod runtime for container-related operations // 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 { switch facts.EngineMode {
case entities.ABIMode: case entities.ABIMode:
r, err := NewLibpodRuntime(facts.FlagSet, facts) 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 // 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 { switch facts.EngineMode {
case entities.ABIMode: case entities.ABIMode:
r, err := NewLibpodImageRuntime(facts.FlagSet, facts) r, err := NewLibpodImageRuntime(facts.FlagSet, facts)

View File

@ -12,7 +12,7 @@ import (
// ContainerEngine Image Proxy will be EOL'ed after podmanV2 is separated from libpod repo // 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) r, err := GetRuntime(context.Background(), flags, opts)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -1,3 +1,5 @@
// build: ABISupport
package infra package infra
import ( import (
@ -22,68 +24,70 @@ type engineOpts struct {
migrate bool migrate bool
noStore bool noStore bool
withFDS bool withFDS bool
flags entities.EngineOptions config entities.PodmanConfig
} }
// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers // 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{ return getRuntime(ctx, fs, &engineOpts{
name: newRuntime, name: newRuntime,
renumber: false, renumber: false,
migrate: true, migrate: true,
noStore: false, noStore: false,
withFDS: true, withFDS: true,
flags: ef, config: cfg,
}) })
} }
// GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify // 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{ return getRuntime(ctx, fs, &engineOpts{
renumber: false, renumber: false,
migrate: false, migrate: false,
noStore: false, noStore: false,
withFDS: false, withFDS: false,
flags: ef, config: cfg,
}) })
} }
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber // 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{ return getRuntime(ctx, fs, &engineOpts{
renumber: true, renumber: true,
migrate: false, migrate: false,
noStore: false, noStore: false,
withFDS: true, withFDS: true,
flags: ef, config: cfg,
}) })
} }
// GetRuntime generates a new libpod runtime configured by command line options // 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{ return getRuntime(ctx, flags, &engineOpts{
renumber: false, renumber: false,
migrate: false, migrate: false,
noStore: false, noStore: false,
withFDS: true, withFDS: true,
flags: ef, config: cfg,
}) })
} }
// GetRuntimeNoStore generates a new libpod runtime configured by command line options // 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{ return getRuntime(ctx, fs, &engineOpts{
renumber: false, renumber: false,
migrate: false, migrate: false,
noStore: true, noStore: true,
withFDS: true, withFDS: true,
flags: ef, config: cfg,
}) })
} }
func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpod.Runtime, error) { func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{} options := []libpod.RuntimeOption{}
storageOpts := storage.StoreOptions{} storageOpts := storage.StoreOptions{}
cfg := opts.config
storageSet := false storageSet := false
uidmapFlag := fs.Lookup("uidmap") uidmapFlag := fs.Lookup("uidmap")
@ -109,25 +113,25 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo
if fs.Changed("root") { if fs.Changed("root") {
storageSet = true storageSet = true
storageOpts.GraphRoot = opts.flags.Root storageOpts.GraphRoot = cfg.Engine.StaticDir
} }
if fs.Changed("runroot") { if fs.Changed("runroot") {
storageSet = true storageSet = true
storageOpts.RunRoot = opts.flags.Runroot storageOpts.RunRoot = cfg.Runroot
} }
if len(storageOpts.RunRoot) > 50 { if len(storageOpts.RunRoot) > 50 {
return nil, errors.New("the specified runroot is longer than 50 characters") return nil, errors.New("the specified runroot is longer than 50 characters")
} }
if fs.Changed("storage-driver") { if fs.Changed("storage-driver") {
storageSet = true storageSet = true
storageOpts.GraphDriverName = opts.flags.StorageDriver storageOpts.GraphDriverName = cfg.StorageDriver
// Overriding the default storage driver caused GraphDriverOptions from storage.conf to be ignored // Overriding the default storage driver caused GraphDriverOptions from storage.conf to be ignored
storageOpts.GraphDriverOptions = []string{} storageOpts.GraphDriverOptions = []string{}
} }
// This should always be checked after storage-driver is checked // This should always be checked after storage-driver is checked
if len(opts.flags.StorageOpts) > 0 { if len(cfg.StorageOpts) > 0 {
storageSet = true storageSet = true
storageOpts.GraphDriverOptions = opts.flags.StorageOpts storageOpts.GraphDriverOptions = cfg.StorageOpts
} }
if opts.migrate { if opts.migrate {
options = append(options, libpod.WithMigrate()) 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 flags for image config?
// TODO CLI flag for signature policy? // TODO CLI flag for signature policy?
if len(opts.flags.Namespace) > 0 { if len(cfg.Engine.Namespace) > 0 {
options = append(options, libpod.WithNamespace(opts.flags.Namespace)) options = append(options, libpod.WithNamespace(cfg.Engine.Namespace))
} }
if fs.Changed("runtime") { if fs.Changed("runtime") {
options = append(options, libpod.WithOCIRuntime(opts.flags.Runtime)) options = append(options, libpod.WithOCIRuntime(cfg.RuntimePath))
} }
if fs.Changed("conmon") { if fs.Changed("conmon") {
options = append(options, libpod.WithConmonPath(opts.flags.ConmonPath)) options = append(options, libpod.WithConmonPath(cfg.ConmonPath))
} }
if fs.Changed("tmpdir") { 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") { 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") { 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") { if fs.Changed("cgroup-manager") {
options = append(options, libpod.WithCgroupManager(opts.flags.CGroupManager)) options = append(options, libpod.WithCgroupManager(cfg.Engine.CgroupManager))
} else { } else {
unified, err := cgroups.IsCgroup2UnifiedMode() unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil { 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? // TODO flag to set libpod tmp dir?
if fs.Changed("cni-config-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") { 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") { 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? // TODO flag to set CNI plugins dir?

View File

@ -12,7 +12,7 @@ import (
// ContainerEngine Proxy will be EOL'ed after podmanV2 is separated from libpod repo // 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) r, err := GetRuntime(context.Background(), flags, opts)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -11,7 +11,7 @@ import (
"github.com/containers/libpod/pkg/domain/infra/tunnel" "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 { switch facts.EngineMode {
case entities.ABIMode: case entities.ABIMode:
return nil, fmt.Errorf("direct runtime not supported") 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 // 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 { switch facts.EngineMode {
case entities.ABIMode: case entities.ABIMode:
return nil, fmt.Errorf("direct image runtime not supported") return nil, fmt.Errorf("direct image runtime not supported")

View File

@ -5,6 +5,7 @@ import (
"io" "io"
"os" "os"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/bindings/containers" "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) { 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") return nil, errors.New("unmounting containers is not supported for remote clients")
} }
func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) {
return config.Default()
}

View File

@ -5,6 +5,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
images "github.com/containers/libpod/pkg/bindings/images" images "github.com/containers/libpod/pkg/bindings/images"
"github.com/containers/libpod/pkg/domain/entities" "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) { func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
return images.Search(ir.ClientCxt, term, opts) return images.Search(ir.ClientCxt, term, opts)
} }
func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) {
return config.Default()
}

View File

@ -516,6 +516,8 @@ func ParseInputTime(inputTime string) (time.Time, error) {
} }
// GetGlobalOpts checks all global flags and generates the command string // 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 { func GetGlobalOpts(c *cliconfig.RunlabelValues) string {
globalFlags := map[string]bool{ globalFlags := map[string]bool{
"cgroup-manager": true, "cni-config-dir": true, "conmon": true, "default-mounts-file": true, "cgroup-manager": true, "cni-config-dir": true, "conmon": true, "default-mounts-file": true,