summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md2
-rw-r--r--Makefile5
-rw-r--r--cmd/podman/build.go50
-rw-r--r--cmd/podman/cliconfig/config.go1
-rw-r--r--cmd/podman/cliconfig/defaults.go5
-rw-r--r--cmd/podman/common.go6
-rw-r--r--cmd/podman/libpodruntime/runtime.go17
-rw-r--r--cmd/podman/shared/container.go6
-rw-r--r--cmd/podman/shared/create.go14
-rw-r--r--cmd/podman/shared/funcs.go2
-rw-r--r--cmd/podman/shared/intermediate.go2
-rw-r--r--cmd/podman/shared/intermediate_varlink.go5
-rw-r--r--cmd/podman/system_migrate.go4
-rw-r--r--cmd/podman/utils.go10
-rw-r--r--cmd/podman/varlink/io.podman.varlink2
-rw-r--r--docs/podman-build.1.md67
-rw-r--r--docs/podman-create.1.md12
-rw-r--r--docs/podman-derivative-api64
-rw-r--r--docs/podman-run.1.md12
-rw-r--r--docs/podman-system-migrate.1.md8
-rw-r--r--docs/podman.1.md2
-rw-r--r--go.mod3
-rw-r--r--go.sum14
-rw-r--r--libpod/info.go13
-rw-r--r--libpod/options.go22
-rw-r--r--libpod/runtime.go4
-rw-r--r--libpod/runtime_migrate.go26
-rw-r--r--pkg/rootless/rootless_linux.go8
-rw-r--r--pkg/rootless/rootless_unsupported.go5
-rw-r--r--pkg/spec/createconfig.go3
-rw-r--r--pkg/spec/spec.go10
-rw-r--r--test/e2e/ps_test.go7
-rw-r--r--test/e2e/start_test.go4
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--troubleshooting.md2
-rw-r--r--vendor/github.com/containers/psgo/.travis.yml6
-rw-r--r--vendor/github.com/containers/psgo/Makefile9
-rw-r--r--vendor/github.com/containers/psgo/go.mod2
-rw-r--r--vendor/github.com/containers/psgo/go.sum8
-rw-r--r--vendor/github.com/containers/psgo/internal/cgroups/cgroups.go44
-rw-r--r--vendor/github.com/containers/psgo/internal/proc/pids.go78
-rw-r--r--vendor/modules.txt3
42 files changed, 445 insertions, 124 deletions
diff --git a/API.md b/API.md
index a9905c940..a2a093bec 100755
--- a/API.md
+++ b/API.md
@@ -1591,7 +1591,7 @@ subgidname [?string](#?string)
sysctl [?[]string](#?[]string)
-systemd [?bool](#?bool)
+systemd [?string](#?string)
tmpfs [?[]string](#?[]string)
diff --git a/Makefile b/Makefile
index 735981d34..1e722b6fd 100644
--- a/Makefile
+++ b/Makefile
@@ -438,7 +438,10 @@ install.systemd:
install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.socket ${DESTDIR}${SYSTEMDDIR}/io.podman.socket
install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.socket ${DESTDIR}${USERSYSTEMDDIR}/io.podman.socket
install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.service ${DESTDIR}${SYSTEMDDIR}/io.podman.service
- install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.service ${DESTDIR}${USERSYSTEMDDIR}/io.podman.service
+ install ${SELINUXOPT} -d ${DESTDIR}${USERSYSTEMDDIR}
+ # User units are ordered differently, we can't make the *system* multi-user.target depend on a user unit.
+ # For user units the default.target that's the default is fine.
+ sed -e 's,^WantedBy=.*,WantedBy=default.target,' < contrib/varlink/io.podman.service > ${DESTDIR}${USERSYSTEMDDIR}/io.podman.service
install ${SELINUXOPT} -m 644 contrib/varlink/podman.conf ${DESTDIR}${TMPFILESDIR}/podman.conf
uninstall:
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index 8eb12cacd..4ea4d3825 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -21,7 +21,7 @@ import (
var (
buildCommand cliconfig.BuildValues
- buildDescription = "Builds an OCI or Docker image using instructions from one or more Dockerfiles and a specified build context directory."
+ buildDescription = "Builds an OCI or Docker image using instructions from one or more Containerfiles and a specified build context directory."
layerValues buildahcli.LayerResults
budFlagsValues buildahcli.BudResults
fromAndBudValues buildahcli.FromAndBudResults
@@ -30,7 +30,7 @@ var (
_buildCommand = &cobra.Command{
Use: "build [flags] CONTEXT",
- Short: "Build an image using instructions from Dockerfiles",
+ Short: "Build an image using instructions from Containerfiles",
Long: buildDescription,
RunE: func(cmd *cobra.Command, args []string) error {
buildCommand.InputArgs = args
@@ -44,7 +44,7 @@ var (
return buildCmd(&buildCommand)
},
Example: `podman build .
- podman build --creds=username:password -t imageName -f Dockerfile.simple .
+ podman build --creds=username:password -t imageName -f Containerfile.simple .
podman build --layers --force-rm --tag imageName .`,
}
)
@@ -82,16 +82,16 @@ func init() {
markFlagHidden(flags, "signature-policy")
}
-func getDockerfiles(files []string) []string {
- var dockerfiles []string
+func getContainerfiles(files []string) []string {
+ var containerfiles []string
for _, f := range files {
if f == "-" {
- dockerfiles = append(dockerfiles, "/dev/stdin")
+ containerfiles = append(containerfiles, "/dev/stdin")
} else {
- dockerfiles = append(dockerfiles, f)
+ containerfiles = append(containerfiles, f)
}
}
- return dockerfiles
+ return containerfiles
}
func getNsValues(c *cliconfig.BuildValues) ([]buildah.NamespaceOption, error) {
@@ -151,7 +151,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
}
}
- dockerfiles := getDockerfiles(c.File)
+ containerfiles := getContainerfiles(c.File)
format, err := getFormat(&c.PodmanCommand)
if err != nil {
return nil
@@ -190,31 +190,35 @@ func buildCmd(c *cliconfig.BuildValues) error {
}
} else {
// No context directory or URL was specified. Try to use the
- // home of the first locally-available Dockerfile.
- for i := range dockerfiles {
- if strings.HasPrefix(dockerfiles[i], "http://") ||
- strings.HasPrefix(dockerfiles[i], "https://") ||
- strings.HasPrefix(dockerfiles[i], "git://") ||
- strings.HasPrefix(dockerfiles[i], "github.com/") {
+ // home of the first locally-available Containerfile.
+ for i := range containerfiles {
+ if strings.HasPrefix(containerfiles[i], "http://") ||
+ strings.HasPrefix(containerfiles[i], "https://") ||
+ strings.HasPrefix(containerfiles[i], "git://") ||
+ strings.HasPrefix(containerfiles[i], "github.com/") {
continue
}
- absFile, err := filepath.Abs(dockerfiles[i])
+ absFile, err := filepath.Abs(containerfiles[i])
if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
+ return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
}
contextDir = filepath.Dir(absFile)
- dockerfiles[i], err = filepath.Rel(contextDir, absFile)
+ containerfiles[i], err = filepath.Rel(contextDir, absFile)
if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
+ return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
}
break
}
}
if contextDir == "" {
- return errors.Errorf("no context directory specified, and no dockerfile specified")
+ return errors.Errorf("no context directory specified, and no containerfile specified")
}
- if len(dockerfiles) == 0 {
- dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile"))
+ if len(containerfiles) == 0 {
+ if checkIfFileExists(filepath.Join(contextDir, "Containerfile")) {
+ containerfiles = append(containerfiles, filepath.Join(contextDir, "Containerfile"))
+ } else {
+ containerfiles = append(containerfiles, filepath.Join(contextDir, "Dockerfile"))
+ }
}
runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
@@ -318,7 +322,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
Squash: c.Squash,
Target: c.Target,
}
- return runtime.Build(getContext(), c, options, dockerfiles)
+ return runtime.Build(getContext(), c, options, containerfiles)
}
// useLayers returns false if BUILDAH_LAYERS is set to "0" or "false"
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index 5b5225f02..4831b7971 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -651,6 +651,7 @@ type SystemRenumberValues struct {
type SystemMigrateValues struct {
PodmanCommand
+ NewRuntime string
}
type SystemDfValues struct {
diff --git a/cmd/podman/cliconfig/defaults.go b/cmd/podman/cliconfig/defaults.go
index d5dae0874..ce695d153 100644
--- a/cmd/podman/cliconfig/defaults.go
+++ b/cmd/podman/cliconfig/defaults.go
@@ -1,10 +1,5 @@
package cliconfig
-const (
- // DefaultSystemD value
- DefaultSystemD bool = true
-)
-
var (
// DefaultHealthCheckInterval default value
DefaultHealthCheckInterval = "30s"
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 2a3f8f3ad..e93586b62 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -455,9 +455,9 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"sysctl", []string{},
"Sysctl options (default [])",
)
- createFlags.Bool(
- "systemd", cliconfig.DefaultSystemD,
- "Run container in systemd mode if the command executable is systemd or init",
+ createFlags.String(
+ "systemd", "true",
+ `Run container in systemd mode ("true"|"false"|"always" (default "true")`,
)
createFlags.StringArray(
"tmpfs", []string{},
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index 6dafeb0b0..dd8c3f173 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -14,31 +14,31 @@ import (
)
// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers
-func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, true, false, true)
+func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand, newRuntime string) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, false, true, false, true, newRuntime)
}
// GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify
func GetRuntimeDisableFDs(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, false, false)
+ return getRuntime(ctx, c, false, false, false, false, "")
}
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber
func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, true, false, false, true)
+ return getRuntime(ctx, c, true, false, false, true, "")
}
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, false, true)
+ return getRuntime(ctx, c, false, false, false, true, "")
}
// GetRuntimeNoStore generates a new libpod runtime configured by command line options
func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, true, true)
+ return getRuntime(ctx, c, false, false, true, true, "")
}
-func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool) (*libpod.Runtime, error) {
+func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool, newRuntime string) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
storageOpts := storage.StoreOptions{}
storageSet := false
@@ -88,6 +88,9 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migra
}
if migrate {
options = append(options, libpod.WithMigrate())
+ if newRuntime != "" {
+ options = append(options, libpod.WithMigrateRuntime(newRuntime))
+ }
}
if renumber {
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index 022377b1f..15bbb46d2 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -449,10 +449,8 @@ func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, m
// PBatch performs batch operations on a container in parallel. It spawns the
// number of workers relative to the number of parallel operations desired.
func PBatch(containers []*libpod.Container, workers int, opts PsOptions) []PsContainerOutput {
- var (
- wg sync.WaitGroup
- psResults []PsContainerOutput
- )
+ var wg sync.WaitGroup
+ psResults := []PsContainerOutput{}
// If the number of containers in question is less than the number of
// proposed parallel operations, we shouldnt spawn so many workers.
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index 9020613c5..7c56db8db 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -662,9 +662,17 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
return nil, errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.String("image-volume"))
}
- var systemd bool
- if command != nil && c.Bool("systemd") && ((filepath.Base(command[0]) == "init") || (filepath.Base(command[0]) == "systemd")) {
- systemd = true
+ systemd := c.String("systemd") == "always"
+ if !systemd && command != nil {
+ x, err := strconv.ParseBool(c.String("systemd"))
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot parse bool %s", c.String("systemd"))
+ }
+ if x && (command[0] == "/usr/sbin/init" || (filepath.Base(command[0]) == "systemd")) {
+ systemd = true
+ }
+ }
+ if systemd {
if signalString == "" {
stopSignal, err = signal.ParseSignal("RTMIN+3")
if err != nil {
diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go
index bb4eed1e3..9362e8e9b 100644
--- a/cmd/podman/shared/funcs.go
+++ b/cmd/podman/shared/funcs.go
@@ -21,7 +21,7 @@ func GetAuthFile(authfile string) string {
}
if runtimeDir, err := util.GetRuntimeDir(); err == nil {
- return filepath.Join(runtimeDir, "auth.json")
+ return filepath.Join(runtimeDir, "containers/auth.json")
}
return ""
}
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
index cccdd1bea..0f71dc087 100644
--- a/cmd/podman/shared/intermediate.go
+++ b/cmd/podman/shared/intermediate.go
@@ -449,7 +449,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["subgidname"] = newCRString(c, "subgidname")
m["subuidname"] = newCRString(c, "subuidname")
m["sysctl"] = newCRStringSlice(c, "sysctl")
- m["systemd"] = newCRBool(c, "systemd")
+ m["systemd"] = newCRString(c, "systemd")
m["tmpfs"] = newCRStringArray(c, "tmpfs")
m["tty"] = newCRBool(c, "tty")
m["uidmap"] = newCRStringSlice(c, "uidmap")
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
index 9dbf83950..c95470a72 100644
--- a/cmd/podman/shared/intermediate_varlink.go
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -152,7 +152,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create {
Subuidname: StringToPtr(g.Find("subuidname")),
Subgidname: StringToPtr(g.Find("subgidname")),
Sysctl: StringSliceToPtr(g.Find("sysctl")),
- Systemd: BoolToPtr(g.Find("systemd")),
+ Systemd: StringToPtr(g.Find("systemd")),
Tmpfs: StringSliceToPtr(g.Find("tmpfs")),
Tty: BoolToPtr(g.Find("tty")),
Uidmap: StringSliceToPtr(g.Find("uidmap")),
@@ -321,6 +321,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
var memSwapDefault int64 = -1
netModeDefault := "bridge"
+ systemdDefault := "true"
if rootless.IsRootless() {
netModeDefault = "slirp4netns"
}
@@ -409,7 +410,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
m["subgidname"] = stringFromVarlink(opts.Subgidname, "subgidname", nil)
m["subuidname"] = stringFromVarlink(opts.Subuidname, "subuidname", nil)
m["sysctl"] = stringSliceFromVarlink(opts.Sysctl, "sysctl", nil)
- m["systemd"] = boolFromVarlink(opts.Systemd, "systemd", cliconfig.DefaultSystemD)
+ m["systemd"] = stringFromVarlink(opts.Systemd, "systemd", &systemdDefault)
m["tmpfs"] = stringSliceFromVarlink(opts.Tmpfs, "tmpfs", nil)
m["tty"] = boolFromVarlink(opts.Tty, "tty", false)
m["uidmap"] = stringSliceFromVarlink(opts.Uidmap, "uidmap", nil)
diff --git a/cmd/podman/system_migrate.go b/cmd/podman/system_migrate.go
index 4a0afcfad..9c90aeb52 100644
--- a/cmd/podman/system_migrate.go
+++ b/cmd/podman/system_migrate.go
@@ -32,13 +32,15 @@ func init() {
migrateCommand.Command = _migrateCommand
migrateCommand.SetHelpTemplate(HelpTemplate())
migrateCommand.SetUsageTemplate(UsageTemplate())
+ flags := migrateCommand.Flags()
+ flags.StringVar(&migrateCommand.NewRuntime, "new-runtime", "", "Specify a new runtime for all containers")
}
func migrateCmd(c *cliconfig.SystemMigrateValues) error {
// We need to pass one extra option to NewRuntime.
// This will inform the OCI runtime to start a migrate.
// That's controlled by the last argument to GetRuntime.
- r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand)
+ r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand, c.NewRuntime)
if err != nil {
return errors.Wrapf(err, "error migrating containers")
}
diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go
index c0ddaba4e..592d7a1d1 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "os"
"reflect"
"runtime/debug"
@@ -63,3 +64,12 @@ func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
}
return pflag.NormalizedName(name)
}
+
+// Check if a file exists and is not a directory
+func checkIfFileExists(name string) bool {
+ file, err := os.Stat(name)
+ if os.IsNotExist(err) {
+ return false
+ }
+ return !file.IsDir()
+}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 2408dc80c..13e8394fb 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -363,7 +363,7 @@ type Create (
subuidname: ?string,
subgidname: ?string,
sysctl: ?[]string,
- systemd: ?bool,
+ systemd: ?string,
tmpfs: ?[]string,
tty: ?bool,
uidmap: ?[]string,
diff --git a/docs/podman-build.1.md b/docs/podman-build.1.md
index 1a04f8224..c16d964a9 100644
--- a/docs/podman-build.1.md
+++ b/docs/podman-build.1.md
@@ -1,23 +1,25 @@
% podman-build(1)
## NAME
-podman\-build - Build a container image using a Dockerfile
+podman\-build - Build a container image using a Containerfile
## SYNOPSIS
-**podman build** [*options*] *context*
+**podman build** [*options*] [*context*]
-**podman image build** [*options*] *context*
+**podman image build** [*options*] [*context*]
## DESCRIPTION
-**podman build** Builds an image using instructions from one or more Dockerfiles and a specified build context directory.
+**podman build** Builds an image using instructions from one or more Containerfiles or Dockerfiles and a specified build context directory. A Containerfile uses the same syntax as a Dockerfile internally. For this document, a file referred to as a Containerfile can be a file named either 'Containerfile' or 'Dockerfile'.
-The build context directory can be specified as the http(s) URL of an archive, git repository or Dockerfile.
+The build context directory can be specified as the http(s) URL of an archive, git repository or Containerfile.
-Dockerfiles ending with a ".in" suffix will be preprocessed via CPP(1). This can be useful to decompose Dockerfiles into several reusable parts that can be used via CPP's **#include** directive. Notice, a Dockerfile.in file can still be used by other tools when manually preprocessing them via `cpp -E`.
+If no context directory is specified, then Podman will assume the current working directory as the build context, which should contain the Containerfile.
+
+Containerfiles ending with a ".in" suffix will be preprocessed via CPP(1). This can be useful to decompose Containerfiles into several reusable parts that can be used via CPP's **#include** directive. Notice, a Containerfile.in file can still be used by other tools when manually preprocessing them via `cpp -E`.
When the URL is an archive, the contents of the URL is downloaded to a temporary location and extracted before execution.
-When the URL is an Dockerfile, the Dockerfile is downloaded to a temporary location.
+When the URL is an Containerfile, the Containerfile is downloaded to a temporary location.
When a Git repository is set as the URL, the repository is cloned locally and then set as the context.
@@ -46,7 +48,7 @@ environment variable. `export REGISTRY_AUTH_FILE=path`
**--build-arg**=*arg=value*
Specifies a build argument and its value, which will be interpolated in
-instructions read from the Dockerfiles in the same way that environment
+instructions read from the Containerfiles in the same way that environment
variables are, but which will not be added to environment variable list in the
resulting image's configuration.
@@ -170,6 +172,10 @@ The [username[:password]] to use to authenticate with the registry if required.
If one or both values are not supplied, a command line prompt will appear and the
value can be entered. The password is entered without echo.
+**--device**=*device*
+
+Add a host device to the container. The format is `<device-on-host>[:<device-on-container>][:<permissions>]` (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
+
**--disable-compression, -D**
Don't compress filesystem layers when building the image unless it is required
@@ -201,22 +207,22 @@ Set custom DNS options
Set custom DNS search domains
-**--file**, **-f**=*Dockerfile*
+**--file**, **-f**=*Containerfile*
-Specifies a Dockerfile which contains instructions for building the image,
+Specifies a Containerfile which contains instructions for building the image,
either a local file or an **http** or **https** URL. If more than one
-Dockerfile is specified, *FROM* instructions will only be accepted from the
+Containerfile is specified, *FROM* instructions will only be accepted from the
first specified file.
-If a build context is not specified, and at least one Dockerfile is a
+If a build context is not specified, and at least one Containerfile is a
local file, the directory in which it resides will be used as the build
context.
-If you specify `-f -`, the Dockerfile contents will be read from stdin.
+If you specify `-f -`, the Containerfile contents will be read from stdin.
**--force-rm**=*true|false*
-Always remove intermediate containers after a build, even if the build is unsuccessful.
+Always remove intermediate containers after a build, even if the build fails (default false).
**--format**
@@ -368,7 +374,8 @@ environment variable. `export BUILDAH_RUNTIME=/usr/local/bin/runc`
Adds global flags for the container runtime. To list the supported flags, please
consult the manpages of the selected container runtime (`runc` is the default
-runtime, the manpage to consult is `runc(8)`).
+runtime, the manpage to consult is `runc(8)`. When the machine is configured
+for cgroup V2, the default runtime is `crun`, the manpage to consult is `crun(8)`.).
Note: Do not pass the leading `--` to the flag. To pass the runc flag `--log-format json`
to podman build, the option given would be `--runtime-flag log-format=json`.
@@ -408,7 +415,7 @@ If _imageName_ does not include a registry name, the registry name *localhost* w
**--target**=*stageName*
-Set the target build stage to build. When building a Dockerfile with multiple build stages, --target
+Set the target build stage to build. When building a Containerfile with multiple build stages, --target
can be used to specify an intermediate build stage by name as the final stage for the resulting image.
Commands after the target stage will be skipped.
@@ -526,7 +533,7 @@ process.
container. The `OPTIONS` are a comma delimited list and can be:
* [rw|ro]
- * [z|Z]
+ * [z|Z|O]
* [`[r]shared`|`[r]slave`|`[r]private`]
The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The `HOST-DIR`
@@ -559,7 +566,7 @@ Only the current container can use a private volume.
`Overlay Volume Mounts`
- The `:O` flag tells Buildah to mount the directory from the host as a temporary storage using the Overlay file system. The `RUN` command containers are allowed to modify contents within the mountpoint and are stored in the container storage in a separate directory. In Overlay FS terms the source directory will be the lower, and the container storage directory will be the upper. Modifications to the mount point are destroyed when the `RUN` command finishes executing, similar to a tmpfs mount point.
+ The `:O` flag tells Podman to mount the directory from the host as a temporary storage using the Overlay file system. The `RUN` command containers are allowed to modify contents within the mountpoint and are stored in the container storage in a separate directory. In Overlay FS terms the source directory will be the lower, and the container storage directory will be the upper. Modifications to the mount point are destroyed when the `RUN` command finishes executing, similar to a tmpfs mount point.
Any subsequent execution of `RUN` commands sees the original source directory content, any changes from previous RUN commands no longer exists.
@@ -605,16 +612,16 @@ mount can be changed directly. For instance if `/` is the source mount for
## EXAMPLES
-### Build an image using local Dockerfiles
+### Build an image using local Containerfiles
```
$ podman build .
-$ podman build -f Dockerfile.simple .
+$ podman build -f Containerfile.simple .
$ cat ~/Dockerfile | podman build -f - .
-$ podman build -f Dockerfile.simple -f Dockerfile.notsosimple .
+$ podman build -f Dockerfile.simple -f Containerfile.notsosimple .
$ podman build -f Dockerfile.in ~
@@ -649,19 +656,19 @@ $ podman build --no-cache --rm=false -t imageName .
### Building an image using a URL, Git repo, or archive
- The build context directory can be specified as a URL to a Dockerfile, a Git repository, or URL to an archive. If the URL is a Dockerfile, it is downloaded to a temporary location and used as the context. When a Git repository is set as the URL, the repository is cloned locally to a temporary location and then used as the context. Lastly, if the URL is an archive, it is downloaded to a temporary location and extracted before being used as the context.
+ The build context directory can be specified as a URL to a Containerfile, a Git repository, or URL to an archive. If the URL is a Containerfile, it is downloaded to a temporary location and used as the context. When a Git repository is set as the URL, the repository is cloned locally to a temporary location and then used as the context. Lastly, if the URL is an archive, it is downloaded to a temporary location and extracted before being used as the context.
-#### Building an image using a URL to a Dockerfile
+#### Building an image using a URL to a Containerfile
- Podman will download the Dockerfile to a temporary location and then use it as the build context.
+ Podman will download the Containerfile to a temporary location and then use it as the build context.
```
-$ podman build https://10.10.10.1/podman/Dockerfile
+$ podman build https://10.10.10.1/podman/Containerfile
```
#### Building an image using a Git repository
- Podman will clone the specified GitHub repository to a temporary location and use it as the context. The Dockerfile at the root of the repository will be used and it only works if the GitHub repository is a dedicated repository.
+ Podman will clone the specified GitHub repository to a temporary location and use it as the context. The Containerfile at the root of the repository will be used and it only works if the GitHub repository is a dedicated repository.
```
$ podman build git://github.com/scollier/purpletest
@@ -669,10 +676,10 @@ $ podman build git://github.com/scollier/purpletest
#### Building an image using a URL to an archive
- Podman will fetch the archive file, decompress it, and use its contents as the build context. The Dockerfile at the root of the archive and the rest of the archive will get used as the context of the build. If you pass `-f PATH/Dockerfile` option as well, the system will look for that file inside the contents of the archive.
+ Podman will fetch the archive file, decompress it, and use its contents as the build context. The Containerfile at the root of the archive and the rest of the archive will get used as the context of the build. If you pass `-f PATH/Containerfile` option as well, the system will look for that file inside the contents of the archive.
```
-$ podman build -f dev/Dockerfile https://10.10.10.1/podman/context.tar.gz
+$ podman build -f dev/Containerfile https://10.10.10.1/podman/context.tar.gz
```
Note: supported compression formats are 'xz', 'bzip2', 'gzip' and 'identity' (no compression).
@@ -685,14 +692,14 @@ registries.conf is the configuration file which specifies which container regist
## Troubleshooting
-If you are using a useradd command within a Dockerfile with a large UID/GID, it will create a large sparse file `/var/log/lastlog`. This can cause the build to hang forever. Go language does not support sparse files correctly, which can lead to some huge files being created in your container image.
+If you are using a useradd command within a Containerfile with a large UID/GID, it will create a large sparse file `/var/log/lastlog`. This can cause the build to hang forever. Go language does not support sparse files correctly, which can lead to some huge files being created in your container image.
### Solution
If you are using `useradd` within your build script, you should pass the `--no-log-init or -l` option to the `useradd` command. This option tells useradd to stop creating the lastlog file.
## SEE ALSO
-podman(1), buildah(1), containers-registries.conf(5), useradd(8)
+podman(1), buildah(1), containers-registries.conf(5), crun(8), runc(8), useradd(8)
## HISTORY
May 2018, Minor revisions added by Joe Doss <joe@solidadmin.com>
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 46fa4fcd4..35602f97b 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -710,12 +710,18 @@ Network Namespace - current sysctls allowed:
Note: if you use the --network=host option these sysctls will not be allowed.
-**--systemd**=*true|false*
+**--systemd**=*true|false|always*
Run container in systemd mode. The default is *true*.
-If the command you running inside of the container is systemd or init, podman
-will setup tmpfs mount points in the following directories:
+The value *always* enforces the systemd mode is enforced without
+looking at the executable name. Otherwise, if set to true and the
+command you are running inside the container is systemd or
+/usr/sbin/init.
+
+If the command you are running inside of the container is systemd or
+/usr/sbin/init, Podman will setup tmpfs mount points in the following
+directories:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
diff --git a/docs/podman-derivative-api b/docs/podman-derivative-api
new file mode 100644
index 000000000..1b6153df5
--- /dev/null
+++ b/docs/podman-derivative-api
@@ -0,0 +1,64 @@
+.TH How to use libpod for custom/derivative projects
+.PP
+libpod today is a Golang library and a CLI. The choice of interface you make has advantages and disadvantages.
+
+.SH Running as a subprocess
+.PP
+Advantages:
+
+.RS
+.IP \(bu 2
+Many commands output JSON
+.IP \(bu 2
+Works with languages other than Golang
+.IP \(bu 2
+Easy to get started
+
+.RE
+
+.PP
+Disadvantages:
+
+.RS
+.IP \(bu 2
+Error handling is harder
+.IP \(bu 2
+May be slower
+.IP \(bu 2
+Can't hook into or control low\-level things like how images are pulled
+
+.RE
+
+.SH Vendoring into a Go project
+.PP
+Advantages:
+
+.RS
+.IP \(bu 2
+Significant power and control
+
+.RE
+
+.PP
+Disadvantages:
+
+.RS
+.IP \(bu 2
+You are now on the hook for container runtime security updates (partially, \fB\fCrunc\fR/\fB\fCcrun\fR are separate)
+.IP \(bu 2
+Binary size
+.IP \(bu 2
+Potential skew between multiple libpod versions operating on the same storage can cause problems
+
+.RE
+
+.SH Varlink
+.PP
+Some code exists for this; splits the difference. Future uncertain.
+
+.SH Making the choice
+.PP
+A good question to ask first is: Do you want users to be able to use \fB\fCpodman\fR to manipulate the containers created by your project?
+If so, that makes it more likely that you want to run \fB\fCpodman\fR as a subprocess. If you want a separate image store and a fundamentally
+different experience; if what you're doing with containers is quite different from those created by the \fB\fCpodman\fR CLI,
+that may drive you towards vendoring.
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index dfc634288..e255119d7 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -747,12 +747,18 @@ Network Namespace - current sysctls allowed:
Note: if you use the `--network=host` option these sysctls will not be allowed.
-**--systemd**=*true|false*
+**--systemd**=*true|false|always*
Run container in systemd mode. The default is *true*.
-If the command you are running inside of the container is systemd or init, Podman
-will setup tmpfs mount points in the following directories:
+The value *always* enforces the systemd mode is enforced without
+looking at the executable name. Otherwise, if set to true and the
+command you are running inside the container is systemd or
+/usr/sbin/init.
+
+If the command you are running inside of the container is systemd or
+/usr/sbin/init, Podman will setup tmpfs mount points in the following
+directories:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
diff --git a/docs/podman-system-migrate.1.md b/docs/podman-system-migrate.1.md
index d175d0344..d5e3bcb95 100644
--- a/docs/podman-system-migrate.1.md
+++ b/docs/podman-system-migrate.1.md
@@ -24,6 +24,14 @@ pause process. The `/etc/subuid` and `/etc/subgid` files can then be
edited or changed with usermod to recreate the user namespace with the
newly configured mappings.
+## OPTIONS
+
+**--new-runtime**=*runtime*
+
+Set a new OCI runtime for all containers.
+This can be used after a system upgrade which changes the default OCI runtime to move all containers to the new runtime.
+There are no guarantees that the containers will continue to work under the new runtime, as some runtimes support differing options and configurations.
+
## SYNOPSIS
**podman system migrate**
diff --git a/docs/podman.1.md b/docs/podman.1.md
index 742d94bd5..f6fa1a457 100644
--- a/docs/podman.1.md
+++ b/docs/podman.1.md
@@ -137,7 +137,7 @@ the exit codes follow the `chroot` standard, see below:
| Command | Description |
| ------------------------------------------------ | --------------------------------------------------------------------------- |
| [podman-attach(1)](podman-attach.1.md) | Attach to a running container. |
-| [podman-build(1)](podman-build.1.md) | Build a container image using a Dockerfile. |
+| [podman-build(1)](podman-build.1.md) | Build a container image using a Containerfile. |
| [podman-commit(1)](podman-commit.1.md) | Create new image based on the changed container. |
| [podman-container(1)](podman-container.1.md) | Manage containers. |
| [podman-cp(1)](podman-cp.1.md) | Copy files/folders between a container and the local filesystem. |
diff --git a/go.mod b/go.mod
index 40a05553c..356ceaa7a 100644
--- a/go.mod
+++ b/go.mod
@@ -14,9 +14,8 @@ require (
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.8.2
github.com/containers/buildah v1.11.3
- github.com/containers/image v3.0.2+incompatible // indirect
github.com/containers/image/v4 v4.0.1
- github.com/containers/psgo v1.3.1
+ github.com/containers/psgo v1.3.2
github.com/containers/storage v1.13.4
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
diff --git a/go.sum b/go.sum
index 24bcc6ed8..e724b93d0 100644
--- a/go.sum
+++ b/go.sum
@@ -69,6 +69,20 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDpl
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/psgo v1.3.1 h1:1kE+jJ9Ou5f9zQT/M2IdeSclsKWsXrSFlOcnqc+F2TA=
github.com/containers/psgo v1.3.1/go.mod h1:LLiRMmxZ6FWP4bB/fOUu6kDT+4okk/ZCeeykqh0O5Ns=
+github.com/containers/psgo v1.3.2 h1:jYfppPih3S/j2Yi5O14AXjd8GfCx1ph9L3YsoK3adko=
+github.com/containers/psgo v1.3.2/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
+github.com/containers/storage v1.12.10-0.20190627120555-8eed0c36d1e3 h1:kO/YA36sGuPDFvVIzZxJp7xmwa+/wCVADxDSuFzsZwM=
+github.com/containers/storage v1.12.10-0.20190627120555-8eed0c36d1e3/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.11 h1:r35VsROen9Kw3+LN/v4O4g7cT5zQPX06vkcjqScJ2z8=
+github.com/containers/storage v1.12.11/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.12 h1:gao0GNzjmSX4Ai/StOHtUVIrBguC0OKyvx/ZMwBdyuY=
+github.com/containers/storage v1.12.12/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.13 h1:GtaLCY8p1Drlk1Oew581jGvB137UaO+kpz0HII67T0A=
+github.com/containers/storage v1.12.13/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.16 h1:zePYS1GiG8CuRqLCeA0ufx4X27K06HcJLV50DdojL+Y=
+github.com/containers/storage v1.12.16/go.mod h1:QsZp4XMJjyPNNbQHZeyNW3OmhwsWviI+7S6iOcu6a4c=
+github.com/containers/storage v1.13.1 h1:rjVirLS9fCGkUFlLDZEoGDDUugtIf46DufWvJu08wxQ=
+github.com/containers/storage v1.13.1/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.2 h1:UXZ0Ckmk6+6+4vj2M2ywruVtH97pnRoAhTG8ctd+yQI=
github.com/containers/storage v1.13.2/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
diff --git a/libpod/info.go b/libpod/info.go
index 2c28b67c8..e5c075d97 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -61,6 +61,18 @@ func (r *Runtime) hostInfo() (map[string]interface{}, error) {
program["Package"] = packageVersion(path)
info["slirp4netns"] = program
}
+ uidmappings, err := rootless.ReadMappingsProc("/proc/self/uid_map")
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading uid mappings")
+ }
+ gidmappings, err := rootless.ReadMappingsProc("/proc/self/gid_map")
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading gid mappings")
+ }
+ idmappings := make(map[string]interface{})
+ idmappings["uidmap"] = uidmappings
+ idmappings["gidmap"] = gidmappings
+ info["IDMappings"] = idmappings
}
info["Distribution"] = map[string]interface{}{
"distribution": hostDistributionInfo["Distribution"],
@@ -124,6 +136,7 @@ func (r *Runtime) hostInfo() (map[string]interface{}, error) {
}
info["hostname"] = host
info["eventlogger"] = r.eventer.String()
+
return info, nil
}
diff --git a/libpod/options.go b/libpod/options.go
index ee44439ac..ddc5993af 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -463,6 +463,28 @@ func WithMigrate() RuntimeOption {
}
}
+// WithMigrateRuntime instructs Libpod to change the default OCI runtime on all
+// containers during a migration. This is not used if `MigrateRuntime()` is not
+// also passed.
+// Libpod makes no promises that your containers continue to work with the new
+// runtime - migrations between dissimilar runtimes may well break things.
+// Use with caution.
+func WithMigrateRuntime(requestedRuntime string) RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return define.ErrRuntimeFinalized
+ }
+
+ if requestedRuntime == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "must provide a non-empty name for new runtime")
+ }
+
+ rt.migrateRuntime = requestedRuntime
+
+ return nil
+ }
+}
+
// WithEventsLogger sets the events backend to use.
// Currently supported values are "file" for file backend and "journald" for
// journald backend.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index e961145f5..a0cf0ad7c 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -114,6 +114,10 @@ type Runtime struct {
doRenumber bool
doMigrate bool
+ // System migrate can move containers to a new runtime.
+ // We make no promises that these migrated containers work on the new
+ // runtime, though.
+ migrateRuntime string
// valid indicates whether the runtime is ready to use.
// valid is set to true when a runtime is returned from GetRuntime(),
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
index c363991e6..d85652232 100644
--- a/libpod/runtime_migrate.go
+++ b/libpod/runtime_migrate.go
@@ -5,14 +5,15 @@ package libpod
import (
"context"
"fmt"
- "github.com/containers/libpod/pkg/util"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"syscall"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -63,11 +64,34 @@ func (r *Runtime) migrate(ctx context.Context) error {
}
}
+ // Did the user request a new runtime?
+ runtimeChangeRequested := r.migrateRuntime != ""
+ requestedRuntime, runtimeExists := r.ociRuntimes[r.migrateRuntime]
+ if !runtimeExists && runtimeChangeRequested {
+ return errors.Wrapf(define.ErrInvalidArg, "change to runtime %q requested but no such runtime is defined", r.migrateRuntime)
+ }
+
for _, ctr := range allCtrs {
+ needsWrite := false
+
+ // Reset pause process location
oldLocation := filepath.Join(ctr.state.RunDir, "conmon.pid")
if ctr.config.ConmonPidFile == oldLocation {
logrus.Infof("changing conmon PID file for %s", ctr.ID())
ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid")
+ needsWrite = true
+ }
+
+ // Reset runtime
+ if runtimeChangeRequested {
+ logrus.Infof("Resetting container %s runtime to runtime %s", ctr.ID(), r.migrateRuntime)
+ ctr.config.OCIRuntime = r.migrateRuntime
+ ctr.ociRuntime = requestedRuntime
+
+ needsWrite = true
+ }
+
+ if needsWrite {
if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID())
}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 05d641383..99307e8c4 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -431,12 +431,14 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool,
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write setgroups file")
}
+ logrus.Debugf("write setgroups file exited with 0")
uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666)
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write uid_map")
}
+ logrus.Debugf("write uid_map exited with 0")
}
gidsMapped := false
@@ -602,7 +604,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
return joinUserAndMountNS(uint(pausePid), pausePidPath)
}
-func readMappingsProc(path string) ([]idtools.IDMap, error) {
+func ReadMappingsProc(path string) ([]idtools.IDMap, error) {
file, err := os.Open(path)
if err != nil {
return nil, errors.Wrapf(err, "cannot open %s", path)
@@ -668,7 +670,7 @@ func ConfigurationMatches() (bool, error) {
return false, err
}
- currentUIDs, err := readMappingsProc("/proc/self/uid_map")
+ currentUIDs, err := ReadMappingsProc("/proc/self/uid_map")
if err != nil {
return false, err
}
@@ -677,7 +679,7 @@ func ConfigurationMatches() (bool, error) {
return false, err
}
- currentGIDs, err := readMappingsProc("/proc/self/gid_map")
+ currentGIDs, err := ReadMappingsProc("/proc/self/gid_map")
if err != nil {
return false, err
}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
index ddd9182b0..ce488f364 100644
--- a/pkg/rootless/rootless_unsupported.go
+++ b/pkg/rootless/rootless_unsupported.go
@@ -65,3 +65,8 @@ func ConfigurationMatches() (bool, error) {
func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) {
return nil, nil, errors.New("this function is not supported on this os")
}
+
+// ReadMappingsProc returns the uid_map and gid_map
+func ReadMappingsProc(path string) ([]idtools.IDMap, error) {
+ return nil, nil
+}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index a65263b7d..3685450f0 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -195,8 +195,7 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
if c.Interactive {
options = append(options, libpod.WithStdin())
}
- if c.Systemd && (strings.HasSuffix(c.Command[0], "init") ||
- strings.HasSuffix(c.Command[0], "systemd")) {
+ if c.Systemd {
options = append(options, libpod.WithSystemd())
}
if c.Name != "" {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 57c6e8da7..8f00d3270 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -302,8 +302,8 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
// RESOURCES - PIDS
if config.Resources.PidsLimit > 0 {
- // if running on rootless on a cgroupv1 machine, pids limit is
- // not supported. If the value is still the default
+ // if running on rootless on a cgroupv1 machine or using the cgroupfs manager, pids
+ // limit is not supported. If the value is still the default
// then ignore the settings. If the caller asked for a
// non-default, then try to use it.
setPidLimit := true
@@ -312,7 +312,11 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if err != nil {
return nil, err
}
- if !cgroup2 && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ runtimeConfig, err := runtime.GetConfig()
+ if err != nil {
+ return nil, err
+ }
+ if (!cgroup2 || runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
setPidLimit = false
}
}
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index efcf44f76..34f0692b2 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -151,6 +151,13 @@ var _ = Describe("Podman ps", func() {
Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0))
})
+ It("podman ps with no containers is valid json format", func() {
+ result := podmanTest.Podman([]string{"ps", "--format", "json"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.IsJSONOutputValid()).To(BeTrue())
+ })
+
It("podman ps namespace flag with json format", func() {
_, ec, _ := podmanTest.RunLsContainer("test1")
Expect(ec).To(Equal(0))
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index 06ab6aacd..13f14183b 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -110,7 +110,7 @@ var _ = Describe("Podman start", func() {
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).Should(BeNumerically(">", 0))
- Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(BeZero())
+ Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout, 3.0).Should(BeZero())
})
It("podman failed to start without --rm should NOT delete the container", func() {
@@ -122,7 +122,7 @@ var _ = Describe("Podman start", func() {
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).Should(BeNumerically(">", 0))
- Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(Equal(1))
+ Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout, 3.0).Should(Equal(1))
})
It("podman start --sig-proxy should not work without --attach", func() {
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 02778d493..9ec48ba00 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -94,7 +94,7 @@ WantedBy=multi-user.target
Expect(pull.ExitCode()).To(Equal(0))
ctrName := "testSystemd"
- run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", systemdImage, "init"})
+ run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", systemdImage, "/usr/sbin/init"})
run.WaitWithDefaultTimeout()
Expect(run.ExitCode()).To(Equal(0))
ctrID := run.OutputToString()
diff --git a/troubleshooting.md b/troubleshooting.md
index 89c850356..6fed719f7 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -142,7 +142,7 @@ If you are using a useradd command within a Dockerfile with a large UID/GID, it
#### Solution
-If the entry in the Dockerfile looked like: RUN useradd -u 99999000 -g users newuser then add the `--log-no-init` parameter to change it to: `RUN useradd --log-no-init -u 99999000 -g users newuser`. This option tells useradd to stop creating the lastlog file.
+If the entry in the Dockerfile looked like: RUN useradd -u 99999000 -g users newuser then add the `--no-log-init` parameter to change it to: `RUN useradd --no-log-init -u 99999000 -g users newuser`. This option tells useradd to stop creating the lastlog file.
### 7) Permission denied when running Podman commands
diff --git a/vendor/github.com/containers/psgo/.travis.yml b/vendor/github.com/containers/psgo/.travis.yml
index 1399d24d3..c07bb140b 100644
--- a/vendor/github.com/containers/psgo/.travis.yml
+++ b/vendor/github.com/containers/psgo/.travis.yml
@@ -14,6 +14,6 @@ before_install:
- sudo apt-get install -qq bats
script:
- - make validate || travis_terminate 1
- - make build || travis_terminate 1
- - make test || travis_terminate 1
+ - make validate
+ - make build
+ - make test
diff --git a/vendor/github.com/containers/psgo/Makefile b/vendor/github.com/containers/psgo/Makefile
index 6050b9d5b..361820784 100644
--- a/vendor/github.com/containers/psgo/Makefile
+++ b/vendor/github.com/containers/psgo/Makefile
@@ -1,4 +1,5 @@
export GO111MODULE=off
+export GOPROXY=https://proxy.golang.org
SHELL= /bin/bash
GO ?= go
@@ -9,11 +10,17 @@ PROJECT := github.com/containers/psgo
BATS_TESTS := *.bats
GO_SRC=$(shell find . -name \*.go)
+GO_BUILD=$(GO) build
+# Go module support: set `-mod=vendor` to use the vendored sources
+ifeq ($(shell go help mod >/dev/null 2>&1 && echo true), true)
+ GO_BUILD=GO111MODULE=on $(GO) build -mod=vendor
+endif
+
all: validate build
.PHONY: build
build: $(GO_SRC)
- $(GO) build -buildmode=pie -o $(BUILD_DIR)/$(NAME) $(PROJECT)/sample
+ $(GO_BUILD) -buildmode=pie -o $(BUILD_DIR)/$(NAME) $(PROJECT)/sample
.PHONY: clean
clean:
diff --git a/vendor/github.com/containers/psgo/go.mod b/vendor/github.com/containers/psgo/go.mod
index a194ec196..d9d54c5f7 100644
--- a/vendor/github.com/containers/psgo/go.mod
+++ b/vendor/github.com/containers/psgo/go.mod
@@ -6,6 +6,6 @@ require (
github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9
github.com/sirupsen/logrus v0.0.0-20190403091019-9b3cdde74fbe
- github.com/stretchr/testify v1.3.0
+ github.com/stretchr/testify v1.4.0
golang.org/x/sys v0.0.0-20190425145619-16072639606e
)
diff --git a/vendor/github.com/containers/psgo/go.sum b/vendor/github.com/containers/psgo/go.sum
index da6c750db..bbdd99730 100644
--- a/vendor/github.com/containers/psgo/go.sum
+++ b/vendor/github.com/containers/psgo/go.sum
@@ -16,8 +16,12 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190425145619-16072639606e h1:4ktJgTV34+N3qOZUc5fAaG3Pb11qzMm3PkAoTAgUZ2I=
golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go b/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go
new file mode 100644
index 000000000..eecaf87cb
--- /dev/null
+++ b/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go
@@ -0,0 +1,44 @@
+// Copyright 2019 psgo authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cgroups
+
+import (
+ "sync"
+ "syscall"
+)
+
+const (
+ CgroupRoot = "/sys/fs/cgroup"
+ cgroup2SuperMagic = 0x63677270
+)
+
+var (
+ isUnifiedOnce sync.Once
+ isUnified bool
+ isUnifiedErr error
+)
+
+// IsCgroup2UnifiedMode returns whether we are running in cgroup or cgroupv2 mode.
+func IsCgroup2UnifiedMode() (bool, error) {
+ isUnifiedOnce.Do(func() {
+ var st syscall.Statfs_t
+ if err := syscall.Statfs(CgroupRoot, &st); err != nil {
+ isUnified, isUnifiedErr = false, err
+ } else {
+ isUnified, isUnifiedErr = st.Type == cgroup2SuperMagic, nil
+ }
+ })
+ return isUnified, isUnifiedErr
+}
diff --git a/vendor/github.com/containers/psgo/internal/proc/pids.go b/vendor/github.com/containers/psgo/internal/proc/pids.go
index ff4887364..69e8befc1 100644
--- a/vendor/github.com/containers/psgo/internal/proc/pids.go
+++ b/vendor/github.com/containers/psgo/internal/proc/pids.go
@@ -1,4 +1,4 @@
-// Copyright 2018 psgo authors
+// Copyright 2018-2019 psgo authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,8 +18,11 @@ import (
"bufio"
"fmt"
"os"
+ "path/filepath"
"strconv"
"strings"
+
+ "github.com/containers/psgo/internal/cgroups"
)
// GetPIDs extracts and returns all PIDs from /proc.
@@ -49,45 +52,98 @@ func GetPIDs() ([]string, error) {
return pids, nil
}
-// pidCgroupPath returns the path to the pid's pids cgroup.
-func pidCgroupPath(pid string) (string, error) {
+// GetPIDsFromCgroup returns a strings slice of all pids listesd in pid's pids
+// cgroup. It automatically detects if we're running in unified mode or not.
+func GetPIDsFromCgroup(pid string) ([]string, error) {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, err
+ }
+ if unified {
+ return getPIDsFromCgroupV2(pid)
+ }
+ return getPIDsFromCgroupV1(pid)
+}
+
+// getPIDsFromCgroupV1 returns a strings slice of all pids listesd in pid's pids
+// cgroup.
+func getPIDsFromCgroupV1(pid string) ([]string, error) {
+ // First, find the corresponding path to the PID cgroup.
f, err := os.Open(fmt.Sprintf("/proc/%s/cgroup", pid))
if err != nil {
- return "", err
+ return nil, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
+ cgroupPath := ""
for scanner.Scan() {
fields := strings.Split(scanner.Text(), ":")
if len(fields) != 3 {
continue
}
if fields[1] == "pids" {
- return fmt.Sprintf("/sys/fs/cgroup/pids/%s/cgroup.procs", fields[2]), nil
+ cgroupPath = fmt.Sprintf("/sys/fs/cgroup/pids/%s/cgroup.procs", fields[2])
}
}
- return "", fmt.Errorf("couldn't find pids group for PID %s", pid)
+
+ if cgroupPath == "" {
+ return nil, fmt.Errorf("couldn't find v1 pids group for PID %s", pid)
+ }
+
+ // Second, extract the PIDs inside the cgroup.
+ f, err = os.Open(cgroupPath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ pids := []string{}
+ scanner = bufio.NewScanner(f)
+ for scanner.Scan() {
+ pids = append(pids, scanner.Text())
+ }
+
+ return pids, nil
}
-// GetPIDsFromCgroup returns a strings slice of all pids listesd in pid's pids
+// getPIDsFromCgroupV2 returns a strings slice of all pids listesd in pid's pids
// cgroup.
-func GetPIDsFromCgroup(pid string) ([]string, error) {
- cgroupPath, err := pidCgroupPath(pid)
+func getPIDsFromCgroupV2(pid string) ([]string, error) {
+ // First, find the corresponding path to the PID cgroup.
+ f, err := os.Open(fmt.Sprintf("/proc/%s/cgroup", pid))
if err != nil {
return nil, err
}
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ cgroupSlice := ""
+ for scanner.Scan() {
+ fields := strings.Split(scanner.Text(), ":")
+ if len(fields) != 3 {
+ continue
+ }
+ cgroupSlice = fields[2]
+ break
+ }
+
+ if cgroupSlice == "" {
+ return nil, fmt.Errorf("couldn't find v2 pids group for PID %s", pid)
+ }
- f, err := os.Open(cgroupPath)
+ // Second, extract the PIDs inside the cgroup.
+ f, err = os.Open(filepath.Join(cgroups.CgroupRoot, cgroupSlice, "cgroup.procs"))
if err != nil {
return nil, err
}
defer f.Close()
pids := []string{}
- scanner := bufio.NewScanner(f)
+ scanner = bufio.NewScanner(f)
for scanner.Scan() {
pids = append(pids, scanner.Text())
}
+
return pids, nil
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c01409444..c422598fb 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -108,12 +108,13 @@ github.com/containers/image/v4/pkg/blobinfocache/memory
github.com/containers/image/v4/pkg/blobinfocache/internal/prioritize
# github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b
github.com/containers/libtrust
-# github.com/containers/psgo v1.3.1
+# github.com/containers/psgo v1.3.2
github.com/containers/psgo
github.com/containers/psgo/internal/capabilities
github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
+github.com/containers/psgo/internal/cgroups
github.com/containers/psgo/internal/host
# github.com/containers/storage v1.13.4
github.com/containers/storage