summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/containers/ps.go1
-rw-r--r--commands-demo.md6
-rw-r--r--docs/source/Commands.rst10
-rw-r--r--docs/source/connection.rst12
-rw-r--r--docs/source/image.rst10
-rw-r--r--docs/source/index.rst1
-rw-r--r--docs/source/managecontainers.rst6
-rw-r--r--docs/source/manifest.rst14
-rw-r--r--docs/source/markdown/podman-create.1.md4
-rw-r--r--docs/source/markdown/podman-image.1.md6
-rw-r--r--docs/source/markdown/podman-run.1.md4
-rw-r--r--docs/source/markdown/podman-system-connection.1.md14
-rw-r--r--docs/source/system.rst4
-rwxr-xr-xhack/xref-helpmsgs-manpages138
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--pkg/domain/entities/container_ps.go2
-rw-r--r--pkg/domain/infra/abi/images.go2
-rw-r--r--pkg/specgen/container_validate.go5
-rw-r--r--pkg/specgen/generate/container.go15
-rw-r--r--pkg/specgen/generate/container_create.go16
-rw-r--r--pkg/specgen/generate/security.go5
-rw-r--r--pkg/varlinkapi/create.go7
-rw-r--r--test/e2e/ps_test.go15
-rw-r--r--test/e2e/run_test.go30
-rw-r--r--test/e2e/run_working_dir.go69
-rw-r--r--transfer.md26
26 files changed, 348 insertions, 76 deletions
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 64271031d..ebb6ed98f 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -109,6 +109,7 @@ func jsonOut(responses []entities.ListContainer) error {
r := make([]entities.ListContainer, 0)
for _, con := range responses {
con.CreatedAt = units.HumanDuration(time.Since(time.Unix(con.Created, 0))) + " ago"
+ con.Status = psReporter{con}.Status()
r = append(r, con)
}
b, err := json.MarshalIndent(r, "", " ")
diff --git a/commands-demo.md b/commands-demo.md
index 555f83af9..74879842f 100644
--- a/commands-demo.md
+++ b/commands-demo.md
@@ -27,11 +27,11 @@
| [podman-generate-systemd(1)](https://podman.readthedocs.io/en/latest/markdown/podman-generate-systemd.1.html) | Generate systemd unit file(s) for a container or pod. Not supported for the remote client |
| [podman-history(1)](https://podman.readthedocs.io/en/latest/markdown/podman-history.1.html) | Shows the history of an image |
| [podman-image(1)](https://podman.readthedocs.io/en/latest/image.html) | Manage Images |
-| [podman-image-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-exists.1.html) | Check if an image exists in local storage |
| [podman-image-diff(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-diff.html) | Inspect changes on an image's filesystem. |
+| [podman-image-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-exists.1.html) | Check if an image exists in local storage |
| [podman-image-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-prune.1.html) | Remove all unused images from the local store |
-| [podman-image-sign(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-sign.1.html) | Create a signature for an image |
| [podman-image-search(1)](https://podman.readthedocs.io/en/latest/markdown/podman-search.1.html) | Search a registry for an image. |
+| [podman-image-sign(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-sign.1.html) | Create a signature for an image |
| [podman-image-tree(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-tree.1.html) | Prints layer hierarchy of an image in a tree format |
| [podman-image-trust(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-trust.1.html) | Manage container registry image trust policy |
| [podman-images(1)](https://podman.readthedocs.io/en/latest/markdown/podman-images.1.html) | List images in local storage | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/images/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_images.sh) |
@@ -58,9 +58,9 @@
| [podman-pod-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-exists.1.html) | Check if a pod exists in local storage |
| [podman-pod-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-inspect.1.html) | Displays information describing a pod |
| [podman-pod-kill(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-kill.1.html) | Kill the main process of each container in one or more pods |
-| [podman-pod-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-ps.1.html) | Prints out information about pods |
| [podman-pod-pause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pause.1.html) | Pause one or more containers |
| [podman-pod-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-prune.1.html) | Remove all stopped pods and their containers |
+| [podman-pod-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-ps.1.html) | Prints out information about pods |
| [podman-pod-restart](https://podman.readthedocs.io/en/latest/markdown/podman-pod-restart.1.html) | Restart one or more pods |
| [podman-pod-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-rm.1.html) | Remove one or more stopped pods and containers |
| [podman-pod-start(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-start.1.html) | Start one or more pods |
diff --git a/docs/source/Commands.rst b/docs/source/Commands.rst
index aba29bd82..096bdbedf 100644
--- a/docs/source/Commands.rst
+++ b/docs/source/Commands.rst
@@ -6,11 +6,13 @@ Commands
:doc:`attach <markdown/podman-attach.1>` Attach to a running container
+:doc:`auto-update <markdown/podman-auto-update.1>` Auto update containers according to their auto-update policy
+
:doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles
:doc:`commit <markdown/podman-commit.1>` Create new image based on the changed container
-:doc:`containers <managecontainers>` Manage Containers
+:doc:`container <managecontainers>` Manage Containers
:doc:`cp <markdown/podman-cp.1>` Copy files/folders between a container and the local filesystem
@@ -52,6 +54,8 @@ Commands
:doc:`logs <markdown/podman-logs.1>` Fetch the logs of a container
+:doc:`manifest <manifest>` Create and manipulate manifest lists and image indexes
+
:doc:`mount <markdown/podman-mount.1>` Mount a working container's root filesystem
:doc:`network <network>` Manage Networks
@@ -94,12 +98,14 @@ Commands
:doc:`top <markdown/podman-top.1>` Display the running processes of a container
-:doc:`umount <markdown/podman-umount.1>` Unmounts working container's root filesystem
+:doc:`unmount <markdown/podman-unmount.1>` Unmounts working container's root filesystem
:doc:`unpause <markdown/podman-unpause.1>` Unpause the processes in one or more containers
:doc:`unshare <markdown/podman-unshare.1>` Run a command in a modified user namespace
+:doc:`untag <markdown/podman-untag.1>` Removes one or more names from a locally-stored image
+
:doc:`version <markdown/podman-version.1>` Display the Podman Version Information
:doc:`volume <volume>` Manage volumes
diff --git a/docs/source/connection.rst b/docs/source/connection.rst
new file mode 100644
index 000000000..64eb18c57
--- /dev/null
+++ b/docs/source/connection.rst
@@ -0,0 +1,12 @@
+Manage the destination(s) for Podman service(s)
+=================
+
+:doc:`add <markdown/podman-system-connection-add.1>` Record destination for the Podman service
+
+:doc:`default <markdown/podman-system-connection-default.1>` Set named destination as default for the Podman service
+
+:doc:`list <markdown/podman-system-connection-list.1>` List the destination for the Podman service(s)
+
+:doc:`remove <markdown/podman-system-connection-remove.1>` Delete named destination
+
+:doc:`rename <markdown/podman-system-connection-rename.1>` Rename the destination for Podman service
diff --git a/docs/source/image.rst b/docs/source/image.rst
index a8c6171e1..2b0ef3d43 100644
--- a/docs/source/image.rst
+++ b/docs/source/image.rst
@@ -4,6 +4,8 @@ Image
:doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles
+:doc:`diff <markdown/podman-image-diff.1>` Inspect changes on an image's filesystem
+
:doc:`exists <markdown/podman-image-exists.1>` Check if an image exists in local storage
:doc:`history <markdown/podman-history.1>` Show history of a specified image
@@ -16,6 +18,8 @@ Image
:doc:`load <markdown/podman-load.1>` Load an image from container archive
+:doc:`mount <markdown/podman-image-mount.1>` Mount an image's root filesystem.
+
:doc:`prune <markdown/podman-image-prune.1>` Remove unused images
:doc:`pull <markdown/podman-pull.1>` Pull an image from a registry
@@ -26,6 +30,8 @@ Image
:doc:`save <markdown/podman-save.1>` Save image to an archive
+:doc:`search <markdown/podman-search.1>` Search a registry for an image
+
:doc:`sign <markdown/podman-image-sign.1>` Sign an image
:doc:`tag <markdown/podman-tag.1>` Add an additional name to a local image
@@ -33,3 +39,7 @@ Image
:doc:`tree <markdown/podman-image-tree.1>` Prints layer hierarchy of an image in a tree format
:doc:`trust <markdown/podman-image-trust.1>` Manage container image trust policy
+
+:doc:`unmount <markdown/podman-unmount.1>` Unmount an image's root filesystem
+
+:doc:`untag <markdown/podman-untag.1>` Removes one or more names from a locally-stored image
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 715ca2744..9a1381080 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -15,6 +15,7 @@ If you are completely new to containers, we recommend that you check out the :do
:caption: Contents:
Introduction
+ :doc:`<markdown/podman.1>` Simple management tool for pods, containers and images
Commands
Reference
Tutorials
diff --git a/docs/source/managecontainers.rst b/docs/source/managecontainers.rst
index 5c5a83a82..849fd1d25 100644
--- a/docs/source/managecontainers.rst
+++ b/docs/source/managecontainers.rst
@@ -37,10 +37,10 @@ Manage Containers
:doc:`port <markdown/podman-port.1>` List port mappings or a specific mapping for the container
-:doc:`restart <markdown/podman-restart.1>` Restart one or more containers
-
:doc:`prune <markdown/podman-container-prune.1>` Remove all stopped containers
+:doc:`restart <markdown/podman-restart.1>` Restart one or more containers
+
:doc:`restore <markdown/podman-container-restore.1>` Restores one or more containers from a checkpoint
:doc:`rm <markdown/podman-rm.1>` Remove one or more containers
@@ -57,7 +57,7 @@ Manage Containers
:doc:`top <markdown/podman-top.1>` Display the running processes of a container
-:doc:`umount <markdown/podman-umount.1>` Unmounts working container's root filesystem
+:doc:`unmount <markdown/podman-unmount.1>` Unmounts working container's root filesystem
:doc:`unpause <markdown/podman-unpause.1>` Unpause the processes in one or more containers
diff --git a/docs/source/manifest.rst b/docs/source/manifest.rst
new file mode 100644
index 000000000..c63c28502
--- /dev/null
+++ b/docs/source/manifest.rst
@@ -0,0 +1,14 @@
+Create and manipulate manifest lists and image indexes
+=================
+
+:doc:`add <markdown/podman-manifest-add.1>` Add an image to a manifest list or image index
+
+:doc:`annotate <markdown/podman-manifest-annotate.1>` Add or update information about an entry in a manifest list or image index
+
+:doc:`create <markdown/podman-manifest-create.1>` Create a manifest list or image index
+
+:doc:`inspect <markdown/podman-manifest-inspect.1>` Display a manifest list or image index
+
+:doc:`push <markdown/podman-manifest-push.1>` Push a manifest list or image index to a registry
+
+:doc:`remove <markdown/podman-manifest-remove.1>` Remove an image from a manifest list or image index
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 5c58d59fc..f65c52e29 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -801,8 +801,8 @@ Run container in systemd mode. The default is *true*.
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, /usr/sbin/init
-or /sbin/init.
+command you are running inside the container is systemd, /usr/sbin/init,
+/sbin/init or /usr/local/sbin/init.
If the command you are running inside of the container is systemd,
Podman will setup tmpfs mount points in the following directories:
diff --git a/docs/source/markdown/podman-image.1.md b/docs/source/markdown/podman-image.1.md
index 55e95d032..bbf5f6d84 100644
--- a/docs/source/markdown/podman-image.1.md
+++ b/docs/source/markdown/podman-image.1.md
@@ -20,8 +20,8 @@ The image command allows you to manage images
| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. |
| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. |
| list | [podman-images(1)](podman-images.1.md) | List the container images on the system.(alias ls) |
-| mount | [podman-image-mount(1)](podman-image-mount.1.md) | Mount an image's root filesystem. |
| load | [podman-load(1)](podman-load.1.md) | Load an image from the docker archive. |
+| mount | [podman-image-mount(1)](podman-image-mount.1.md) | Mount an image's root filesystem. |
| prune | [podman-image-prune(1)](podman-image-prune.1.md) | Remove all unused images from the local store. |
| pull | [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. |
| push | [podman-push(1)](podman-push.1.md) | Push an image from local storage to elsewhere. |
@@ -30,10 +30,10 @@ The image command allows you to manage images
| search | [podman-search(1)](podman-search.1.md) | Search a registry for an image. |
| sign | [podman-image-sign(1)](podman-image-sign.1.md) | Create a signature for an image. |
| tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. |
-| untag | [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. |
-| unmount | [podman-image-unmount(1)](podman-image-unmount.1.md) | Unmount an image's root filesystem. |
| tree | [podman-image-tree(1)](podman-image-tree.1.md) | Prints layer hierarchy of an image in a tree format. |
| trust | [podman-image-trust(1)](podman-image-trust.1.md) | Manage container registry image trust policy. |
+| unmount | [podman-image-unmount(1)](podman-image-unmount.1.md) | Unmount an image's root filesystem. |
+| untag | [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. |
## SEE ALSO
podman
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index db742e429..976cdd88b 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -831,8 +831,8 @@ Run container in systemd mode. The default is **true**.
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, _/usr/sbin/init_
-or _/sbin/init_.
+command you are running inside the container is systemd, _/usr/sbin/init_,
+_/sbin/init_ or _/usr/local/sbin/init_.
If the command you are running inside of the container is systemd
Podman will setup tmpfs mount points in the following directories:
diff --git a/docs/source/markdown/podman-system-connection.1.md b/docs/source/markdown/podman-system-connection.1.md
index 86199c6b9..0673aaee1 100644
--- a/docs/source/markdown/podman-system-connection.1.md
+++ b/docs/source/markdown/podman-system-connection.1.md
@@ -13,13 +13,13 @@ The user will be prompted for the ssh login password or key file pass phrase as
## COMMANDS
-| Command | Man Page | Description |
-| ------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------- |
-| add | [podman-system-connection-add(1)](podman-system-connection-add.1.md) | Record destination for the Podman service |
-| default | [podman-system-connection-default(1)](podman-system-connection-default.1.md) | Set named destination as default for the Podman service |
-| list | [podman-system-connection-list(1)](podman-system-connection-list.1.md) | List the destination for the Podman service(s) |
-| remove | [podman-system-connection-remove(1)](podman-system-connection-remove.1.md) | Delete named destination |
-| rename | [podman-system-connection-rename(1)](podman-system-connection-rename.1.md) | Rename the destination for Podman service |
+| Command | Man Page | Description |
+| -------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------- |
+| add | [podman-system-connection\-add(1)](podman-system-connection-add.1.md) | Record destination for the Podman service |
+| default | [podman-system-connection\-default(1)](podman-system-connection-default.1.md) | Set named destination as default for the Podman service |
+| list | [podman-system-connection\-list(1)](podman-system-connection-list.1.md) | List the destination for the Podman service(s) |
+| remove | [podman-system-connection\-remove(1)](podman-system-connection-remove.1.md) | Delete named destination |
+| rename | [podman-system-connection\-rename(1)](podman-system-connection-rename.1.md) | Rename the destination for Podman service |
## EXAMPLE
```
diff --git a/docs/source/system.rst b/docs/source/system.rst
index 2d93a1d6d..566fd1a95 100644
--- a/docs/source/system.rst
+++ b/docs/source/system.rst
@@ -1,6 +1,8 @@
System
======
+:doc:`connection <connection>` Manage the destination(s) for Podman service(s)
+
:doc:`df <markdown/podman-system-df.1>` Show podman disk usage
:doc:`info <markdown/podman-info.1>` Display podman system information
@@ -12,3 +14,5 @@ System
:doc:`renumber <markdown/podman-system-renumber.1>` Migrate lock numbers
:doc:`reset <markdown/podman-system-reset.1>` Reset podman storage
+
+:doc:`service <markdown/podman-system-service.1>` Run an API service
diff --git a/hack/xref-helpmsgs-manpages b/hack/xref-helpmsgs-manpages
index 16b596589..7b617eed7 100755
--- a/hack/xref-helpmsgs-manpages
+++ b/hack/xref-helpmsgs-manpages
@@ -26,8 +26,14 @@ $| = 1;
my $Default_Podman = './bin/podman';
my $PODMAN = $ENV{PODMAN} || $Default_Podman;
+# Path to all doc files, including .rst and (down one level) markdown
+my $Docs_Path = 'docs/source';
+
# Path to podman markdown source files (of the form podman-*.1.md)
-my $Markdown_Path = 'docs/source/markdown';
+my $Markdown_Path = "$Docs_Path/markdown";
+
+# Global error count
+my $Errs = 0;
# END user-customizable section
###############################################################################
@@ -96,35 +102,38 @@ sub main {
my $help = podman_help();
my $man = podman_man('podman');
+ my $rst = podman_rst();
+
+ xref_by_help($help, $man);
+ xref_by_man($help, $man);
- my $retval = xref_by_help($help, $man)
- + xref_by_man($help, $man);
+ xref_rst($help, $rst);
- exit !!$retval;
+ exit !!$Errs;
}
+###############################################################################
+# BEGIN cross-referencing
+
##################
# xref_by_help # Find keys in '--help' but not in man
##################
sub xref_by_help {
my ($help, $man, @subcommand) = @_;
- my $errs = 0;
for my $k (sort keys %$help) {
if (exists $man->{$k}) {
if (ref $help->{$k}) {
- $errs += xref_by_help($help->{$k}, $man->{$k}, @subcommand, $k);
+ xref_by_help($help->{$k}, $man->{$k}, @subcommand, $k);
}
# Otherwise, non-ref is leaf node such as a --option
}
else {
my $man = $man->{_path} || 'man';
warn "$ME: podman @subcommand --help lists $k, but $k not in $man\n";
- ++$errs;
+ ++$Errs;
}
}
-
- return $errs;
}
#################
@@ -137,13 +146,11 @@ sub xref_by_help {
sub xref_by_man {
my ($help, $man, @subcommand) = @_;
- my $errs = 0;
-
# FIXME: this generates way too much output
for my $k (grep { $_ ne '_path' } sort keys %$man) {
if (exists $help->{$k}) {
if (ref $man->{$k}) {
- $errs += xref_by_man($help->{$k}, $man->{$k}, @subcommand, $k);
+ xref_by_man($help->{$k}, $man->{$k}, @subcommand, $k);
}
}
elsif ($k ne '--help' && $k ne '-h') {
@@ -175,13 +182,38 @@ sub xref_by_man {
next if "@subcommand" eq 'system' && $k eq 'service';
warn "$ME: podman @subcommand: $k in $man, but not --help\n";
- ++$errs;
+ ++$Errs;
}
}
+}
- return $errs;
+##############
+# xref_rst # Cross-check *.rst files against help
+##############
+sub xref_rst {
+ my ($help, $rst, @subcommand) = @_;
+
+ # Cross-check against rst (but only subcommands, not options).
+ # We key on $help because that is Absolute Truth: anything in podman --help
+ # must be referenced in an rst (the converse is not true).
+ for my $k (sort grep { $_ !~ /^-/ } keys %$help) {
+ # Check for subcommands, if any (eg podman system -> connection -> add)
+ if (ref $help->{$k}) {
+ xref_rst($help->{$k}, $rst->{$k}, @subcommand, $k);
+ }
+
+ # Check that command is mentioned in at least one .rst file
+ if (! exists $rst->{$k}{_desc}) {
+ my @podman = ("podman", @subcommand, $k);
+ warn "$ME: no link in *.rst for @podman\n";
+ ++$Errs;
+ }
+ }
}
+# END cross-referencing
+###############################################################################
+# BEGIN data gathering
#################
# podman_help # Parse output of 'podman [subcommand] --help'
@@ -249,6 +281,7 @@ sub podman_man {
or die "$ME: Cannot read $manpath: $!\n";
my $section = '';
my @most_recent_flags;
+ my $previous_subcmd = '';
while (my $line = <$fh>) {
chomp $line;
next unless $line; # skip empty lines
@@ -278,6 +311,11 @@ sub podman_man {
elsif ($line =~ /^\|\s+(\S+)\s+\|\s+\[\S+\]\((\S+)\.1\.md\)/) {
# $1 will be changed by recursion _*BEFORE*_ left-hand assignment
my $subcmd = $1;
+ if ($previous_subcmd gt $subcmd) {
+ warn "$ME: $subpath: '$previous_subcmd' and '$subcmd' are out of order\n";
+ ++$Errs;
+ }
+ $previous_subcmd = $subcmd;
$man{$subcmd} = podman_man($2);
}
}
@@ -315,4 +353,76 @@ sub podman_man {
}
+################
+# podman_rst # Parse contents of docs/source/*.rst
+################
+sub podman_rst {
+ my %rst;
+
+ # Read all .rst files, looking for ":doc:`subcmd <target>` description"
+ for my $rst (glob "$Docs_Path/*.rst") {
+ open my $fh, '<', $rst
+ or die "$ME: Cannot read $rst: $!\n";
+
+ # The basename of foo.rst is usually, but not always, the name of
+ # a podman subcommand. There are a few special cases:
+ (my $command = $rst) =~ s!^.*/(.*)\.rst!$1!;
+
+ my $subcommand_href = \%rst;
+ if ($command eq 'Commands') {
+ ;
+ }
+ elsif ($command eq 'managecontainers') {
+ $subcommand_href = $rst{container} //= { };
+ }
+ elsif ($command eq 'connection') {
+ $subcommand_href = $rst{system}{connection} //= { };
+ }
+ else {
+ $subcommand_href = $rst{$command} //= { };
+ }
+
+ my $previous_subcommand = '';
+ while (my $line = <$fh>) {
+ if ($line =~ /^:doc:`(\S+)\s+<(.*?)>`\s+(.*)/) {
+ my ($subcommand, $target, $desc) = ($1, $2, $3);
+
+ # Check that entries are in alphabetical order
+ if ($subcommand lt $previous_subcommand) {
+ warn "$ME: $rst:$.: '$previous_subcommand' and '$subcommand' are out of order\n";
+ ++$Errs;
+ }
+ $previous_subcommand = $subcommand;
+
+ # Mark this subcommand as documented.
+ $subcommand_href->{$subcommand}{_desc} = $desc;
+
+ # Check for invalid links. These will be one of two forms:
+ # <markdown/foo.1> -> markdown/foo.1.md
+ # <foo> -> foo.rst
+ if ($target =~ m!^markdown/!) {
+ if (! -e "$Docs_Path/$target.md") {
+ warn "$ME: $rst:$.: '$subcommand' links to nonexistent $target\n";
+ ++$Errs;
+ }
+ }
+ else {
+ if (! -e "$Docs_Path/$target.rst") {
+ warn "$ME: $rst:$.: '$subcommand' links to nonexistent $target.rst\n";
+ }
+ }
+ }
+ }
+ close $fh;
+ }
+
+ # Special case: 'image trust set/show' are documented in image-trust.1
+ $rst{image}{trust}{$_} = { _desc => 'ok' } for (qw(set show));
+
+ return \%rst;
+}
+
+# END data gathering
+###############################################################################
+
1;
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 9fb9738dc..e2bc4e50f 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -626,7 +626,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: "/sys/fs/cgroup/systemd",
Type: "bind",
Source: "/sys/fs/cgroup/systemd",
- Options: []string{"bind", "nodev", "noexec", "nosuid"},
+ Options: []string{"bind", "nodev", "noexec", "nosuid", "rslave"},
}
g.AddMount(systemdMnt)
g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
diff --git a/pkg/domain/entities/container_ps.go b/pkg/domain/entities/container_ps.go
index 50dd4933b..ed40a37ab 100644
--- a/pkg/domain/entities/container_ps.go
+++ b/pkg/domain/entities/container_ps.go
@@ -56,6 +56,8 @@ type ListContainer struct {
StartedAt int64
// State of container
State string
+ // Status is a human-readable approximation of a duration for json output
+ Status string
}
// ListContainer Namespaces contains the identifiers of the container's Linux namespaces
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 35675e1f3..70d740bb5 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -226,7 +226,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
if err != nil {
imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, rawImage))
if err != nil {
- return nil, errors.Errorf("invalid image reference %q", rawImage)
+ return nil, errors.Wrapf(err, "invalid image reference %q", rawImage)
}
}
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 1a1bb4526..8289e2089 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -142,11 +142,6 @@ func (s *SpecGenerator) Validate() error {
return err
}
- // The following are defaults as needed by container creation
- if len(s.WorkDir) < 1 {
- s.WorkDir = "/"
- }
-
// Set defaults if network info is not provided
if s.NetNS.NSMode == "" {
s.NetNS.NSMode = Bridge
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 65f8197bc..53d160442 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -135,15 +135,18 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
s.Annotations = annotations
// workdir
- if newImage != nil {
- workingDir, err := newImage.WorkingDir(ctx)
- if err != nil {
- return nil, err
- }
- if len(s.WorkDir) < 1 && len(workingDir) > 1 {
+ if s.WorkDir == "" {
+ if newImage != nil {
+ workingDir, err := newImage.WorkingDir(ctx)
+ if err != nil {
+ return nil, err
+ }
s.WorkDir = workingDir
}
}
+ if s.WorkDir == "" {
+ s.WorkDir = "/"
+ }
if len(s.SeccompProfilePath) < 1 {
p, err := libpod.DefaultSeccompPath()
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index b61ac2c30..fda4c098c 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -164,13 +164,19 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
}
if len(command) > 0 {
- if command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd") {
+ useSystemdCommands := map[string]bool{
+ "/sbin/init": true,
+ "/usr/sbin/init": true,
+ "/usr/local/sbin/init": true,
+ }
+ if useSystemdCommands[command[0]] || (filepath.Base(command[0]) == "systemd") {
useSystemd = true
}
}
default:
return nil, errors.Wrapf(err, "invalid value %q systemd option requires 'true, false, always'", s.Systemd)
}
+ logrus.Debugf("using systemd mode: %t", useSystemd)
if useSystemd {
// is StopSignal was not set by the user then set it to systemd
// expected StopSigal
@@ -241,13 +247,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
// If the user did not set an workdir but the image did, ensure it is
// created.
if s.WorkDir == "" && img != nil {
- newWD, err := img.WorkingDir(ctx)
- if err != nil {
- return nil, err
- }
- if newWD != "" {
- options = append(options, libpod.WithCreateWorkingDir())
- }
+ options = append(options, libpod.WithCreateWorkingDir())
}
if s.StopSignal != nil {
options = append(options, libpod.WithStopSignal(*s.StopSignal))
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 4352ef718..5e4cc3399 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -158,8 +158,9 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
configSpec.Linux.Seccomp = seccompConfig
}
- // Clear default Seccomp profile from Generator for privileged containers
- if s.SeccompProfilePath == "unconfined" || s.Privileged {
+ // Clear default Seccomp profile from Generator for unconfined containers
+ // and privileged containers which do not specify a seccomp profile.
+ if s.SeccompProfilePath == "unconfined" || (s.Privileged && (s.SeccompProfilePath == config.SeccompOverridePath || s.SeccompProfilePath == config.SeccompDefaultPath)) {
configSpec.Linux.Seccomp = nil
}
diff --git a/pkg/varlinkapi/create.go b/pkg/varlinkapi/create.go
index 2d3e20f67..e9309a2d4 100644
--- a/pkg/varlinkapi/create.go
+++ b/pkg/varlinkapi/create.go
@@ -704,7 +704,12 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
if err != nil {
return nil, errors.Wrapf(err, "cannot parse bool %s", c.String("systemd"))
}
- if x && (command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd")) {
+ useSystemdCommands := map[string]bool{
+ "/sbin/init": true,
+ "/usr/sbin/init": true,
+ "/usr/local/sbin/init": true,
+ }
+ if x && (useSystemdCommands[command[0]] || (filepath.Base(command[0]) == "systemd")) {
systemd = true
}
}
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index f10ef5c99..a734d399d 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -188,6 +188,21 @@ var _ = Describe("Podman ps", func() {
Expect(result.IsJSONOutputValid()).To(BeTrue())
})
+ It("podman ps print a human-readable `Status` with json format", func() {
+ _, ec, _ := podmanTest.RunLsContainer("test1")
+ Expect(ec).To(Equal(0))
+
+ result := podmanTest.Podman([]string{"ps", "-a", "--format", "json"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.IsJSONOutputValid()).To(BeTrue())
+ // must contain "Status"
+ match, StatusLine := result.GrepString(`Status`)
+ Expect(match).To(BeTrue())
+ // container is running or exit, so it must contain `ago`
+ Expect(StatusLine[0]).To(ContainSubstring("ago"))
+ })
+
It("podman ps namespace flag with go template format", func() {
Skip(v2fail)
_, ec, _ := podmanTest.RunLsContainer("test1")
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index dc44d3b3f..30e565894 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -193,22 +193,46 @@ var _ = Describe("Podman run", func() {
Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE"))
})
- It("podman run seccomp test", func() {
-
+ forbidGetCWDSeccompProfile := func() string {
in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
jsonFile, err := podmanTest.CreateSeccompJson(in)
if err != nil {
fmt.Println(err)
Skip("Failed to prepare seccomp.json for test.")
}
+ return jsonFile
+ }
+
+ It("podman run seccomp test", func() {
+ session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(ExitWithError())
+ match, _ := session.GrepString("Operation not permitted")
+ Expect(match).Should(BeTrue())
+ })
- session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", jsonFile}, ""), ALPINE, "pwd"})
+ It("podman run seccomp test --privileged", func() {
+ session := podmanTest.Podman([]string{"run", "-it", "--privileged", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
match, _ := session.GrepString("Operation not permitted")
Expect(match).Should(BeTrue())
})
+ It("podman run seccomp test --privileged no profile should be unconfined", func() {
+ session := podmanTest.Podman([]string{"run", "-it", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.OutputToString()).To(ContainSubstring("0"))
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
+ It("podman run seccomp test no profile should be default", func() {
+ session := podmanTest.Podman([]string{"run", "-it", ALPINE, "grep", "Seccomp", "/proc/self/status"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.OutputToString()).To(ContainSubstring("2"))
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
It("podman run capabilities test", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/run_working_dir.go b/test/e2e/run_working_dir.go
new file mode 100644
index 000000000..93330deba
--- /dev/null
+++ b/test/e2e/run_working_dir.go
@@ -0,0 +1,69 @@
+package integration
+
+import (
+ "os"
+ "strings"
+
+ . "github.com/containers/podman/v2/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Podman run", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+ podmanTest.SeedImages()
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ processTestResult(f)
+
+ })
+
+ It("podman run a container without workdir", func() {
+ session := podmanTest.Podman([]string{"run", ALPINE, "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("/"))
+ })
+
+ It("podman run a container using non existing --workdir", func() {
+ if !strings.Contains(podmanTest.OCIRuntime, "crun") {
+ Skip("Test only works on crun")
+ }
+ session := podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", ALPINE, "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(127))
+ })
+
+ It("podman run a container on an image with a workdir", func() {
+ SkipIfRemote()
+ dockerfile := `FROM alpine
+RUN mkdir -p /home/foobar
+WORKDIR /etc/foobar`
+ podmanTest.BuildImage(dockerfile, "test", "false")
+
+ session := podmanTest.Podman([]string{"run", "test", "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("/etc/foobar"))
+
+ session = podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", "test", "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("/home/foobar"))
+ })
+})
diff --git a/transfer.md b/transfer.md
index 9aa271c37..49ff687e6 100644
--- a/transfer.md
+++ b/transfer.md
@@ -38,10 +38,10 @@ There are other equivalents for these tools
| Existing Step | `Podman` (and friends) |
| :--- | :--- |
| `docker attach` | [`podman attach`](./docs/source/markdown/podman-attach.1.md) |
-| `docker cp` | [`podman cp`](./docs/source/markdown/podman-cp.1.md) |
| `docker build` | [`podman build`](./docs/source/markdown/podman-build.1.md) |
| `docker commit` | [`podman commit`](./docs/source/markdown/podman-commit.1.md) |
| `docker container`|[`podman container`](./docs/source/markdown/podman-container.1.md) |
+| `docker cp` | [`podman cp`](./docs/source/markdown/podman-cp.1.md) |
| `docker create` | [`podman create`](./docs/source/markdown/podman-create.1.md) |
| `docker diff` | [`podman diff`](./docs/source/markdown/podman-diff.1.md) |
| `docker events` | [`podman events`](./docs/source/markdown/podman-events.1.md) |
@@ -59,10 +59,10 @@ There are other equivalents for these tools
| `docker network ls` | [`podman network ls`](./docs/source/markdown/podman-network-ls.1.md) |
| `docker network rm` | [`podman network rm`](./docs.source/markdown/podman-network-rm.1.md) |
| `docker pause` | [`podman pause`](./docs/source/markdown/podman-pause.1.md) |
+| `docker port` | [`podman port`](./docs/source/markdown/podman-port.1.md) |
| `docker ps` | [`podman ps`](./docs/source/markdown/podman-ps.1.md) |
| `docker pull` | [`podman pull`](./docs/source/markdown/podman-pull.1.md) |
| `docker push` | [`podman push`](./docs/source/markdown/podman-push.1.md) |
-| `docker port` | [`podman port`](./docs/source/markdown/podman-port.1.md) |
| `docker restart` | [`podman restart`](./docs/source/markdown/podman-restart.1.md) |
| `docker rm` | [`podman rm`](./docs/source/markdown/podman-rm.1.md) |
| `docker rmi` | [`podman rmi`](./docs/source/markdown/podman-rmi.1.md) |
@@ -71,20 +71,20 @@ There are other equivalents for these tools
| `docker search` | [`podman search`](./docs/source/markdown/podman-search.1.md) |
| `docker start` | [`podman start`](./docs/source/markdown/podman-start.1.md) |
| `docker stop` | [`podman stop`](./docs/source/markdown/podman-stop.1.md) |
+| `docker system df` | [`podman system df`](./docs/source/markdown/podman-system-df.1.md) |
+| `docker system info` | [`podman system info`](./docs/source/markdown/podman-system-info.1.md) |
+| `docker system prune` | [`podman system prune`](./docs/source/markdown/podman-system-prune.1.md) |
+| `docker system` | [`podman system`](./docs/source/markdown/podman-system.1.md) |
| `docker tag` | [`podman tag`](./docs/source/markdown/podman-tag.1.md) |
| `docker top` | [`podman top`](./docs/source/markdown/podman-top.1.md) |
| `docker unpause` | [`podman unpause`](./docs/source/markdown/podman-unpause.1.md) |
| `docker version` | [`podman version`](./docs/source/markdown/podman-version.1.md) |
-| `docker volume` | [`podman volume`](./docs/source/markdown/podman-volume.1.md) |
| `docker volume create` | [`podman volume create`](./docs/source/markdown/podman-volume-create.1.md) |
| `docker volume inspect`| [`podman volume inspect`](./docs/source/markdown/podman-volume-inspect.1.md)|
| `docker volume ls` | [`podman volume ls`](./docs/source/markdown/podman-volume-ls.1.md) |
| `docker volume prune` | [`podman volume prune`](./docs/source/markdown/podman-volume-prune.1.md) |
| `docker volume rm` | [`podman volume rm`](./docs/source/markdown/podman-volume-rm.1.md) |
-| `docker system` | [`podman system`](./docs/source/markdown/podman-system.1.md) |
-| `docker system df` | [`podman system df`](./docs/source/markdown/podman-system-df.1.md) |
-| `docker system prune` | [`podman system prune`](./docs/source/markdown/podman-system-prune.1.md) |
-| `docker system info` | [`podman system info`](./docs/source/markdown/podman-system-info.1.md) |
+| `docker volume` | [`podman volume`](./docs/source/markdown/podman-volume.1.md) |
| `docker wait` | [`podman wait`](./docs/source/markdown/podman-wait.1.md) |
**** Use mount to take advantage of the entire linux tool chain rather then just cp. Read [`here`](./docs/podman-cp.1.md) for more information.
@@ -95,8 +95,8 @@ Those Docker commands currently do not have equivalents in `podman`:
| Missing command | Description|
| :--- | :--- |
-| `docker container update` | podman does not support altering running containers. We recommend recreating containers with the correct arguments.|
| `docker container rename` | podman does not support `container rename` - or the `rename` shorthand. We recommend using `podman rm` and `podman create` to create a container with a specific name.|
+| `docker container update` | podman does not support altering running containers. We recommend recreating containers with the correct arguments.|
| `docker node` ||
| `docker plugin` | podman does not support plugins. We recommend you use alternative OCI Runtimes or OCI Runtime Hooks to alter behavior of podman.|
| `docker secret` ||
@@ -108,22 +108,21 @@ Those Docker commands currently do not have equivalents in `podman`:
The following podman commands do not have a Docker equivalent:
-* [`podman generate`](./docs/source/markdown/podman-generate.1.md)
-* [`podman generate kube`](./docs/source/markdown/podman-generate-kube.1.md)
* [`podman container checkpoint`](/docs/source/markdown/podman-container-checkpoint.1.md)
* [`podman container cleanup`](/docs/source/markdown/podman-container-cleanup.1.md)
* [`podman container exists`](/docs/source/markdown/podman-container-exists.1.md)
* [`podman container refresh`](/docs/source/markdown/podman-container-refresh.1.md)
-* [`podman container runlabel`](/docs/source/markdown/podman-container-runlabel.1.md)
* [`podman container restore`](/docs/source/markdown/podman-container-restore.1.md)
+* [`podman container runlabel`](/docs/source/markdown/podman-container-runlabel.1.md)
+* [`podman generate kube`](./docs/source/markdown/podman-generate-kube.1.md)
+* [`podman generate`](./docs/source/markdown/podman-generate.1.md)
* [`podman healthcheck run`](/docs/source/markdown/podman-healthcheck-run.1.md)
* [`podman image exists`](./docs/source/markdown/podman-image-exists.1.md)
* [`podman image sign`](./docs/source/markdown/podman-image-sign.1.md)
* [`podman image trust`](./docs/source/markdown/podman-image-trust.1.md)
* [`podman mount`](./docs/source/markdown/podman-mount.1.md)
-* [`podman play`](./docs/source/markdown/podman-play.1.md)
* [`podman play kube`](./docs/source/markdown/podman-play-kube.1.md)
-* [`podman pod`](./docs/source/markdown/podman-pod.1.md)
+* [`podman play`](./docs/source/markdown/podman-play.1.md)
* [`podman pod create`](./docs/source/markdown/podman-pod-create.1.md)
* [`podman pod exists`](./docs/source/markdown/podman-pod-exists.1.md)
* [`podman pod inspect`](./docs/source/markdown/podman-pod-inspect.1.md)
@@ -136,4 +135,5 @@ The following podman commands do not have a Docker equivalent:
* [`podman pod stop`](./docs/source/markdown/podman-pod-stop.1.md)
* [`podman pod top`](./docs/source/markdown/podman-pod-top.1.md)
* [`podman pod unpause`](./docs/source/markdown/podman-pod-unpause.1.md)
+* [`podman pod`](./docs/source/markdown/podman-pod.1.md)
* [`podman umount`](./docs/source/markdown/podman-umount.1.md)