mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
Merge pull request #5812 from jwhonce/wip/options
Add support for the global flags and config files
This commit is contained in:
@ -31,6 +31,9 @@ var (
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
registry.RootRequired: "true",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -46,7 +46,7 @@ func init() {
|
||||
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.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("cidfile")
|
||||
_ = flags.MarkHidden("ignore")
|
||||
|
@ -44,7 +44,7 @@ func init() {
|
||||
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.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...
|
||||
_ = flags.MarkHidden("latest")
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ package main
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
_ "github.com/containers/libpod/cmd/podmanV2/containers"
|
||||
_ "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/system"
|
||||
_ "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/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := libpod.SetXdgDirs(); err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
// This is the bootstrap configuration, if user gives
|
||||
// CLI flags parts of this configuration may be overwritten
|
||||
registry.PodmanOptions = registry.NewPodmanConfig()
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -53,7 +28,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
for _, c := range registry.Commands {
|
||||
if Contains(registry.EngineOptions.EngineMode, c.Mode) {
|
||||
if Contains(registry.PodmanOptions.EngineMode, c.Mode) {
|
||||
parent := rootCmd
|
||||
if c.Parent != nil {
|
||||
parent = c.Parent
|
||||
|
59
cmd/podmanV2/registry/config.go
Normal file
59
cmd/podmanV2/registry/config.go
Normal 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}
|
||||
}
|
@ -29,8 +29,9 @@ var (
|
||||
exitCode = ExecErrorCodeGeneric
|
||||
imageEngine entities.ImageEngine
|
||||
|
||||
Commands []CliCommand
|
||||
EngineOptions entities.EngineOptions
|
||||
// Commands holds the cobra.Commands to present to the user, including
|
||||
// parent if not a child of "root"
|
||||
Commands []CliCommand
|
||||
)
|
||||
|
||||
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
|
||||
func NewImageEngine(cmd *cobra.Command, args []string) (entities.ImageEngine, error) {
|
||||
if imageEngine == nil {
|
||||
EngineOptions.FlagSet = cmd.Flags()
|
||||
engine, err := infra.NewImageEngine(EngineOptions)
|
||||
PodmanOptions.FlagSet = cmd.Flags()
|
||||
engine, err := infra.NewImageEngine(PodmanOptions)
|
||||
if err != nil {
|
||||
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
|
||||
func NewContainerEngine(cmd *cobra.Command, args []string) (entities.ContainerEngine, error) {
|
||||
if containerEngine == nil {
|
||||
EngineOptions.FlagSet = cmd.Flags()
|
||||
engine, err := infra.NewContainerEngine(EngineOptions)
|
||||
PodmanOptions.FlagSet = cmd.Flags()
|
||||
engine, err := infra.NewContainerEngine(PodmanOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -125,24 +126,17 @@ func IdOrLatestArgs(cmd *cobra.Command, args []string) error {
|
||||
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 {
|
||||
if cliCtx == nil {
|
||||
cliCtx = context.TODO()
|
||||
cliCtx = context.Background()
|
||||
}
|
||||
return cliCtx
|
||||
}
|
||||
|
||||
type ContextOptionsKey string
|
||||
|
||||
const PodmanOptionsKey ContextOptionsKey = "PodmanOptions"
|
||||
|
||||
func GetContextWithOptions() context.Context {
|
||||
return context.WithValue(GetContext(), PodmanOptionsKey, PodmanOptions)
|
||||
}
|
||||
|
@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func IsRemote() bool {
|
||||
return EngineOptions.EngineMode == entities.TunnelMode
|
||||
return PodmanOptions.EngineMode == entities.TunnelMode
|
||||
}
|
||||
|
@ -1,29 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/syslog"
|
||||
"os"
|
||||
"path"
|
||||
"runtime/pprof"
|
||||
|
||||
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||
"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/opentracing/opentracing-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
logrusSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{
|
||||
Use: path.Base(os.Args[0]),
|
||||
Long: "Manage pods, containers and images",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
TraverseChildren: true,
|
||||
PersistentPreRunE: preRunE,
|
||||
RunE: registry.SubCommandExists,
|
||||
Version: version.Version,
|
||||
Use: path.Base(os.Args[0]),
|
||||
Long: "Manage pods, containers and images",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
TraverseChildren: true,
|
||||
PersistentPreRunE: preRunE,
|
||||
RunE: registry.SubCommandExists,
|
||||
PersistentPostRunE: postRunE,
|
||||
Version: version.Version,
|
||||
}
|
||||
|
||||
logLevels = entities.NewStringSet("debug", "info", "warn", "error", "fatal", "panic")
|
||||
@ -32,30 +40,73 @@ var (
|
||||
)
|
||||
|
||||
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(®istry.EngineOptions.Uri, "remote", "r", "", "URL to access Podman service")
|
||||
rootCmd.PersistentFlags().StringSliceVar(®istry.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(
|
||||
logging,
|
||||
rootlessHook,
|
||||
loggingHook,
|
||||
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.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
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -83,17 +134,68 @@ func syslogHook() {
|
||||
}
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
o := registry.NewOptions(rootCmd.Context(), ®istry.EngineOptions)
|
||||
if err := rootCmd.ExecuteContext(o); err != nil {
|
||||
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)
|
||||
func rootlessHook() {
|
||||
if rootless.IsRootless() {
|
||||
logrus.Error("rootless mode is currently not supported. Support will return ASAP.")
|
||||
}
|
||||
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)")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
// 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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Config string
|
||||
CpuProfile string
|
||||
LogLevel string
|
||||
TmpDir string
|
||||
|
||||
RemoteUserName string
|
||||
RemoteHost string
|
||||
VarlinkAddress string
|
||||
ConnectionName string
|
||||
RemoteConfigFilePath string
|
||||
Port int
|
||||
IdentityFile string
|
||||
IgnoreHosts bool
|
||||
Runroot string
|
||||
StorageDriver string
|
||||
StorageOpts []string
|
||||
}
|
||||
|
||||
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
|
||||
// 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
|
||||
// }
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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]
|
||||
// }
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user