diff options
44 files changed, 92 insertions, 1525 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 49a40dfa0..f256d9677 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -51,12 +51,12 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringVar( &cf.CGroupsNS, - "cgroupns", getDefaultCgroupNS(), + "cgroupns", containerConfig.CgroupNS(), "cgroup namespace to use", ) createFlags.StringVar( &cf.CGroups, - "cgroups", "enabled", + "cgroups", containerConfig.Cgroups(), `control container cgroup configuration ("enabled"|"disabled"|"no-conmon")`, ) createFlags.StringVar( @@ -121,12 +121,12 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringVar( &cf.DetachKeys, - "detach-keys", GetDefaultDetachKeys(), + "detach-keys", containerConfig.DetachKeys(), "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`", ) createFlags.StringSliceVar( &cf.Device, - "device", getDefaultDevices(), + "device", containerConfig.Devices(), fmt.Sprintf("Add a host device to the container"), ) createFlags.StringSliceVar( @@ -161,7 +161,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringArrayVarP( &cf.env, - "env", "e", getDefaultEnv(), + "env", "e", containerConfig.Env(), "Set environment variables in container", ) createFlags.BoolVar( @@ -238,7 +238,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringVar( &cf.InitPath, - "init-path", getDefaultInitPath(), + "init-path", containerConfig.InitPath(), // Do not use the Value field for setting the default value to determine user input (i.e., non-empty string) fmt.Sprintf("Path to the container-init binary"), ) @@ -249,7 +249,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringVar( &cf.IPC, - "ipc", getDefaultIPCNS(), + "ipc", containerConfig.IPCNS(), "IPC namespace to use", ) createFlags.StringVar( @@ -331,13 +331,13 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { // markFlagHidden(createFlags, "override-os") createFlags.StringVar( &cf.PID, - "pid", getDefaultPidNS(), + "pid", containerConfig.PidNS(), "PID namespace to use", ) createFlags.Int64Var( &cf.PIDsLimit, - "pids-limit", getDefaultPidsLimit(), - getDefaultPidsDescription(), + "pids-limit", containerConfig.PidsLimit(), + "Tune container pids limit (set 0 for unlimited, -1 for server defaults)", ) createFlags.StringVar( &cf.Pod, @@ -391,12 +391,12 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringArrayVar( &cf.SecurityOpt, - "security-opt", getDefaultSecurityOptions(), + "security-opt", containerConfig.SecurityOptions(), "Security Options", ) createFlags.StringVar( &cf.ShmSize, - "shm-size", getDefaultShmSize(), + "shm-size", containerConfig.ShmSize(), "Size of /dev/shm "+sizeWithUnitFormat, ) createFlags.StringVar( @@ -427,7 +427,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { createFlags.StringSliceVar( &cf.Sysctl, - "sysctl", getDefaultSysctls(), + "sysctl", containerConfig.Sysctls(), "Sysctl options", ) createFlags.StringVar( @@ -452,7 +452,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringSliceVar( &cf.Ulimit, - "ulimit", getDefaultUlimits(), + "ulimit", containerConfig.Ulimits(), "Ulimit options", ) createFlags.StringVarP( @@ -462,12 +462,12 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringVar( &cf.UserNS, - "userns", getDefaultUserNS(), + "userns", containerConfig.Containers.UserNS, "User namespace to use", ) createFlags.StringVar( &cf.UTS, - "uts", getDefaultUTSNS(), + "uts", containerConfig.Containers.UTSNS, "UTS namespace to use", ) createFlags.StringArrayVar( @@ -477,7 +477,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { ) createFlags.StringArrayVarP( &cf.Volume, - "volume", "v", getDefaultVolumes(), + "volume", "v", containerConfig.Volumes(), "Bind mount a volume into the container", ) createFlags.StringSliceVar( diff --git a/cmd/podman/common/default.go b/cmd/podman/common/default.go index 853f87ab6..89316270b 100644 --- a/cmd/podman/common/default.go +++ b/cmd/podman/common/default.go @@ -1,18 +1,5 @@ package common -import ( - "fmt" - "os" - - "github.com/containers/buildah/pkg/parse" - "github.com/containers/libpod/pkg/apparmor" - "github.com/containers/libpod/pkg/cgroups" - "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/specgen" - "github.com/containers/libpod/pkg/sysinfo" - "github.com/opencontainers/selinux/go-selinux" -) - var ( // DefaultHealthCheckInterval default value DefaultHealthCheckInterval = "30s" @@ -25,111 +12,3 @@ var ( // DefaultImageVolume default value DefaultImageVolume = "bind" ) - -// TODO these options are directly embedded into many of the CLI cobra values, as such -// this approach will not work in a remote client. so we will need to likely do something like a -// supported and unsupported approach here and backload these options into the specgen -// once we are "on" the host system. -func getDefaultSecurityOptions() []string { - securityOpts := []string{} - if containerConfig.Containers.SeccompProfile != "" && containerConfig.Containers.SeccompProfile != parse.SeccompDefaultPath { - securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", containerConfig.Containers.SeccompProfile)) - } - if apparmor.IsEnabled() && containerConfig.Containers.ApparmorProfile != "" { - securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", containerConfig.Containers.ApparmorProfile)) - } - if selinux.GetEnabled() && !containerConfig.Containers.EnableLabeling { - securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0])) - } - return securityOpts -} - -// getDefaultSysctls -func getDefaultSysctls() []string { - return containerConfig.Containers.DefaultSysctls -} - -func getDefaultVolumes() []string { - return containerConfig.Containers.Volumes -} - -func getDefaultDevices() []string { - return containerConfig.Containers.Devices -} - -func getDefaultDNSServers() []string { //nolint - return containerConfig.Containers.DNSServers -} - -func getDefaultDNSSearches() []string { //nolint - return containerConfig.Containers.DNSSearches -} - -func getDefaultDNSOptions() []string { //nolint - return containerConfig.Containers.DNSOptions -} - -func getDefaultEnv() []string { - return containerConfig.Containers.Env -} - -func getDefaultInitPath() string { - return containerConfig.Containers.InitPath -} - -func getDefaultIPCNS() string { - return containerConfig.Containers.IPCNS -} - -func getDefaultPidNS() string { - return containerConfig.Containers.PidNS -} - -func getDefaultNetNS() string { //nolint - if containerConfig.Containers.NetNS == string(specgen.Private) && rootless.IsRootless() { - return string(specgen.Slirp) - } - return containerConfig.Containers.NetNS -} - -func getDefaultCgroupNS() string { - return containerConfig.Containers.CgroupNS -} - -func getDefaultUTSNS() string { - return containerConfig.Containers.UTSNS -} - -func getDefaultShmSize() string { - return containerConfig.Containers.ShmSize -} - -func getDefaultUlimits() []string { - return containerConfig.Containers.DefaultUlimits -} - -func getDefaultUserNS() string { - userns := os.Getenv("PODMAN_USERNS") - if userns != "" { - return userns - } - return containerConfig.Containers.UserNS -} - -func getDefaultPidsLimit() int64 { - if rootless.IsRootless() { - cgroup2, _ := cgroups.IsCgroup2UnifiedMode() - if cgroup2 { - return containerConfig.Containers.PidsLimit - } - } - return sysinfo.GetDefaultPidsLimit() -} - -func getDefaultPidsDescription() string { - return "Tune container pids limit (set 0 for unlimited)" -} - -func GetDefaultDetachKeys() string { - return containerConfig.Engine.DetachKeys -} diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 104038d05..1a47733e7 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -17,15 +17,15 @@ func GetNetFlags() *pflag.FlagSet { "Add a custom host-to-IP mapping (host:ip) (default [])", ) netFlags.StringSlice( - "dns", getDefaultDNSServers(), + "dns", containerConfig.DNSServers(), "Set custom DNS servers", ) netFlags.StringSlice( - "dns-opt", getDefaultDNSOptions(), + "dns-opt", containerConfig.DNSOptions(), "Set custom DNS options", ) netFlags.StringSlice( - "dns-search", getDefaultDNSSearches(), + "dns-search", containerConfig.DNSSearches(), "Set custom DNS search domains", ) netFlags.String( @@ -37,7 +37,7 @@ func GetNetFlags() *pflag.FlagSet { "Container MAC address (e.g. 92:d0:c6:0a:29:33)", ) netFlags.String( - "network", getDefaultNetNS(), + "network", containerConfig.NetNS(), "Connect a container to a network", ) netFlags.StringSliceP( diff --git a/cmd/podman/containers/attach.go b/cmd/podman/containers/attach.go index 700be1f84..10ad80503 100644 --- a/cmd/podman/containers/attach.go +++ b/cmd/podman/containers/attach.go @@ -3,7 +3,6 @@ package containers import ( "os" - "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" @@ -39,7 +38,7 @@ func init() { Command: attachCommand, }) flags := attachCommand.Flags() - flags.StringVar(&attachOpts.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") + flags.StringVar(&attachOpts.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVar(&attachOpts.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false") flags.BoolVar(&attachOpts.SigProxy, "sig-proxy", true, "Proxy received signals to the process") flags.BoolVarP(&attachOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") diff --git a/cmd/podman/containers/container.go b/cmd/podman/containers/container.go index 8564b23f4..4b1733eb0 100644 --- a/cmd/podman/containers/container.go +++ b/cmd/podman/containers/container.go @@ -1,12 +1,9 @@ package containers import ( - "os" - - "github.com/containers/common/pkg/config" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/pkg/domain/entities" - "github.com/sirupsen/logrus" + "github.com/containers/libpod/pkg/util" "github.com/spf13/cobra" ) @@ -20,7 +17,7 @@ var ( RunE: registry.SubCommandExists, } - defaultContainerConfig = getDefaultContainerConfig() + containerConfig = util.DefaultContainerConfig() ) func init() { @@ -29,12 +26,3 @@ func init() { Command: containerCmd, }) } - -func getDefaultContainerConfig() *config.Config { - defaultContainerConfig, err := config.Default() - if err != nil { - logrus.Error(err) - os.Exit(1) - } - return defaultContainerConfig -} diff --git a/cmd/podman/containers/exec.go b/cmd/podman/containers/exec.go index 68ecb2196..aaee4ee1c 100644 --- a/cmd/podman/containers/exec.go +++ b/cmd/podman/containers/exec.go @@ -4,7 +4,6 @@ import ( "bufio" "os" - "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/pkg/domain/entities" envLib "github.com/containers/libpod/pkg/env" @@ -38,7 +37,7 @@ func init() { }) flags := execCommand.Flags() flags.SetInterspersed(false) - flags.StringVar(&execOpts.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") + flags.StringVar(&execOpts.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") flags.StringArrayVarP(&envInput, "env", "e", []string{}, "Set environment variables") flags.StringSliceVar(&envFile, "env-file", []string{}, "Read in a file of environment variables") flags.BoolVarP(&execOpts.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 68b6de4ca..74df449a2 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -16,7 +16,7 @@ import ( var ( restartDescription = fmt.Sprintf(`Restarts one or more running containers. The container ID or name can be used. - A timeout before forcibly stopping can be set, but defaults to %d seconds.`, defaultContainerConfig.Engine.StopTimeout) + A timeout before forcibly stopping can be set, but defaults to %d seconds.`, containerConfig.Engine.StopTimeout) restartCommand = &cobra.Command{ Use: "restart [flags] CONTAINER [CONTAINER...]", @@ -46,7 +46,7 @@ func init() { flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers") flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used") - flags.UintVarP(&restartTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&restartTimeout, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") if registry.IsRemote() { _ = flags.MarkHidden("latest") } diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go index 33e5a3094..f2ee0f177 100644 --- a/cmd/podman/containers/start.go +++ b/cmd/podman/containers/start.go @@ -4,7 +4,6 @@ import ( "fmt" "os" - "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/utils" "github.com/containers/libpod/libpod/define" @@ -38,7 +37,7 @@ func init() { }) flags := startCommand.Flags() flags.BoolVarP(&startOptions.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") - flags.StringVar(&startOptions.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") + flags.StringVar(&startOptions.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVarP(&startOptions.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") flags.BoolVarP(&startOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&startOptions.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)") diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index c1560be08..1856524c9 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -14,7 +14,7 @@ import ( var ( stopDescription = fmt.Sprintf(`Stops one or more running containers. The container name or ID can be used. - A timeout to forcibly stop the container can also be set but defaults to %d seconds otherwise.`, defaultContainerConfig.Engine.StopTimeout) + A timeout to forcibly stop the container can also be set but defaults to %d seconds otherwise.`, containerConfig.Engine.StopTimeout) stopCommand = &cobra.Command{ Use: "stop [flags] CONTAINER [CONTAINER...]", Short: "Stop one or more containers", @@ -44,7 +44,7 @@ func init() { flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") 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") + flags.UintVarP(&stopTimeout, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") if registry.IsRemote() { _ = flags.MarkHidden("latest") @@ -58,7 +58,7 @@ func stop(cmd *cobra.Command, args []string) error { var ( errs utils.OutputErrors ) - stopOptions.Timeout = defaultContainerConfig.Engine.StopTimeout + stopOptions.Timeout = containerConfig.Engine.StopTimeout if cmd.Flag("time").Changed { stopOptions.Timeout = stopTimeout } diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 63dab4707..647cf24b2 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -9,7 +9,6 @@ import ( "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/cmd/podman/registry" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/specgen" @@ -50,8 +49,8 @@ func init() { flags.AddFlagSet(common.GetNetFlags()) flags.StringVar(&createOptions.CGroupParent, "cgroup-parent", "", "Set parent cgroup for the pod") flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with") - flags.StringVar(&createOptions.InfraImage, "infra-image", define.DefaultInfraImage, "The image of the infra container to associate with the pod") - flags.StringVar(&createOptions.InfraCommand, "infra-command", define.DefaultInfraCommand, "The command to run on the infra container when the pod is started") + flags.StringVar(&createOptions.InfraImage, "infra-image", containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod") + flags.StringVar(&createOptions.InfraCommand, "infra-command", containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started") flags.StringSliceVar(&labelFile, "label-file", []string{}, "Read in a line delimited file of labels") flags.StringSliceVarP(&labels, "label", "l", []string{}, "Set metadata on pod (default [])") flags.StringVarP(&createOptions.Name, "name", "n", "", "Assign a name to the pod") diff --git a/cmd/podman/pods/pod.go b/cmd/podman/pods/pod.go index 1cac50e40..fa917b2ae 100644 --- a/cmd/podman/pods/pod.go +++ b/cmd/podman/pods/pod.go @@ -3,6 +3,7 @@ package pods import ( "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/util" "github.com/spf13/cobra" ) @@ -15,6 +16,7 @@ var ( TraverseChildren: true, RunE: registry.SubCommandExists, } + containerConfig = util.DefaultContainerConfig() ) func init() { diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go index 683d9c00a..daf05d640 100644 --- a/cmd/podman/pods/stop.go +++ b/cmd/podman/pods/stop.go @@ -47,11 +47,10 @@ func init() { flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running pods") flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing") flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Stop the latest pod podman is aware of") - flags.UintVarP(&timeout, "time", "t", 0, "Seconds to wait for pod stop before killing the container") + flags.UintVarP(&timeout, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container") if registry.IsRemote() { _ = flags.MarkHidden("latest") _ = flags.MarkHidden("ignore") - } flags.SetNormalizeFunc(utils.AliasFlags) } diff --git a/cmd/podman/volumes/create.go b/cmd/podman/volumes/create.go index df0731791..1bec8d0e7 100644 --- a/cmd/podman/volumes/create.go +++ b/cmd/podman/volumes/create.go @@ -40,7 +40,7 @@ func init() { Parent: volumeCmd, }) flags := createCommand.Flags() - flags.StringVar(&createOpts.Driver, "driver", "", "Specify volume driver name (default local)") + flags.StringVar(&createOpts.Driver, "driver", "local", "Specify volume driver name") flags.StringSliceVarP(&opts.Label, "label", "l", []string{}, "Set metadata for a volume (default [])") flags.StringArrayVarP(&opts.Opts, "opt", "o", []string{}, "Set driver specific options (default [])") } diff --git a/contrib/podmanimage/stable/Dockerfile b/contrib/podmanimage/stable/Dockerfile index c0c07d9d2..7aeb5bbdc 100644 --- a/contrib/podmanimage/stable/Dockerfile +++ b/contrib/podmanimage/stable/Dockerfile @@ -11,16 +11,12 @@ FROM fedora:latest # Don't include container-selinux and remove # directories used by yum that are just taking # up space. -RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install podman fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.* +RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install podman fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.* # Adjust storage.conf to enable Fuse storage. RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock -# Adjust libpod.conf to write logging to a file -RUN sed -i 's/# events_logger = "journald"/events_logger = "file"/g' /usr/share/containers/libpod.conf +ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ -# Set up environment variables to note that this is -# not starting with usernamespace and default to -# isolate the filesystem with chroot. -ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/stable/containers.conf b/contrib/podmanimage/stable/containers.conf new file mode 100644 index 000000000..e6b806da3 --- /dev/null +++ b/contrib/podmanimage/stable/containers.conf @@ -0,0 +1,11 @@ +[containers] +netns="host" +userns="host" +ipcns="host" +utsns="host" +cgroupns="host" +cgroups="disabled" +[engine] +cgroup_manager = "cgroupfs" +events_logger="file" +runtime="crun" diff --git a/contrib/podmanimage/stable/manual/Containerfile b/contrib/podmanimage/stable/manual/Containerfile index d76d6d9b4..afc4f5ffd 100644 --- a/contrib/podmanimage/stable/manual/Containerfile +++ b/contrib/podmanimage/stable/manual/Containerfile @@ -30,10 +30,6 @@ RUN yum -y install /tmp/podman-1.7.0-3.fc30.x86_64.rpm fuse-overlayfs --exclude RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock -# Adjust libpod.conf to write logging to a file -RUN sed -i 's/events_logger = "journald"/events_logger = "file"/g' /usr/share/containers/libpod.conf; mkdir -p /run/systemd/journal +ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ -# Set up environment variables to note that this is -# not starting with usernamespace and default to -# isolate the filesystem with chroot. -ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/testing/Dockerfile b/contrib/podmanimage/testing/Dockerfile index a8e7653f6..3a7a0b7f8 100644 --- a/contrib/podmanimage/testing/Dockerfile +++ b/contrib/podmanimage/testing/Dockerfile @@ -13,16 +13,12 @@ FROM fedora:latest # Don't include container-selinux and remove # directories used by yum that are just taking # up space. -RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install podman fuse-overlayfs --exclude container-selinux --enablerepo updates-testing; rm -rf /var/cache /var/log/dnf* /var/log/yum.* +RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install podman fuse-overlayfs --exclude container-selinux --enablerepo updates-testing; rm -rf /var/cache /var/log/dnf* /var/log/yum.* # Adjust storage.conf to enable Fuse storage. RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock -# Adjust libpod.conf to write logging to a file -RUN sed -i 's/# events_logger = "journald"/events_logger = "file"/g' /usr/share/containers/libpod.conf +ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ -# Set up environment variables to note that this is -# not starting with usernamespace and default to -# isolate the filesystem with chroot. -ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile index 847097920..3b2f49094 100644 --- a/contrib/podmanimage/upstream/Dockerfile +++ b/contrib/podmanimage/upstream/Dockerfile @@ -17,7 +17,7 @@ ENV GOPATH=/root/podman # to the container. # Finally remove the podman directory and a few other packages # that are needed for building but not running Podman -RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install --exclude container-selinux \ +RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install --exclude container-selinux \ --enablerepo=updates-testing \ btrfs-progs-devel \ containernetworking-cni \ @@ -37,7 +37,7 @@ RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install libselinux-devel \ make \ pkgconfig \ - runc \ + crun \ fuse-overlayfs \ fuse3 \ containers-common; \ @@ -59,9 +59,6 @@ RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install mkdir -p /etc/cni/net.d; \ curl -qsSL https://raw.githubusercontent.com/containers/libpod/master/cni/87-podman-bridge.conflist | tee /etc/cni/net.d/99-loopback.conf; \ mkdir -p /usr/share/containers; \ - cp $GOPATH/src/github.com/containers/libpod/libpod.conf /usr/share/containers; \ - # Adjust libpod.conf to write logging to a file - sed -i 's/# events_logger = "journald"/events_logger = "file"/g' /usr/share/containers/libpod.conf; \ rm -rf /root/podman/*; \ yum -y remove git golang go-md2man make; \ yum clean all; @@ -70,7 +67,6 @@ RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock -# Set up environment variables to note that this is -# not starting with usernamespace and default to -# isolate the filesystem with chroot. -ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot +ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ + +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index c40ad45b9..38dfa7ab7 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -20,11 +20,11 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/buildah/pkg/secrets" + "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/pkg/annotations" - "github.com/containers/libpod/pkg/apparmor" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/criu" "github.com/containers/libpod/pkg/lookup" diff --git a/libpod/define/config.go b/libpod/define/config.go index 17d764c65..692eafb04 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -6,10 +6,6 @@ import ( ) var ( - // DefaultInfraImage to use for infra container - DefaultInfraImage = "k8s.gcr.io/pause:3.2" - // DefaultInfraCommand to be run in an infra container - DefaultInfraCommand = "/pause" // DefaultSHMLockPath is the default path for SHM locks DefaultSHMLockPath = "/libpod_lock" // DefaultRootlessSHMLockPath is the default path for rootless SHM locks diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 12af40876..3d4bd4fb5 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -46,12 +46,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()")) return } - defaultContainerConfig, err := runtime.GetConfig() + containerConfig, err := runtime.GetConfig() if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "GetConfig()")) return } - cc, err := makeCreateConfig(defaultContainerConfig, input, newImage) + cc, err := makeCreateConfig(containerConfig, input, newImage) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "makeCreatConfig()")) return @@ -60,7 +60,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.CreateContainer(r.Context(), w, runtime, &cc) } -func makeCreateConfig(defaultContainerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) { +func makeCreateConfig(containerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) { var ( err error init bool @@ -81,7 +81,7 @@ func makeCreateConfig(defaultContainerConfig *config.Config, input handlers.Crea workDir = input.WorkingDir } - stopTimeout := defaultContainerConfig.Engine.StopTimeout + stopTimeout := containerConfig.Engine.StopTimeout if input.StopTimeout != nil { stopTimeout = uint(*input.StopTimeout) } diff --git a/pkg/api/handlers/compat/info.go b/pkg/api/handlers/compat/info.go index 179b4a3e0..e9756a03f 100644 --- a/pkg/api/handlers/compat/info.go +++ b/pkg/api/handlers/compat/info.go @@ -10,12 +10,12 @@ import ( "time" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/sysinfo" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/sysinfo" docker "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/google/uuid" diff --git a/pkg/apparmor/apparmor.go b/pkg/apparmor/apparmor.go deleted file mode 100644 index 8e17361cb..000000000 --- a/pkg/apparmor/apparmor.go +++ /dev/null @@ -1,19 +0,0 @@ -package apparmor - -import ( - "errors" - - "github.com/containers/common/pkg/config" - libpodVersion "github.com/containers/libpod/version" -) - -var ( - // DefaultLipodProfilePrefix is used for version-independent presence checks. - DefaultLipodProfilePrefix = config.DefaultApparmorProfile - // DefaultLibpodProfile is the name of default libpod AppArmor profile. - DefaultLibpodProfile = DefaultLipodProfilePrefix + "-" + libpodVersion.Version - // ErrApparmorUnsupported indicates that AppArmor support is not supported. - ErrApparmorUnsupported = errors.New("AppArmor is not supported") - // ErrApparmorRootless indicates that AppArmor support is not supported in rootless mode. - ErrApparmorRootless = errors.New("AppArmor is not supported in rootless mode") -) diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go deleted file mode 100644 index 33710ff56..000000000 --- a/pkg/apparmor/apparmor_linux.go +++ /dev/null @@ -1,289 +0,0 @@ -// +build linux,apparmor - -package apparmor - -import ( - "bufio" - "bytes" - "fmt" - "io" - "os" - "os/exec" - "path" - "strconv" - "strings" - "text/template" - - "github.com/containers/libpod/pkg/rootless" - runcaa "github.com/opencontainers/runc/libcontainer/apparmor" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// profileDirectory is the file store for apparmor profiles and macros. -var profileDirectory = "/etc/apparmor.d" - -// IsEnabled returns true if AppArmor is enabled on the host. -func IsEnabled() bool { - if rootless.IsRootless() { - return false - } - return runcaa.IsEnabled() -} - -// profileData holds information about the given profile for generation. -type profileData struct { - // Name is profile name. - Name string - // Imports defines the apparmor functions to import, before defining the profile. - Imports []string - // InnerImports defines the apparmor functions to import in the profile. - InnerImports []string - // Version is the {major, minor, patch} version of apparmor_parser as a single number. - Version int -} - -// generateDefault creates an apparmor profile from ProfileData. -func (p *profileData) generateDefault(out io.Writer) error { - compiled, err := template.New("apparmor_profile").Parse(libpodProfileTemplate) - if err != nil { - return err - } - - if macroExists("tunables/global") { - p.Imports = append(p.Imports, "#include <tunables/global>") - } else { - p.Imports = append(p.Imports, "@{PROC}=/proc/") - } - - if macroExists("abstractions/base") { - p.InnerImports = append(p.InnerImports, "#include <abstractions/base>") - } - - ver, err := getAAParserVersion() - if err != nil { - return err - } - p.Version = ver - - return compiled.Execute(out, p) -} - -// macrosExists checks if the passed macro exists. -func macroExists(m string) bool { - _, err := os.Stat(path.Join(profileDirectory, m)) - return err == nil -} - -// InstallDefault generates a default profile and loads it into the kernel -// using 'apparmor_parser'. -func InstallDefault(name string) error { - if rootless.IsRootless() { - return ErrApparmorRootless - } - - p := profileData{ - Name: name, - } - - cmd := exec.Command("apparmor_parser", "-Kr") - pipe, err := cmd.StdinPipe() - if err != nil { - return err - } - if err := cmd.Start(); err != nil { - if pipeErr := pipe.Close(); pipeErr != nil { - logrus.Errorf("unable to close apparmor pipe: %q", pipeErr) - } - return err - } - if err := p.generateDefault(pipe); err != nil { - if pipeErr := pipe.Close(); pipeErr != nil { - logrus.Errorf("unable to close apparmor pipe: %q", pipeErr) - } - if cmdErr := cmd.Wait(); cmdErr != nil { - logrus.Errorf("unable to wait for apparmor command: %q", cmdErr) - } - return err - } - - if pipeErr := pipe.Close(); pipeErr != nil { - logrus.Errorf("unable to close apparmor pipe: %q", pipeErr) - } - return cmd.Wait() -} - -// DefaultContent returns the default profile content as byte slice. The -// profile is named as the provided `name`. The function errors if the profile -// generation fails. -func DefaultContent(name string) ([]byte, error) { - p := profileData{Name: name} - var bytes bytes.Buffer - if err := p.generateDefault(&bytes); err != nil { - return nil, err - } - return bytes.Bytes(), nil -} - -// IsLoaded checks if a profile with the given name has been loaded into the -// kernel. -func IsLoaded(name string) (bool, error) { - if name != "" && rootless.IsRootless() { - return false, errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) - } - - file, err := os.Open("/sys/kernel/security/apparmor/profiles") - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - defer file.Close() - - r := bufio.NewReader(file) - for { - p, err := r.ReadString('\n') - if err == io.EOF { - break - } - if err != nil { - return false, err - } - if strings.HasPrefix(p, name+" ") { - return true, nil - } - } - - return false, nil -} - -// execAAParser runs `apparmor_parser` with the passed arguments. -func execAAParser(dir string, args ...string) (string, error) { - c := exec.Command("apparmor_parser", args...) - c.Dir = dir - - output, err := c.CombinedOutput() - if err != nil { - return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err) - } - - return string(output), nil -} - -// getAAParserVersion returns the major and minor version of apparmor_parser. -func getAAParserVersion() (int, error) { - output, err := execAAParser("", "--version") - if err != nil { - return -1, err - } - return parseAAParserVersion(output) -} - -// parseAAParserVersion parses the given `apparmor_parser --version` output and -// returns the major and minor version number as an integer. -func parseAAParserVersion(output string) (int, error) { - // output is in the form of the following: - // AppArmor parser version 2.9.1 - // Copyright (C) 1999-2008 Novell Inc. - // Copyright 2009-2012 Canonical Ltd. - lines := strings.SplitN(output, "\n", 2) - words := strings.Split(lines[0], " ") - version := words[len(words)-1] - - // split by major minor version - v := strings.Split(version, ".") - if len(v) == 0 || len(v) > 3 { - return -1, fmt.Errorf("parsing version failed for output: `%s`", output) - } - - // Default the versions to 0. - var majorVersion, minorVersion, patchLevel int - - majorVersion, err := strconv.Atoi(v[0]) - if err != nil { - return -1, err - } - - if len(v) > 1 { - minorVersion, err = strconv.Atoi(v[1]) - if err != nil { - return -1, err - } - } - if len(v) > 2 { - patchLevel, err = strconv.Atoi(v[2]) - if err != nil { - return -1, err - } - } - - // major*10^5 + minor*10^3 + patch*10^0 - numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel - return numericVersion, nil - -} - -// CheckProfileAndLoadDefault checks if the specified profile is loaded and -// loads the DefaultLibpodProfile if the specified on is prefixed by -// DefaultLipodProfilePrefix. This allows to always load and apply the latest -// default AppArmor profile. Note that AppArmor requires root. If it's a -// default profile, return DefaultLipodProfilePrefix, otherwise the specified -// one. -func CheckProfileAndLoadDefault(name string) (string, error) { - if name == "unconfined" { - return name, nil - } - - // AppArmor is not supported in rootless mode as it requires root - // privileges. Return an error in case a specific profile is specified. - if rootless.IsRootless() { - if name != "" { - return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) - } else { - logrus.Debug("skipping loading default AppArmor profile (rootless mode)") - return "", nil - } - } - - // Check if AppArmor is disabled and error out if a profile is to be set. - if !runcaa.IsEnabled() { - if name == "" { - return "", nil - } else { - return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name) - } - } - - // If the specified name is not empty or is not a default libpod one, - // ignore it and return the name. - if name != "" && !strings.HasPrefix(name, DefaultLipodProfilePrefix) { - isLoaded, err := IsLoaded(name) - if err != nil { - return "", err - } - if !isLoaded { - return "", fmt.Errorf("AppArmor profile %q specified but not loaded", name) - } - return name, nil - } - - name = DefaultLibpodProfile - // To avoid expensive redundant loads on each invocation, check - // if it's loaded before installing it. - isLoaded, err := IsLoaded(name) - if err != nil { - return "", err - } - if !isLoaded { - err = InstallDefault(name) - if err != nil { - return "", err - } - logrus.Infof("successfully loaded AppAmor profile %q", name) - } else { - logrus.Infof("AppAmor profile %q is already loaded", name) - } - - return name, nil -} diff --git a/pkg/apparmor/apparmor_linux_template.go b/pkg/apparmor/apparmor_linux_template.go deleted file mode 100644 index 8d9a92ef7..000000000 --- a/pkg/apparmor/apparmor_linux_template.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build linux,apparmor - -package apparmor - -const libpodProfileTemplate = ` -{{range $value := .Imports}} -{{$value}} -{{end}} - -profile {{.Name}} flags=(attach_disconnected,mediate_deleted) { -{{range $value := .InnerImports}} - {{$value}} -{{end}} - - network, - capability, - file, - umount, - -{{if ge .Version 208096}} - # Allow signals from privileged profiles and from within the same profile - signal (receive) peer=unconfined, - signal (send,receive) peer={{.Name}}, -{{end}} - - deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir) - # deny write to files not in /proc/<number>/** or /proc/sys/** - deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w, - deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel) - deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/ - deny @{PROC}/sysrq-trigger rwklx, - deny @{PROC}/kcore rwklx, - - deny mount, - - deny /sys/[^f]*/** wklx, - deny /sys/f[^s]*/** wklx, - deny /sys/fs/[^c]*/** wklx, - deny /sys/fs/c[^g]*/** wklx, - deny /sys/fs/cg[^r]*/** wklx, - deny /sys/firmware/** rwklx, - deny /sys/kernel/security/** rwklx, - -{{if ge .Version 208095}} - # suppress ptrace denials when using using 'ps' inside a container - ptrace (trace,read) peer={{.Name}}, -{{end}} -} -` diff --git a/pkg/apparmor/apparmor_linux_test.go b/pkg/apparmor/apparmor_linux_test.go deleted file mode 100644 index 3ff6e18bc..000000000 --- a/pkg/apparmor/apparmor_linux_test.go +++ /dev/null @@ -1,140 +0,0 @@ -// +build linux,apparmor - -package apparmor - -import ( - "os" - "testing" -) - -type versionExpected struct { - output string - version int -} - -func TestParseAAParserVersion(t *testing.T) { - if !IsEnabled() { - t.Skip("AppArmor disabled: skipping tests") - } - versions := []versionExpected{ - { - output: `AppArmor parser version 2.10 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 210000, - }, - { - output: `AppArmor parser version 2.8 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 208000, - }, - { - output: `AppArmor parser version 2.20 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 220000, - }, - { - output: `AppArmor parser version 2.05 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 205000, - }, - { - output: `AppArmor parser version 2.9.95 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 209095, - }, - { - output: `AppArmor parser version 3.14.159 -Copyright (C) 1999-2008 Novell Inc. -Copyright 2009-2012 Canonical Ltd. - -`, - version: 314159, - }, - } - - for _, v := range versions { - version, err := parseAAParserVersion(v.output) - if err != nil { - t.Fatalf("expected error to be nil for %#v, got: %v", v, err) - } - if version != v.version { - t.Fatalf("expected version to be %d, was %d, for: %#v\n", v.version, version, v) - } - } -} - -const ( - aapath = "/sys/kernel/security/apparmor/" - profile = "libpod-default-testing" -) - -func TestInstallDefault(t *testing.T) { - if _, err := os.Stat(aapath); err != nil { - t.Skip("AppArmor isn't available in this environment") - } - - // removes `profile` - removeProfile := func() error { - path := aapath + ".remove" - - f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, os.ModeAppend) - if err != nil { - return err - } - defer f.Close() - - _, err = f.WriteString(profile) - return err - } - - // makes sure `profile` is loaded according to `state` - checkLoaded := func(state bool) { - loaded, err := IsLoaded(profile) - if err != nil { - t.Fatalf("Error searching AppArmor profile '%s': %v", profile, err) - } - if state != loaded { - if state { - t.Fatalf("AppArmor profile '%s' isn't loaded but should", profile) - } else { - t.Fatalf("AppArmor profile '%s' is loaded but shouldn't", profile) - } - } - } - - // test installing the profile - if err := InstallDefault(profile); err != nil { - t.Fatalf("Couldn't install AppArmor profile '%s': %v", profile, err) - } - checkLoaded(true) - - // remove the profile and check again - if err := removeProfile(); err != nil { - t.Fatalf("Couldn't remove AppArmor profile '%s': %v", profile, err) - } - checkLoaded(false) -} - -func TestDefaultContent(t *testing.T) { - if _, err := os.Stat(aapath); err != nil { - t.Skip("AppArmor isn't available in this environment") - } - if _, err := DefaultContent(profile); err != nil { - t.Fatalf("Couldn't retrieve default AppArmor profile content '%s': %v", profile, err) - } -} diff --git a/pkg/apparmor/apparmor_unsupported.go b/pkg/apparmor/apparmor_unsupported.go deleted file mode 100644 index 13469f1b6..000000000 --- a/pkg/apparmor/apparmor_unsupported.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build !linux !apparmor - -package apparmor - -// IsEnabled dummy. -func IsEnabled() bool { - return false -} - -// InstallDefault dummy. -func InstallDefault(name string) error { - return ErrApparmorUnsupported -} - -// IsLoaded dummy. -func IsLoaded(name string) (bool, error) { - return false, ErrApparmorUnsupported -} - -// CheckProfileAndLoadDefault dummy. -func CheckProfileAndLoadDefault(name string) (string, error) { - if name == "" { - return "", nil - } - return "", ErrApparmorUnsupported -} - -// DefaultContent dummy. -func DefaultContent(name string) ([]byte, error) { - return nil, nil -} diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 5de07fc28..7ee2df890 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -5,11 +5,11 @@ import ( "github.com/containers/common/pkg/capabilities" cconfig "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/sysinfo" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/env" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/sysinfo" "github.com/containers/libpod/pkg/util" "github.com/docker/go-units" "github.com/opencontainers/runc/libcontainer/user" diff --git a/pkg/spec/spec_test.go b/pkg/spec/spec_test.go index 0f63b2bbc..71434fe73 100644 --- a/pkg/spec/spec_test.go +++ b/pkg/spec/spec_test.go @@ -4,9 +4,9 @@ import ( "runtime" "testing" + "github.com/containers/common/pkg/sysinfo" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/sysinfo" "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" "github.com/docker/go-units" diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go index 9e9659fa9..f2f90e58d 100644 --- a/pkg/specgen/pod_validate.go +++ b/pkg/specgen/pod_validate.go @@ -1,14 +1,16 @@ package specgen import ( - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" ) var ( // ErrInvalidPodSpecConfig describes an error given when the podspecgenerator is invalid ErrInvalidPodSpecConfig error = errors.New("invalid pod spec") + // containerConfig has the default configurations defined in containers.conf + containerConfig = util.DefaultContainerConfig() ) func exclusivePodOptions(opt1, opt2 string) error { @@ -96,10 +98,10 @@ func (p *PodSpecGenerator) Validate() error { } } if len(p.InfraImage) < 1 { - p.InfraImage = define.DefaultInfraImage + p.InfraImage = containerConfig.Engine.InfraImage } if len(p.InfraCommand) < 1 { - p.InfraCommand = []string{define.DefaultInfraCommand} + p.InfraCommand = []string{containerConfig.Engine.InfraCommand} } return nil } diff --git a/pkg/sysinfo/README.md b/pkg/sysinfo/README.md deleted file mode 100644 index c1530cef0..000000000 --- a/pkg/sysinfo/README.md +++ /dev/null @@ -1 +0,0 @@ -SysInfo stores information about which features a kernel supports. diff --git a/pkg/sysinfo/numcpu.go b/pkg/sysinfo/numcpu.go deleted file mode 100644 index aeb1a3a80..000000000 --- a/pkg/sysinfo/numcpu.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !linux,!windows - -package sysinfo - -import ( - "runtime" -) - -// NumCPU returns the number of CPUs -func NumCPU() int { - return runtime.NumCPU() -} diff --git a/pkg/sysinfo/numcpu_linux.go b/pkg/sysinfo/numcpu_linux.go deleted file mode 100644 index f1d2d9db3..000000000 --- a/pkg/sysinfo/numcpu_linux.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build linux - -package sysinfo - -import ( - "runtime" - "unsafe" - - "golang.org/x/sys/unix" -) - -// numCPU queries the system for the count of threads available -// for use to this process. -// -// Issues two syscalls. -// Returns 0 on errors. Use |runtime.NumCPU| in that case. -func numCPU() int { - // Gets the affinity mask for a process: The very one invoking this function. - pid, _, _ := unix.RawSyscall(unix.SYS_GETPID, 0, 0, 0) - - var mask [1024 / 64]uintptr - _, _, err := unix.RawSyscall(unix.SYS_SCHED_GETAFFINITY, pid, uintptr(len(mask)*8), uintptr(unsafe.Pointer(&mask[0]))) - if err != 0 { - return 0 - } - - // For every available thread a bit is set in the mask. - ncpu := 0 - for _, e := range mask { - if e == 0 { - continue - } - ncpu += int(popcnt(uint64(e))) - } - return ncpu -} - -// NumCPU returns the number of CPUs which are currently online -func NumCPU() int { - if ncpu := numCPU(); ncpu > 0 { - return ncpu - } - return runtime.NumCPU() -} diff --git a/pkg/sysinfo/numcpu_windows.go b/pkg/sysinfo/numcpu_windows.go deleted file mode 100644 index 1d89dd550..000000000 --- a/pkg/sysinfo/numcpu_windows.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build windows - -package sysinfo - -import ( - "runtime" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - kernel32 = windows.NewLazySystemDLL("kernel32.dll") - getCurrentProcess = kernel32.NewProc("GetCurrentProcess") - getProcessAffinityMask = kernel32.NewProc("GetProcessAffinityMask") -) - -func numCPU() int { - // Gets the affinity mask for a process - var mask, sysmask uintptr - currentProcess, _, _ := getCurrentProcess.Call() - ret, _, _ := getProcessAffinityMask.Call(currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask))) - if ret == 0 { - return 0 - } - // For every available thread a bit is set in the mask. - ncpu := int(popcnt(uint64(mask))) - return ncpu -} - -// NumCPU returns the number of CPUs which are currently online -func NumCPU() int { - if ncpu := numCPU(); ncpu > 0 { - return ncpu - } - return runtime.NumCPU() -} diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go deleted file mode 100644 index 686f66ce5..000000000 --- a/pkg/sysinfo/sysinfo.go +++ /dev/null @@ -1,153 +0,0 @@ -package sysinfo - -import "github.com/docker/docker/pkg/parsers" - -// SysInfo stores information about which features a kernel supports. -// TODO Windows: Factor out platform specific capabilities. -type SysInfo struct { - // Whether the kernel supports AppArmor or not - AppArmor bool - // Whether the kernel supports Seccomp or not - Seccomp bool - - cgroupMemInfo - cgroupCPUInfo - cgroupBlkioInfo - cgroupCpusetInfo - cgroupPids - - // Whether IPv4 forwarding is supported or not, if this was disabled, networking will not work - IPv4ForwardingDisabled bool - - // Whether bridge-nf-call-iptables is supported or not - BridgeNFCallIPTablesDisabled bool - - // Whether bridge-nf-call-ip6tables is supported or not - BridgeNFCallIP6TablesDisabled bool - - // Whether the cgroup has the mountpoint of "devices" or not - CgroupDevicesEnabled bool -} - -type cgroupMemInfo struct { - // Whether memory limit is supported or not - MemoryLimit bool - - // Whether swap limit is supported or not - SwapLimit bool - - // Whether soft limit is supported or not - MemoryReservation bool - - // Whether OOM killer disable is supported or not - OomKillDisable bool - - // Whether memory swappiness is supported or not - MemorySwappiness bool - - // Whether kernel memory limit is supported or not - KernelMemory bool -} - -type cgroupCPUInfo struct { - // Whether CPU shares is supported or not - CPUShares bool - - // Whether CPU CFS(Completely Fair Scheduler) period is supported or not - CPUCfsPeriod bool - - // Whether CPU CFS(Completely Fair Scheduler) quota is supported or not - CPUCfsQuota bool - - // Whether CPU real-time period is supported or not - CPURealtimePeriod bool - - // Whether CPU real-time runtime is supported or not - CPURealtimeRuntime bool -} - -type cgroupBlkioInfo struct { - // Whether Block IO weight is supported or not - BlkioWeight bool - - // Whether Block IO weight_device is supported or not - BlkioWeightDevice bool - - // Whether Block IO read limit in bytes per second is supported or not - BlkioReadBpsDevice bool - - // Whether Block IO write limit in bytes per second is supported or not - BlkioWriteBpsDevice bool - - // Whether Block IO read limit in IO per second is supported or not - BlkioReadIOpsDevice bool - - // Whether Block IO write limit in IO per second is supported or not - BlkioWriteIOpsDevice bool -} - -type cgroupCpusetInfo struct { - // Whether Cpuset is supported or not - Cpuset bool - - // Available Cpuset's cpus - Cpus string - - // Available Cpuset's memory nodes - Mems string -} - -type cgroupPids struct { - // Whether Pids Limit is supported or not - PidsLimit bool -} - -// IsCpusetCpusAvailable returns `true` if the provided string set is contained -// in cgroup's cpuset.cpus set, `false` otherwise. -// If error is not nil a parsing error occurred. -func (c cgroupCpusetInfo) IsCpusetCpusAvailable(provided string) (bool, error) { - return isCpusetListAvailable(provided, c.Cpus) -} - -// IsCpusetMemsAvailable returns `true` if the provided string set is contained -// in cgroup's cpuset.mems set, `false` otherwise. -// If error is not nil a parsing error occurred. -func (c cgroupCpusetInfo) IsCpusetMemsAvailable(provided string) (bool, error) { - return isCpusetListAvailable(provided, c.Mems) -} - -func isCpusetListAvailable(provided, available string) (bool, error) { - parsedProvided, err := parsers.ParseUintList(provided) - if err != nil { - return false, err - } - parsedAvailable, err := parsers.ParseUintList(available) - if err != nil { - return false, err - } - for k := range parsedProvided { - if !parsedAvailable[k] { - return false, nil - } - } - return true, nil -} - -// Returns bit count of 1, used by NumCPU -func popcnt(x uint64) (n byte) { - x -= (x >> 1) & 0x5555555555555555 - x = (x>>2)&0x3333333333333333 + x&0x3333333333333333 - x += x >> 4 - x &= 0x0f0f0f0f0f0f0f0f - x *= 0x0101010101010101 - return byte(x >> 56) -} - -// GetDefaultPidsLimit returns the default pids limit to run containers with -func GetDefaultPidsLimit() int64 { - sysInfo := New(true) - if !sysInfo.PidsLimit { - return 0 - } - return 4096 -} diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go deleted file mode 100644 index 76bda23c6..000000000 --- a/pkg/sysinfo/sysinfo_linux.go +++ /dev/null @@ -1,261 +0,0 @@ -package sysinfo - -import ( - "fmt" - "io/ioutil" - "os" - "path" - "strings" - - cg "github.com/containers/libpod/pkg/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -func findCgroupMountpoints() (map[string]string, error) { - cgMounts, err := cgroups.GetCgroupMounts(false) - if err != nil { - return nil, fmt.Errorf("failed to parse cgroup information: %v", err) - } - mps := make(map[string]string) - for _, m := range cgMounts { - for _, ss := range m.Subsystems { - mps[ss] = m.Mountpoint - } - } - return mps, nil -} - -// New returns a new SysInfo, using the filesystem to detect which features -// the kernel supports. If `quiet` is `false` warnings are printed in logs -// whenever an error occurs or misconfigurations are present. -func New(quiet bool) *SysInfo { - sysInfo := &SysInfo{} - cgMounts, err := findCgroupMountpoints() - if err != nil { - logrus.Warnf("Failed to parse cgroup information: %v", err) - } else { - sysInfo.cgroupMemInfo = checkCgroupMem(cgMounts, quiet) - sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet) - sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) - sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) - sysInfo.cgroupPids = checkCgroupPids(quiet) - } - - _, ok := cgMounts["devices"] - sysInfo.CgroupDevicesEnabled = ok - - sysInfo.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward") - sysInfo.BridgeNFCallIPTablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables") - sysInfo.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables") - - // Check if AppArmor is supported. - if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { - sysInfo.AppArmor = true - } - - // Check if Seccomp is supported, via CONFIG_SECCOMP. - if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL { - // Make sure the kernel has CONFIG_SECCOMP_FILTER. - if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL { - sysInfo.Seccomp = true - } - } - - return sysInfo -} - -// checkCgroupMem reads the memory information from the memory cgroup mount point. -func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo { - mountPoint, ok := cgMounts["memory"] - if !ok { - if !quiet { - logrus.Warn("Your kernel does not support cgroup memory limit") - } - return cgroupMemInfo{} - } - - swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes") - if !quiet && !swapLimit { - logrus.Warn("Your kernel does not support swap memory limit") - } - memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes") - if !quiet && !memoryReservation { - logrus.Warn("Your kernel does not support memory reservation") - } - oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control") - if !quiet && !oomKillDisable { - logrus.Warn("Your kernel does not support oom control") - } - memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness") - if !quiet && !memorySwappiness { - logrus.Warn("Your kernel does not support memory swappiness") - } - kernelMemory := cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes") - if !quiet && !kernelMemory { - logrus.Warn("Your kernel does not support kernel memory limit") - } - - return cgroupMemInfo{ - MemoryLimit: true, - SwapLimit: swapLimit, - MemoryReservation: memoryReservation, - OomKillDisable: oomKillDisable, - MemorySwappiness: memorySwappiness, - KernelMemory: kernelMemory, - } -} - -// checkCgroupCPU reads the cpu information from the cpu cgroup mount point. -func checkCgroupCPU(cgMounts map[string]string, quiet bool) cgroupCPUInfo { - mountPoint, ok := cgMounts["cpu"] - if !ok { - if !quiet { - logrus.Warn("Unable to find cpu cgroup in mounts") - } - return cgroupCPUInfo{} - } - - cpuShares := cgroupEnabled(mountPoint, "cpu.shares") - if !quiet && !cpuShares { - logrus.Warn("Your kernel does not support cgroup cpu shares") - } - - cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us") - if !quiet && !cpuCfsPeriod { - logrus.Warn("Your kernel does not support cgroup cfs period") - } - - cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us") - if !quiet && !cpuCfsQuota { - logrus.Warn("Your kernel does not support cgroup cfs quotas") - } - - cpuRealtimePeriod := cgroupEnabled(mountPoint, "cpu.rt_period_us") - if !quiet && !cpuRealtimePeriod { - logrus.Warn("Your kernel does not support cgroup rt period") - } - - cpuRealtimeRuntime := cgroupEnabled(mountPoint, "cpu.rt_runtime_us") - if !quiet && !cpuRealtimeRuntime { - logrus.Warn("Your kernel does not support cgroup rt runtime") - } - - return cgroupCPUInfo{ - CPUShares: cpuShares, - CPUCfsPeriod: cpuCfsPeriod, - CPUCfsQuota: cpuCfsQuota, - CPURealtimePeriod: cpuRealtimePeriod, - CPURealtimeRuntime: cpuRealtimeRuntime, - } -} - -// checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point. -func checkCgroupBlkioInfo(cgMounts map[string]string, quiet bool) cgroupBlkioInfo { - mountPoint, ok := cgMounts["blkio"] - if !ok { - if !quiet { - logrus.Warn("Unable to find blkio cgroup in mounts") - } - return cgroupBlkioInfo{} - } - - weight := cgroupEnabled(mountPoint, "blkio.weight") - if !quiet && !weight { - logrus.Warn("Your kernel does not support cgroup blkio weight") - } - - weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device") - if !quiet && !weightDevice { - logrus.Warn("Your kernel does not support cgroup blkio weight_device") - } - - readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device") - if !quiet && !readBpsDevice { - logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device") - } - - writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device") - if !quiet && !writeBpsDevice { - logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device") - } - readIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device") - if !quiet && !readIOpsDevice { - logrus.Warn("Your kernel does not support cgroup blkio throttle.read_iops_device") - } - - writeIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device") - if !quiet && !writeIOpsDevice { - logrus.Warn("Your kernel does not support cgroup blkio throttle.write_iops_device") - } - return cgroupBlkioInfo{ - BlkioWeight: weight, - BlkioWeightDevice: weightDevice, - BlkioReadBpsDevice: readBpsDevice, - BlkioWriteBpsDevice: writeBpsDevice, - BlkioReadIOpsDevice: readIOpsDevice, - BlkioWriteIOpsDevice: writeIOpsDevice, - } -} - -// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point. -func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetInfo { - mountPoint, ok := cgMounts["cpuset"] - if !ok { - if !quiet { - logrus.Warn("Unable to find cpuset cgroup in mounts") - } - return cgroupCpusetInfo{} - } - - cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) - if err != nil { - return cgroupCpusetInfo{} - } - - mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) - if err != nil { - return cgroupCpusetInfo{} - } - - return cgroupCpusetInfo{ - Cpuset: true, - Cpus: strings.TrimSpace(string(cpus)), - Mems: strings.TrimSpace(string(mems)), - } -} - -// checkCgroupPids reads the pids information from the pids cgroup mount point. -func checkCgroupPids(quiet bool) cgroupPids { - cgroup2, err := cg.IsCgroup2UnifiedMode() - if err != nil { - logrus.Errorf("Failed to check cgroups version: %v", err) - } - if !cgroup2 { - _, err := cgroups.FindCgroupMountpoint("", "pids") - if err != nil { - if !quiet { - logrus.Warn(err) - } - return cgroupPids{} - } - } - - return cgroupPids{ - PidsLimit: true, - } -} - -func cgroupEnabled(mountPoint, name string) bool { - _, err := os.Stat(path.Join(mountPoint, name)) - return err == nil -} - -func readProcBool(path string) bool { - val, err := ioutil.ReadFile(path) - if err != nil { - return false - } - return strings.TrimSpace(string(val)) == "1" -} diff --git a/pkg/sysinfo/sysinfo_linux_test.go b/pkg/sysinfo/sysinfo_linux_test.go deleted file mode 100644 index 860784f2a..000000000 --- a/pkg/sysinfo/sysinfo_linux_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package sysinfo - -import ( - "io/ioutil" - "os" - "path" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "golang.org/x/sys/unix" -) - -func TestReadProcBool(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "test-sysinfo-proc") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) - - procFile := filepath.Join(tmpDir, "read-proc-bool") - err = ioutil.WriteFile(procFile, []byte("1"), 0644) - require.NoError(t, err) - - if !readProcBool(procFile) { - t.Fatal("expected proc bool to be true, got false") - } - - if err := ioutil.WriteFile(procFile, []byte("0"), 0644); err != nil { - t.Fatal(err) - } - if readProcBool(procFile) { - t.Fatal("expected proc bool to be false, got true") - } - - if readProcBool(path.Join(tmpDir, "no-exist")) { - t.Fatal("should be false for non-existent entry") - } - -} - -func TestCgroupEnabled(t *testing.T) { - cgroupDir, err := ioutil.TempDir("", "cgroup-test") - require.NoError(t, err) - defer os.RemoveAll(cgroupDir) - - if cgroupEnabled(cgroupDir, "test") { - t.Fatal("cgroupEnabled should be false") - } - - err = ioutil.WriteFile(path.Join(cgroupDir, "test"), []byte{}, 0644) - require.NoError(t, err) - - if !cgroupEnabled(cgroupDir, "test") { - t.Fatal("cgroupEnabled should be true") - } -} - -func TestNew(t *testing.T) { - sysInfo := New(false) - require.NotNil(t, sysInfo) - checkSysInfo(t, sysInfo) - - sysInfo = New(true) - require.NotNil(t, sysInfo) - checkSysInfo(t, sysInfo) -} - -func checkSysInfo(t *testing.T, sysInfo *SysInfo) { - // Check if Seccomp is supported, via CONFIG_SECCOMP.then sysInfo.Seccomp must be TRUE , else FALSE - if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL { - // Make sure the kernel has CONFIG_SECCOMP_FILTER. - if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL { - require.True(t, sysInfo.Seccomp) - } - } else { - require.False(t, sysInfo.Seccomp) - } -} - -func TestNewAppArmorEnabled(t *testing.T) { - // Check if AppArmor is supported. then it must be TRUE , else FALSE - if _, err := os.Stat("/sys/kernel/security/apparmor"); err != nil { - t.Skip("App Armor Must be Enabled") - } - - sysInfo := New(true) - require.True(t, sysInfo.AppArmor) -} - -func TestNewAppArmorDisabled(t *testing.T) { - // Check if AppArmor is supported. then it must be TRUE , else FALSE - if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { - t.Skip("App Armor Must be Disabled") - } - - sysInfo := New(true) - require.False(t, sysInfo.AppArmor) -} - -func TestNumCPU(t *testing.T) { - cpuNumbers := NumCPU() - if cpuNumbers <= 0 { - t.Fatal("CPU returned must be greater than zero") - } -} diff --git a/pkg/sysinfo/sysinfo_solaris.go b/pkg/sysinfo/sysinfo_solaris.go deleted file mode 100644 index 7463cdd8f..000000000 --- a/pkg/sysinfo/sysinfo_solaris.go +++ /dev/null @@ -1,122 +0,0 @@ -// +build solaris,cgo - -package sysinfo - -import ( - "bytes" - "os/exec" - "strconv" - "strings" -) - -/* -#cgo LDFLAGS: -llgrp -#cgo CFLAGS: -Wall -Werror -#include <unistd.h> -#include <stdlib.h> -#include <sys/lgrp_user.h> -int getLgrpCount() { - lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE; - uint_t nlgrps; - - if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) { - return -1; - } - nlgrps = lgrp_nlgrps(lgrpcookie); - return nlgrps; -} -*/ -import "C" - -// IsCPUSharesAvailable returns whether CPUShares setting is supported. -// We need FSS to be set as default scheduling class to support CPU Shares -func IsCPUSharesAvailable() bool { - cmd := exec.Command("/usr/sbin/dispadmin", "-d") - outBuf := new(bytes.Buffer) - errBuf := new(bytes.Buffer) - cmd.Stderr = errBuf - cmd.Stdout = outBuf - - if err := cmd.Run(); err != nil { - return false - } - return (strings.Contains(outBuf.String(), "FSS")) -} - -// New returns a new SysInfo, using the filesystem to detect which features -// the kernel supports. -//NOTE Solaris: If we change the below capabilities be sure -// to update verifyPlatformContainerSettings() in daemon_solaris.go -func New(quiet bool) *SysInfo { - sysInfo := &SysInfo{} - sysInfo.cgroupMemInfo = setCgroupMem(quiet) - sysInfo.cgroupCPUInfo = setCgroupCPU(quiet) - sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet) - sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet) - - sysInfo.IPv4ForwardingDisabled = false - - sysInfo.AppArmor = false - - return sysInfo -} - -// setCgroupMem reads the memory information for Solaris. -func setCgroupMem(quiet bool) cgroupMemInfo { - - return cgroupMemInfo{ - MemoryLimit: true, - SwapLimit: true, - MemoryReservation: false, - OomKillDisable: false, - MemorySwappiness: false, - KernelMemory: false, - } -} - -// setCgroupCPU reads the cpu information for Solaris. -func setCgroupCPU(quiet bool) cgroupCPUInfo { - - return cgroupCPUInfo{ - CPUShares: true, - CPUCfsPeriod: false, - CPUCfsQuota: true, - CPURealtimePeriod: false, - CPURealtimeRuntime: false, - } -} - -// blkio switches are not supported in Solaris. -func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo { - - return cgroupBlkioInfo{ - BlkioWeight: false, - BlkioWeightDevice: false, - } -} - -// setCgroupCPUsetInfo reads the cpuset information for Solaris. -func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo { - - return cgroupCpusetInfo{ - Cpuset: true, - Cpus: getCPUCount(), - Mems: getLgrpCount(), - } -} - -func getCPUCount() string { - ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) - if ncpus <= 0 { - return "" - } - return strconv.FormatInt(int64(ncpus), 16) -} - -func getLgrpCount() string { - nlgrps := C.getLgrpCount() - if nlgrps <= 0 { - return "" - } - return strconv.FormatInt(int64(nlgrps), 16) -} diff --git a/pkg/sysinfo/sysinfo_test.go b/pkg/sysinfo/sysinfo_test.go deleted file mode 100644 index 895828f26..000000000 --- a/pkg/sysinfo/sysinfo_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package sysinfo - -import "testing" - -func TestIsCpusetListAvailable(t *testing.T) { - cases := []struct { - provided string - available string - res bool - err bool - }{ - {"1", "0-4", true, false}, - {"01,3", "0-4", true, false}, - {"", "0-7", true, false}, - {"1--42", "0-7", false, true}, - {"1-42", "00-1,8,,9", false, true}, - {"1,41-42", "43,45", false, false}, - {"0-3", "", false, false}, - } - for _, c := range cases { - r, err := isCpusetListAvailable(c.provided, c.available) - if (c.err && err == nil) && r != c.res { - t.Fatalf("Expected pair: %v, %v for %s, %s. Got %v, %v instead", c.res, c.err, c.provided, c.available, c.err && err == nil, r) - } - } -} diff --git a/pkg/sysinfo/sysinfo_unix.go b/pkg/sysinfo/sysinfo_unix.go deleted file mode 100644 index 45f3ef1c6..000000000 --- a/pkg/sysinfo/sysinfo_unix.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !linux,!solaris,!windows - -package sysinfo - -// New returns an empty SysInfo for non linux nor solaris for now. -func New(quiet bool) *SysInfo { - sysInfo := &SysInfo{} - return sysInfo -} diff --git a/pkg/sysinfo/sysinfo_windows.go b/pkg/sysinfo/sysinfo_windows.go deleted file mode 100644 index 4e6255bc5..000000000 --- a/pkg/sysinfo/sysinfo_windows.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build windows - -package sysinfo - -// New returns an empty SysInfo for windows for now. -func New(quiet bool) *SysInfo { - sysInfo := &SysInfo{} - return sysInfo -} diff --git a/pkg/util/utils.go b/pkg/util/utils.go index babf7dfc9..55e775d7a 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -13,6 +13,7 @@ import ( "time" "github.com/BurntSushi/toml" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/types" "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/namespaces" @@ -27,6 +28,17 @@ import ( "golang.org/x/crypto/ssh/terminal" ) +var containerConfig *config.Config + +func init() { + var err error + containerConfig, err = config.Default() + if err != nil { + logrus.Error(err) + os.Exit(1) + } +} + // Helper function to determine the username/password passed // in the creds string. It could be either or both. func parseCreds(creds string) (string, string) { @@ -669,3 +681,7 @@ func swapSELinuxLabel(cLabel, processLabel string) (string, error) { dcon["type"] = scon["type"] return dcon.Get(), nil } + +func DefaultContainerConfig() *config.Config { + return containerConfig +} diff --git a/pkg/varlinkapi/create.go b/pkg/varlinkapi/create.go index 63d5072c6..571ce6115 100644 --- a/pkg/varlinkapi/create.go +++ b/pkg/varlinkapi/create.go @@ -13,6 +13,7 @@ import ( "syscall" "time" + "github.com/containers/common/pkg/sysinfo" "github.com/containers/image/v5/manifest" "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/libpod" @@ -28,7 +29,6 @@ import ( "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/seccomp" cc "github.com/containers/libpod/pkg/spec" - "github.com/containers/libpod/pkg/sysinfo" systemdGen "github.com/containers/libpod/pkg/systemd/generate" "github.com/containers/libpod/pkg/util" "github.com/docker/go-connections/nat" diff --git a/pkg/varlinkapi/intermediate_varlink.go b/pkg/varlinkapi/intermediate_varlink.go index 21c57d4f4..bd0c45b33 100644 --- a/pkg/varlinkapi/intermediate_varlink.go +++ b/pkg/varlinkapi/intermediate_varlink.go @@ -331,7 +331,7 @@ func intFromVarlink(v *int64, flagName string, defaultValue *int) CRInt { // structure. func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { // FIXME this will need to be fixed!!!!! With containers conf - //defaultContainerConfig := cliconfig.GetDefaultConfig() + //containerConfig := cliconfig.GetDefaultConfig() // TODO | WARN // We do not get a default network over varlink. Unlike the other default values for some cli // elements, it seems it gets set to the default anyway. |