summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--cmd/podman/common/create_opts.go4
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--docs/MANPAGE_SYNTAX.md59
-rw-r--r--docs/source/markdown/podman-attach.1.md36
-rw-r--r--docs/source/markdown/podman-auto-update.1.md55
-rw-r--r--docs/source/markdown/podman-commit.1.md46
-rw-r--r--docs/tutorials/mac_experimental.md99
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--libpod/container_internal_linux.go20
-rw-r--r--libpod/container_log.go54
-rw-r--r--pkg/api/handlers/compat/images.go34
-rw-r--r--pkg/api/handlers/compat/networks.go2
-rw-r--r--pkg/api/handlers/compat/swagger.go7
-rw-r--r--pkg/api/handlers/libpod/images_pull.go2
-rw-r--r--pkg/api/handlers/libpod/networks.go3
-rw-r--r--pkg/api/handlers/libpod/swagger.go7
-rw-r--r--pkg/api/server/register_images.go20
-rw-r--r--pkg/api/server/register_networks.go9
-rw-r--r--test/apiv2/20-containers.at9
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_image.py5
-rw-r--r--test/e2e/logs_test.go14
-rw-r--r--test/system/255-auto-update.bats274
-rw-r--r--vendor/github.com/containers/buildah/CHANGELOG.md3
-rw-r--r--vendor/github.com/containers/buildah/changelog.txt3
-rw-r--r--vendor/github.com/containers/buildah/define/types.go2
-rw-r--r--vendor/modules.txt2
-rw-r--r--version/version.go2
29 files changed, 629 insertions, 162 deletions
diff --git a/Makefile b/Makefile
index 15d6d9fb6..4a7c727de 100644
--- a/Makefile
+++ b/Makefile
@@ -428,8 +428,16 @@ pkg/api/swagger.yaml: .gopathok
make -C pkg/api
$(MANPAGES): %: %.md .install.md2man docdir
- @sed -e 's/\((podman[^)]*\.md)\)//g' -e 's/\[\(podman[^]]*\)\]/\1/g' \
- -e 's;<\(/\)\?\(a\|a\s\+[^>]*\|sup\)>;;g' $< | \
+
+### sed is used to filter http/s links as well as relative links
+### replaces "\" at the end of a line with two spaces
+### this ensures that manpages are renderd correctly
+
+ @sed -e 's/\((podman[^)]*\.md\(#.*\)\?)\)//g' \
+ -e 's/\[\(podman[^]]*\)\]/\1/g' \
+ -e 's/\[\([^]]*\)](http[^)]\+)/\1/g' \
+ -e 's;<\(/\)\?\(a\|a\s\+[^>]*\|sup\)>;;g' \
+ -e 's/\\$// /g' $< | \
$(GOMD2MAN) -in /dev/stdin -out $(subst source/markdown,build/man,$@)
.PHONY: docdir
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 76d7345fc..66778f519 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -249,7 +249,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
}
// netMode
- nsmode, _, err := specgen.ParseNetworkNamespace(string(cc.HostConfig.NetworkMode), true)
+ nsmode, networks, err := specgen.ParseNetworkNamespace(string(cc.HostConfig.NetworkMode), true)
if err != nil {
return nil, nil, err
}
@@ -322,7 +322,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
netInfo.Aliases = aliases
netInfo.CNINetworks = cniNetworks
case len(cc.HostConfig.NetworkMode) > 0:
- netInfo.CNINetworks = []string{string(cc.HostConfig.NetworkMode)}
+ netInfo.CNINetworks = networks
}
parsedTmp := make([]string, 0, len(cc.HostConfig.Tmpfs))
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 02b73bdb8..6146a2c0e 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -36,7 +36,7 @@ Epoch: 99
%else
Epoch: 0
%endif
-Version: 3.2.0
+Version: 3.3.0
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/docs/MANPAGE_SYNTAX.md b/docs/MANPAGE_SYNTAX.md
index 436ec5e8d..c9b677688 100644
--- a/docs/MANPAGE_SYNTAX.md
+++ b/docs/MANPAGE_SYNTAX.md
@@ -10,7 +10,7 @@ podman\-command - short description
**podman subcommand command** [*optional*] *mandatory value*
-(If there is the possibility to chose between 2 (two) or more mandatory command values. There should also always be a space before and after a vertical bar to ensure better readability.)
+(If there is the possibility to chose between two or more mandatory command values. There should also always be a space before and after a vertical bar to ensure better readability.)
**podman command** [*optional*] *value1* | *value2*
@@ -29,51 +29,68 @@ podman\-command - short description
**podman subcommand command** [*optional*] *value* [*value* ...]
## DESCRIPTION
-**podman command** is always the beginning of the DESCRIPTION section. Putting the command as the first part of the DESCRIPTION ensures uniformity. All commands mentioned in a text retain their appearance and form.\
-Example sentence: The command **podman command** is an example command.\
-It should also be specified if the command can only be run as root. In addition, it should be described when a command or OPTION cannot be executed with the remote client. For a command, this should be done in the DESCRIPTION part. For the OPTIONS, it should be done in the DESCRIPTION of the specified OPTION. Do not use pronouns in the man pages, especially the word `you`.
+**podman command** is always the beginning of the DESCRIPTION section. Putting the command as the first part of the DESCRIPTION ensures uniformity. All commands mentioned in the text retain their appearance and form.\
+Example sentence: The command **podman command** is an example command.
+
+Commands or files that are quoted from other podman manpages or podman repositories have to be linked to those. Non-podman commands are not to be linked.\
+Example sentence: You can use **[podman-run](podman-run.1.md)** or **[containers.conf(5)](https://github.com/containers/common/blob/master/docs/containers.conf.5.md)** for the problem.
+
+It should also be specified if the command can only be run as root. In addition, it should be described when a command, OPTION, or other content cannot be executed with the remote client or in combination with other commands, OPTIONS, or content. In this case, the following sentence is put at the end of a command, OPTION, or content: *IMPORTANT: This option/command/other is not available with the command/OPTION/content/remote Podman client*. For a command, this should be done in the DESCRIPTION section. For the OPTIONS, it should be done in the DESCRIPTION of the specified OPTION. Do not use pronouns in the man pages, especially the word `you`.
## OPTIONS
-All flags are referred to as OPTIONS. The term flags should not be used. All OPTIONS are listed in this section. OPTIONS that appear in descriptions of other OPTIONS and sections retain their appearance, for example: **--exit**. Each OPTION should be explained to the fullest extend below the OPTION itself. Each OPTION is behind an H4-header (`####`).
+All flags are referred to as OPTIONS. The term flags should not be used. All OPTIONS are listed in this section. OPTIONS that appear in descriptions of other OPTIONS and sections retain their appearance, for example: **--exit**.
+
+OPTIONS that are quoted from other podman manpages or podman repositories have to be linked to those.\
+Example sentence: You can use **[podman-generate-systemd --new](podman-generate-systemd.1.md#--new)** for the problem.
+
+ Each OPTION should be explained to the fullest extent below the OPTION itself. Each OPTION is behind an H4-header (`####`). If the OPTION has a default argument, it has to be explained in the description of the OPTION. If the OPTION is also not available with the remote client, the sentence about the default argument should the second to last sentence.
+
-#### **--option**, **-o**
+#### **--version**, **-v**
-OPTIONS can be put after the command in two different ways. Eather the long version with **--option** or as the short version **-o**. If there are two ways to write an OPTION they are separated by a comma. If there are 2 (two) versions of one command the long version is always shown in front.
+OPTIONS can be put after the command in two different ways. Eather the long version with **--option** or as the short version **-o**. If there are two ways to write an OPTION they are separated by a comma. If there are two versions of one command the long version is always shown in front.\
+Example: The default is **false**. *IMPORTANT: This option is not available with the remote Podman client*.
#### **--exit**
An example of an OPTION that has only one possible structure. Thus, it cannot be executed by the extension **-e**.
-#### **--answer**=, **-a**=**_active_** | *disable*
+#### **--answer**=, **-a**=**active** | *disable*
-OPTIONS that accept 2 possible arguments as inputs are shown above. If there is a default argument that is selected when no special input is made, it is shown in **_bold italics_**. It must always be ensured that the standard argument is in the first place after the OPTION. In this example, there are 2 (two) different versions to execute the command. Both versions of the OPTION have to be shown with the arguments behind them.
+The "answer" option above is an example of an OPTION that accepts two possible arguments as inputs. If there is a default argument that is selected when the OPTION is not used in the command, it is shown in **bold**. If the OPTION is used it must include an argument afterwards. It must always be ensured that the standard argument is in the first position after the OPTION. In this example, there are two different ways to execute the command. Both possible OPTIONS have to be shown with the arguments following them. The default value is shown as **active**.
#### **--status**=**good** | *better* | *best*
-This is an example for 3 (three) arguments behind an OPTION. If the number of arguments is higher than 3 (three), the arguments are **not** listed after the equal sign. The arguments have to be explained in a table like in **--test**=**_test_** regardless of the number of arguments.
+This is an example of three arguments following an OPTION. If the number of arguments is greater than three, the arguments are **not** listed after the equal sign. The arguments have to be shown in a table like in **--test**=**_test_**, regardless of the number of arguments. The default value is shown as **good**.
-#### **--test**=**_test_**
+#### **--test**=**test**
-OPTIONS that are followed by an equal sign include an argument after the equal sign in *italic*. If there is a default argument, that is used if the OPTION is not specified in the **command**, the argument after the eqaul sign is displayed in **bold**. All arguments must be listed and explained in the text below the OPTION.
+OPTIONS that are followed by an equal sign include an argument after the equal sign in **bold**. If there is a default argument, that is used if the OPTION is not specified in the command, the argument after the eqaul sign is displayed in **bold**. All arguments must be listed and explained in the text below the OPTION.
| Argument | Description |
-| - | - |
-| **_example one_** | This argument is the standard argument if the OPTION is not specified. |
+| ------------------ | --------------------------------------------------------------------------- |
+| **example one** | This argument is the default argument if the OPTION is not specified. |
| *example two* | If one refers to a command, one should use **bold** marks. |
-| *example three* | Example: In combination with **podman command** highly effective. |
+| *example three* | Example: In combination with **podman command** highly effective. |
| *example four* | Example: Can be combined with **--exit**. |
| *example five* | The fifth description |
-The table shows an example for a listing of arguments. The contents in the table should be aligned left. If the content in the table conflicts with this, it can be aligned in a way that supports the understanding of the content. If there is a standard argument, it **must** listed as the first entry in the table.
+The table shows an example for a listing of arguments. The contents in the table should be aligned left. If the content in the table conflicts with this, it can be aligned in a way that supports the understanding of the content. If there is a default argument, it **must** listed as the first entry in the table. The default value is shown as **example one**.
-If the number of arguments is smaller than 4 (four) they have to be listed behind the OPTION as seen in the OPTION **--status**.
+
+If the number of arguments is smaller than four they have to be listed behind the OPTION as seen in the OPTION **--status**.
+
+#### **--problem**=*problem*
+
+OPTIONS that are followed by an equal sign that is then followed by an unspecified argument, have no default argument. If this OPTION is written with an equal sign and the argument is left empty, there will be no error, but the OPTION will be ignored. The meaning of the argument is described preferably in `one` word after the equal sign in *italic* format.
## SUBCHAPTER
For chapters that are made specifically as an individual SUBCHAPTER in a man page, the previous conditions regarding formatting apply.
There are no restrictions for the use of paragraphs and tables. Within these paragraphs and tables the previous conditions regarding formatting apply.
-Strings of characters or numbers can be highlighted with `backticks`. Paths of any kind **must** be highlighted.\
+Strings of characters or numbers can be highlighted with `backticks`. Paths of any kind **must** be highlighted.
+
IMPORTANT: Only characters that are **not** part of categories mentioned before can be highlighted. This includes headers. For example it is not advised to highlight an OPTION or a **command**.
SUBHEADINGS are displayed as follows:
@@ -81,9 +98,9 @@ SUBHEADINGS are displayed as follows:
Text for SUBHEADINGS.
## EXAMPLES
-All EXAMPLES are listed in this section. This section should be at the end of each man page. Each EXAMPLE is always in one box. The box starts and ends with the last written line, **not** with a blank line. The `$` in front of the commands indicates that it can be run as a normal user, while the commands starting with `#` can only be run as root.
+All EXAMPLES are listed in this section. This section should be at the end of each man page. Each EXAMPLE is always in one box. The box starts and ends with the last written line, **not** with a blank line. The `$` in front of the commands indicates that it can be run as a normal user, while the commands starting with `#` can only be run as root. If there is the need for a comment in a box the comment should have `###` in front of it.
-### Description of the EXAMPLE
+Description of the EXAMPLE
```
$ podman command
@@ -92,7 +109,7 @@ $ podman command -o
$ cat $HOME/Dockerfile | podman command --option
```
-### Description of the EXAMPLE 2
+Description of the EXAMPLE two
```
$ podman command --redhat
diff --git a/docs/source/markdown/podman-attach.1.md b/docs/source/markdown/podman-attach.1.md
index c4a5eec50..092772916 100644
--- a/docs/source/markdown/podman-attach.1.md
+++ b/docs/source/markdown/podman-attach.1.md
@@ -9,48 +9,48 @@ podman\-attach - Attach to a running container
**podman container attach** [*options*] *container*
## DESCRIPTION
-The attach command allows you to attach to a running container using the container's ID
-or name, either to view its ongoing output or to control it interactively.
-
-You can detach from the container (and leave it running) using a configurable key sequence. The default
-sequence is `ctrl-p,ctrl-q`.
-Configure the keys sequence using the **--detach-keys** option, or specifying
-it in the **containers.conf** file: see **containers.conf(5)** for more information.
+**podman attach** attaches to a running *container* using the *container's name* or *ID*, to either view its ongoing output or to control it interactively.\
+The *container* can detached from (and leave it running) using a configurable key sequence. The default sequence is `ctrl-p,ctrl-q`. Configure the keys sequence using the **--detach-keys** option, or specifying it in the `containers.conf` file: see **[containers.conf(5)](https://github.com/containers/common/blob/master/docs/containers.conf.5.md)** for more information.
## OPTIONS
-#### **--detach-keys**=*sequence*
+#### **--detach-keys**=**sequence**
-Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
+Specify the key **sequence** for detaching a *container*. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is `ctrl-p,ctrl-q`.
#### **--latest**, **-l**
-Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
-to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client)
+Instead of providing the *container name* or *ID*, use the last created *container*. If you use methods other than Podman to run containers such as CRI-O, the last started *container* could be from either of those methods. The default is **false**.\
+*IMPORTANT: This option is not available with the remote Podman client*
#### **--no-stdin**
-Do not attach STDIN. The default is false.
+Do not attach STDIN. The default is **false**.
-#### **--sig-proxy**=*true*|*false*
+#### **--sig-proxy**
-Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is *true*.
+Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is **true**.
## EXAMPLES
+Attach to a container called "foobar".
```
$ podman attach foobar
-[root@localhost /]#
```
+
+Attach to the latest created container.
```
$ podman attach --latest
-[root@localhost /]#
```
+
+Attach to a container that start with the ID "1234".
```
$ podman attach 1234
-[root@localhost /]#
```
+
+Attach to a container without attaching STDIN.
```
$ podman attach --no-stdin foobar
```
+
## SEE ALSO
-podman(1), podman-exec(1), podman-run(1), containers.conf(5)
+**[podman(1)](podman.1.md)**, **[podman-exec(1)](podman-exec.1.md)**, **[podman-run(1)](podman-run.1.md)**, **[containers.conf(5)](https://github.com/containers/common/blob/master/docs/containers.conf.5.md)**
diff --git a/docs/source/markdown/podman-auto-update.1.md b/docs/source/markdown/podman-auto-update.1.md
index 087c56360..52a9a3fec 100644
--- a/docs/source/markdown/podman-auto-update.1.md
+++ b/docs/source/markdown/podman-auto-update.1.md
@@ -1,16 +1,16 @@
% podman-auto-update(1)
## NAME
-podman-auto-update - Auto update containers according to their auto-update policy
+podman\-auto-update - Auto update containers according to their auto-update policy
## SYNOPSIS
**podman auto-update** [*options*]
## DESCRIPTION
-`podman auto-update` looks up containers with a specified "io.containers.autoupdate" label (i.e., the auto-update policy).
+**podman auto-update** looks up containers with a specified `io.containers.autoupdate` label (i.e., the auto-update policy).
-If the label is present and set to "registry", Podman reaches out to the corresponding registry to check if the image has been updated.
-The label "image" is an alternative to "registry" maintained for backwards compatibility.
+If the label is present and set to `registry`, Podman reaches out to the corresponding registry to check if the image has been updated.
+The label `image` is an alternative to `registry` maintained for backwards compatibility.
An image is considered updated if the digest in the local storage is different than the one of the remote image.
If an image must be updated, Podman pulls it down and restarts the systemd unit executing the container.
@@ -18,60 +18,57 @@ The registry policy requires a fully-qualified image reference (e.g., quay.io/po
This enforcement is necessary to know which image to actually check and pull.
If an image ID was used, Podman would not know which image to check/pull anymore.
-Alternatively, if the autoupdate label is set to "local", Podman will compare the image a container is using to the image with it's raw name in local storage.
+Alternatively, if the autoupdate label is set to `local`, Podman will compare the image a container is using to the image with its raw name in local storage.
If an image is updated locally, Podman simply restarts the systemd unit executing the container.
-If "io.containers.autoupdate.authfile" label is present, Podman reaches out to corresponding authfile when pulling images.
+If `io.containers.autoupdate.authfile` label is present, Podman reaches out to the corresponding authfile when pulling images.
-At container-creation time, Podman looks up the "PODMAN_SYSTEMD_UNIT" environment variables and stores it verbatim in the container's label.
-This variable is now set by all systemd units generated by `podman-generate-systemd` and is set to `%n` (i.e., the name of systemd unit starting the container).
+At container-creation time, Podman looks up the `PODMAN_SYSTEMD_UNIT` environment variable and stores it verbatim in the container's label.
+This variable is now set by all systemd units generated by **[podman-generate-systemd](podman-generate-systemd.1.md)** and is set to `%n` (i.e., the name of systemd unit starting the container).
This data is then being used in the auto-update sequence to instruct systemd (via DBUS) to restart the unit and hence to restart the container.
-Note that `podman auto-update` relies on systemd. The systemd units are expected to be generated with `podman-generate-systemd --new`, or similar units that create new containers in order to run the updated images.
+Note that **podman auto-update** relies on systemd. The systemd units are expected to be generated with **[podman-generate-systemd --new](podman-generate-systemd.1.md#--new)**, or similar units that create new containers in order to run the updated images.
Systemd units that start and stop a container cannot run a new image.
-
### Systemd Unit and Timer
-Podman ships with a `podman-auto-update.service` systemd unit. This unit is triggered daily at midnight by the `podman-auto-update.timer` systemd timer. The timer can be altered for custom time-based updates if desired. The unit can further be invoked by other systemd units (e.g., via the dependency tree) or manually via `systemctl start podman-auto-update.service`.
-
+Podman ships with a `podman-auto-update.service` systemd unit. This unit is triggered daily at midnight by the `podman-auto-update.timer` systemd timer. The timer can be altered for custom time-based updates if desired. The unit can further be invoked by other systemd units (e.g., via the dependency tree) or manually via **systemctl start podman-auto-update.service**.
## OPTIONS
#### **--authfile**=*path*
-Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
-If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
+Path of the authentication file. Default is `${XDG_RUNTIME_DIR}/containers/auth.json`, which is set using **[podman login](podman-login.1.md)**.
+If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using **docker login**.
-Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
-environment variable. `export REGISTRY_AUTH_FILE=path`
+Note: There is also the option to override the default path of the authentication file by setting the `REGISTRY_AUTH_FILE` environment variable. This can be done with **export REGISTRY_AUTH_FILE=_path_**.
## EXAMPLES
Autoupdate with registry policy
```
-# Start a container
+### Start a container
$ podman run --label "io.containers.autoupdate=registry" \
--label "io.containers.autoupdate.authfile=/some/authfile.json" \
-d busybox:latest top
bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d
-# Generate a systemd unit for this container
+### Generate a systemd unit for this container
$ podman generate systemd --new --files bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d
/home/user/containers/libpod/container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service
-# Load the new systemd unit and start it
+### Load the new systemd unit and start it
$ mv ./container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service ~/.config/systemd/user
$ systemctl --user daemon-reload
-# If the previously created containers or pods are using shared resources, such as ports, make sure to remove them before starting the generated systemd units.
+### If the previously created containers or pods are using shared resources, such as ports, make sure to remove them before starting the generated systemd units.
$ podman stop bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d
$ podman rm bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d
$ systemctl --user start container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service
-# Auto-update the container
+### Auto-update the container
$ podman auto-update
container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service
```
@@ -79,37 +76,37 @@ container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.servi
Autoupdate with local policy
```
-# Start a container
+### Start a container
$ podman run --label "io.containers.autoupdate=local" \
-d busybox:latest top
be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338
-# Generate a systemd unit for this container
+### Generate a systemd unit for this container
$ podman generate systemd --new --files be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338
/home/user/containers/libpod/container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service
-# Load the new systemd unit and start it
+### Load the new systemd unit and start it
$ mv ./container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service ~/.config/systemd/user
$ systemctl --user daemon-reload
-# If the previously created containers or pods are using shared resources, such as ports, make sure to remove them before starting the generated systemd units.
+### If the previously created containers or pods are using shared resources, such as ports, make sure to remove them before starting the generated systemd units.
$ podman stop be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338
$ podman rm be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338
$ systemctl --user start container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service
-# Get the name of the container
+### Get the name of the container
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
01f5c8113e84 docker.io/library/busybox:latest top 2 seconds ago Up 3 seconds ago inspiring_galileo
-# Modify the image
+### Modify the image
$ podman commit --change CMD=/bin/bash inspiring_galileo busybox:latest
-# Auto-update the container
+### Auto-update the container
$ podman auto-update
container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service
```
## SEE ALSO
-podman(1), podman-generate-systemd(1), podman-run(1), systemd.unit(5)
+**[podman(1)](podman.1.md)**, **[podman-generate-systemd(1)](podman-generate-systemd.1.md)**, **[podman-run(1)](podman-run.1.md)**, systemd.unit(5)
diff --git a/docs/source/markdown/podman-commit.1.md b/docs/source/markdown/podman-commit.1.md
index 7485e9bd9..92574cdc5 100644
--- a/docs/source/markdown/podman-commit.1.md
+++ b/docs/source/markdown/podman-commit.1.md
@@ -9,34 +9,27 @@ podman\-commit - Create new image based on the changed container
**podman container commit** [*options*] *container* [*image*]
## DESCRIPTION
-**podman commit** creates an image based on a changed container. The author of the
-image can be set using the `--author` flag. Various image instructions can be
-configured with the `--change` flag and a commit message can be set using the
-`--message` flag. The container and its processes are paused while the image is
-committed. This minimizes the likelihood of data corruption when creating the new
-image. If this is not desired, the `--pause` flag can be set to false. When the commit
-is complete, Podman will print out the ID of the new image.
+**podman commit** creates an image based on a changed *container*. The author of the image can be set using the **--author** OPTION. Various image instructions can be configured with the **--change** OPTION and a commit message can be set using the **--message** OPTION. The *container* and its processes are paused while the image is committed. This minimizes the likelihood of data corruption when creating the new image. If this is not desired, the **--pause** OPTION can be set to *false*. When the commit is complete, Podman will print out the ID of the new image.
-If *image* does not begin with a registry name component, `localhost` will be added to the name.
-If *image* is not provided, the values for the `REPOSITORY` and `TAG` values of the created image will each be set to `<none>`.
+If `image` does not begin with a registry name component, `localhost` will be added to the name.
+If `image` is not provided, the values for the `REPOSITORY` and `TAG` values of the created image will each be set to `<none>`.
## OPTIONS
#### **--author**, **-a**=*author*
-Set the author for the committed image
+Set the author for the committed image.
#### **--change**, **-c**=*instruction*
Apply the following possible instructions to the created image:
**CMD** | **ENTRYPOINT** | **ENV** | **EXPOSE** | **LABEL** | **ONBUILD** | **STOPSIGNAL** | **USER** | **VOLUME** | **WORKDIR**
-Can be set multiple times
+Can be set multiple times.
-#### **--format**, **-f**=*format*
+#### **--format**, **-f** =**oci** | *docker*
-Set the format of the image manifest and metadata. The currently supported formats are _oci_ and _docker_. If
-not specifically set, the default format used is _oci_.
+Set the format of the image manifest and metadata. The currently supported formats are **oci** and *docker*. The default is **oci**.
#### **--iidfile**=*ImageIDfile*
@@ -44,23 +37,24 @@ Write the image ID to the file.
#### **--include-volumes**
-Include in the committed image any volumes added to the container by the `--volume` or `--mount` options to the `podman create` and `podman run` commands.
+Include in the committed image any volumes added to the container by the **--volume** or **--mount** OPTIONS to the **[podman create](podman-create.1.md)** and **[podman run](podman-run.1.md)** commands. The default is **false**.
#### **--message**, **-m**=*message*
-Set commit message for committed image. The message field is not supported in _oci_ format.
+Set commit message for committed image.\
+*IMPORTANT: The message field is not supported in `oci` format.*
#### **--pause**, **-p**
-Pause the container when creating an image
+Pause the container when creating an image. The default is **false**.
#### **--quiet**, **-q**
-Suppress output
+Suppresses output. The default is **false**.
## EXAMPLES
-### Create image from container with entrypoint and label
+Create image from container with entrypoint and label
```
$ podman commit --change CMD=/bin/bash --change ENTRYPOINT=/bin/sh --change "LABEL blue=image" reverent_golick image-committed
Getting image source signatures
@@ -73,39 +67,39 @@ Storing signatures
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
```
-### Create image from container with commit message
+Create image from container with commit message
```
$ podman commit -q --message "committing container to image"
reverent_golick image-committed
-e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8 ```
+e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
```
-### Create image from container with author
+Create image from container with author
```
$ podman commit -q --author "firstName lastName" reverent_golick image-committed
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
```
-### Pause a running container while creating the image
+Pause a running container while creating the image
```
$ podman commit -q --pause=true containerID image-committed
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
```
-### Create an image from a container with a default image tag
+Create an image from a container with a default image tag
```
$ podman commit containerID
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
```
-### Create an image from container with default required capabilities are SETUID and SETGID
+Create an image from container with default required capabilities are SETUID and SETGID
```
$ podman commit -q --change LABEL=io.containers.capabilities=setuid,setgid epic_nobel privimage
400d31a3f36dca751435e80a0e16da4859beb51ff84670ce6bdc5edb30b94066
```
## SEE ALSO
-podman(1), podman-run(1), podman-create(1)
+**[podman(1)](podman.1.md)**, **[podman-run(1)](podman-run.1.md)**, **[podman-create(1)](podman-create.1.md)**
## HISTORY
December 2017, Originally compiled by Urvashi Mohnani <umohnani@redhat.com>
diff --git a/docs/tutorials/mac_experimental.md b/docs/tutorials/mac_experimental.md
new file mode 100644
index 000000000..8df64dc99
--- /dev/null
+++ b/docs/tutorials/mac_experimental.md
@@ -0,0 +1,99 @@
+# Using podman-machine on MacOS (x86_64 and Apple silicon)
+
+## Setup
+
+You must obtain a compressed tarball that contains the following:
+* a qcow image
+* a podman binary
+* a gvproxy binary
+
+You must also have installed brew prior to following this process. See https://brew.sh/ for
+installation instructions.
+
+Note: If your user has admin rights, you can ignore the use of `sudo` in these instructions.
+
+
+1. Install qemu from brew to obtain the required runtime dependencies.
+
+ ```
+ brew install qemu
+ ```
+
+2. If you are running MacOS on the Intel architecture, you can skip to step 8.
+3. Uninstall the brew package
+
+ ```
+ brew uninstall qemu
+ ```
+
+4. Get upstream qemu source code.
+
+ ```
+ git clone https://github.com/qemu/qemu
+ ```
+
+5. Apply patches that have not been merged into upstream qemu.
+
+ ```
+ cd qemu
+ git config user.name "YOUR_NAME"
+ git config user.email johndoe@example.com
+ git checkout v5.2.0
+ curl https://patchwork.kernel.org/series/418581/mbox/ | git am --exclude=MAINTAINERS
+ curl -L https://gist.github.com/citruz/9896cd6fb63288ac95f81716756cb9aa/raw/2d613e9a003b28dfe688f33055706d3873025a40/xcode-12-4.patch | git apply -
+ ```
+
+6. Install qemu build dependencies
+
+ ```
+ brew install libffi gettext pkg-config autoconf automake pixman ninja make
+ ```
+
+7. Configure, compile, and install qemu
+ ```
+ mkdir build
+ cd build
+ ../configure --target-list=aarch64-softmmu --disable-gnutls
+ gmake -j8
+ sudo gmake install
+ ```
+
+
+8. Uncompress and place provided binaries into filesystem
+
+ **Note**: In the following instructions, you need to know the name of the compressed file
+that you were given. It will be used in two of the steps below.
+
+ ```
+ cd ~
+ tar xvf `compressed_file_ending_in_xz`
+ sudo cp -v `unpacked_directory`/{gvproxy,podman} /usr/local/bin
+ ```
+
+9. Sign all binaries
+
+ If you have a Mac with Apple Silicon, issue the following command:
+ ```
+ sudo codesign --entitlements ~/qemu/accel/hvf/entitlements.plist --force -s - /usr/local/bin/qemu-* /usr/local/bin/gvproxy /usr/local/bin/podman
+ ```
+
+ If you have a Mac with an Intel processor, issue the following command:
+
+ ```
+ echo '<?xml version="1.0" encoding="utf-8"?>
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+ <plist version="1.0"> <dict> <key>com.apple.security.hypervisor</key> <true/> </dict> </plist>
+ ' > ~/entitlements.plist
+ sudo codesign --entitlements ~/entitlements.plist --force -s - /usr/local/bin/qemu-* /usr/local/bin/gvproxy /usr/local/bin/podman
+ ```
+
+
+## Test podman
+
+1. podman machine init --image-path /path/to/image
+2. podman machine start
+3. podman images
+4. git clone http://github.com/baude/alpine_nginx && cd alpine_nginx
+5. podman build -t alpine_nginx .
+4. podman run -dt -p 9999:80 alpine_nginx
+5. curl http://localhost:9999
diff --git a/go.mod b/go.mod
index 66a27f0ef..061577d92 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/container-orchestrated-devices/container-device-interface v0.0.0-20210325223243-f99e8b6c10b9
github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.1
- github.com/containers/buildah v1.21.0
+ github.com/containers/buildah v1.21.1
github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.12.0
diff --git a/go.sum b/go.sum
index af13ed423..73bf19bf6 100644
--- a/go.sum
+++ b/go.sum
@@ -218,8 +218,8 @@ github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHV
github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9r2Quag7HMLV8=
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
-github.com/containers/buildah v1.21.0 h1:LuwuqRPjan3X3AIdGwfkEkqMgmrDMNpQznFqNdHgCz8=
-github.com/containers/buildah v1.21.0/go.mod h1:yPdlpVd93T+i91yGxrJbW1YOWrqN64j5ZhHOZmHUejs=
+github.com/containers/buildah v1.21.1 h1:e9LmTCUKUBLg72v5DnIOT/wc8ffkfB7LbpQBywLZo20=
+github.com/containers/buildah v1.21.1/go.mod h1:yPdlpVd93T+i91yGxrJbW1YOWrqN64j5ZhHOZmHUejs=
github.com/containers/common v0.38.4/go.mod h1:egfpX/Y3+19Dz4Wa1eRZDdgzoEOeneieF9CQppKzLBg=
github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a h1:XzYOUf7qjgVJ59YGqAzehlbT63EgjUJhMnfhsPSSJV0=
github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a/go.mod h1:CxHAf4iQOZZ8nASIjMdYHHRyA8dMR4tINSS7WQWlv90=
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index a3acc3198..94bf7855b 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1650,22 +1650,20 @@ func (c *Container) generateResolvConf() (string, error) {
}
}
- // Determine the endpoint for resolv.conf in case it is a symlink
- resolvPath, err := filepath.EvalSymlinks(resolvConf)
+ contents, err := ioutil.ReadFile(resolvConf)
// resolv.conf doesn't have to exists
if err != nil && !os.IsNotExist(err) {
return "", err
}
- // Determine if symlink points to any of the systemd-resolved files
- if strings.HasPrefix(resolvPath, "/run/systemd/resolve/") {
- resolvPath = "/run/systemd/resolve/resolv.conf"
- }
-
- contents, err := ioutil.ReadFile(resolvPath)
- // resolv.conf doesn't have to exists
- if err != nil && !os.IsNotExist(err) {
- return "", err
+ ns := resolvconf.GetNameservers(contents)
+ // check if systemd-resolved is used, assume it is used when 127.0.0.53 is the only nameserver
+ if len(ns) == 1 && ns[0] == "127.0.0.53" {
+ // read the actual resolv.conf file for systemd-resolved
+ contents, err = ioutil.ReadFile("/run/systemd/resolve/resolv.conf")
+ if err != nil {
+ return "", errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
+ }
}
ipv6 := false
diff --git a/libpod/container_log.go b/libpod/container_log.go
index c207df819..a30e4f5cc 100644
--- a/libpod/container_log.go
+++ b/libpod/container_log.go
@@ -4,11 +4,10 @@ import (
"context"
"fmt"
"os"
- "time"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/libpod/logs"
- "github.com/hpcloud/tail/watch"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -94,27 +93,40 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
}()
// Check if container is still running or paused
if options.Follow {
+ state, err := c.State()
+ if err != nil || state != define.ContainerStateRunning {
+ // If the container isn't running or if we encountered
+ // an error getting its state, instruct the logger to
+ // read the file until EOF.
+ tailError := t.StopAtEOF()
+ if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
+ logrus.Error(tailError)
+ }
+ if errors.Cause(err) != define.ErrNoSuchCtr {
+ logrus.Error(err)
+ }
+ return nil
+ }
+
+ // The container is running, so we need to wait until the container exited
go func() {
- for {
- state, err := c.State()
- time.Sleep(watch.POLL_DURATION)
- if err != nil {
- tailError := t.StopAtEOF()
- if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
- logrus.Error(tailError)
- }
- if errors.Cause(err) != define.ErrNoSuchCtr {
- logrus.Error(err)
- }
- break
- }
- if state != define.ContainerStateRunning && state != define.ContainerStatePaused {
- tailError := t.StopAtEOF()
- if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
- logrus.Error(tailError)
- }
- break
+ eventChannel := make(chan *events.Event)
+ eventOptions := events.ReadOptions{
+ EventChannel: eventChannel,
+ Filters: []string{"event=died", "container=" + c.ID()},
+ Stream: true,
+ }
+ go func() {
+ if err := c.runtime.Events(ctx, eventOptions); err != nil {
+ logrus.Errorf("Error waiting for container to exit: %v", err)
}
+ }()
+ // Now wait for the died event and signal to finish
+ // reading the log until EOF.
+ <-eventChannel
+ tailError := t.StopAtEOF()
+ if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
+ logrus.Error(tailError)
}
}()
}
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 7b336c470..ac212474b 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -168,6 +168,8 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
query := struct {
FromSrc string `schema:"fromSrc"`
Changes []string `schema:"changes"`
+ Message string `schema:"message"`
+ Repo string `shchema:"repo"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -184,14 +186,15 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
return
}
+
source = f.Name()
if err := SaveFromBody(f, r); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
}
}
-
imageEngine := abi.ImageEngine{Libpod: runtime}
- report, err := imageEngine.Import(r.Context(), entities.ImageImportOptions{Source: source, Changes: query.Changes})
+ // TODO: add support for ImageImportOptions to take a platform parameter. Also import https://github.com/opencontainers/image-spec/tree/master/specs-go/v1 either here or within imageEngine.Import to get default platform
+ report, err := imageEngine.Import(r.Context(), entities.ImageImportOptions{Source: source, Changes: query.Changes, Message: query.Message, Reference: query.Repo})
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball"))
return
@@ -224,10 +227,10 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
query := struct {
FromImage string `schema:"fromImage"`
Tag string `schema:"tag"`
+ Platform string `schema:"platform"`
}{
// This is where you can override the golang default value for one of fields
}
-
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
@@ -250,12 +253,36 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
}
defer auth.RemoveAuthfile(authfile)
+ platformSpecs := strings.Split(query.Platform, "/") // split query into its parts
+
+ addOS := true // default assume true due to structure of if/else below
+ addArch := false
+ addVariant := false
+
+ if len(platformSpecs) > 1 { // if we have two arguments then we have os and arch
+ addArch = true
+ if len(platformSpecs) > 2 { // if we have 3 arguments then we have os arch and variant
+ addVariant = true
+ }
+ } else if len(platformSpecs) == 0 {
+ addOS = false
+ }
+
pullOptions := &libimage.PullOptions{}
pullOptions.AuthFilePath = authfile
if authConf != nil {
pullOptions.Username = authConf.Username
pullOptions.Password = authConf.Password
pullOptions.IdentityToken = authConf.IdentityToken
+ if addOS { // if the len is not 0
+ pullOptions.OS = platformSpecs[0]
+ if addArch {
+ pullOptions.Architecture = platformSpecs[1]
+ }
+ if addVariant {
+ pullOptions.Variant = platformSpecs[2]
+ }
+ }
}
pullOptions.Writer = os.Stderr // allows for debugging on the server
@@ -294,7 +321,6 @@ loop: // break out of for/select infinite loop
Error string `json:"error,omitempty"`
Id string `json:"id,omitempty"` // nolint
}
-
select {
case e := <-progress:
switch e.Event {
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index be895001c..4e1f31404 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -419,7 +419,7 @@ func Prune(w http.ResponseWriter, r *http.Request) {
type response struct {
NetworksDeleted []string
}
- var prunedNetworks []string //nolint
+ prunedNetworks := []string{}
for _, pr := range pruneReports {
if pr.Error != nil {
logrus.Error(pr.Error)
diff --git a/pkg/api/handlers/compat/swagger.go b/pkg/api/handlers/compat/swagger.go
index a0783e723..b773799ef 100644
--- a/pkg/api/handlers/compat/swagger.go
+++ b/pkg/api/handlers/compat/swagger.go
@@ -77,10 +77,3 @@ type swagCompatNetworkDisconnectRequest struct {
// in:body
Body struct{ types.NetworkDisconnect }
}
-
-// Network prune
-// swagger:response NetworkPruneResponse
-type swagCompatNetworkPruneResponse struct {
- // in:body
- Body []string
-}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index fe56aa31d..e88b53a4b 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -85,7 +85,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
var pulledImages []*libimage.Image
var pullError error
- runCtx, cancel := context.WithCancel(context.Background())
+ runCtx, cancel := context.WithCancel(r.Context())
go func() {
defer cancel()
pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, config.PullPolicyAlways, pullOptions)
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 5417f778e..e4f450e12 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -190,5 +190,8 @@ func Prune(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
+ if pruneReports == nil {
+ pruneReports = []*entities.NetworkPruneReport{}
+ }
utils.WriteResponse(w, http.StatusOK, pruneReports)
}
diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go
index 19eced986..2ac5009fc 100644
--- a/pkg/api/handlers/libpod/swagger.go
+++ b/pkg/api/handlers/libpod/swagger.go
@@ -119,6 +119,13 @@ type swagNetworkCreateReport struct {
Body entities.NetworkCreateReport
}
+// Network prune
+// swagger:response NetworkPruneResponse
+type swagNetworkPruneResponse struct {
+ // in:body
+ Body []entities.NetworkPruneReport
+}
+
func ServeSwagger(w http.ResponseWriter, r *http.Request) {
path := DefaultPodmanSwaggerSpec
if p, found := os.LookupEnv("PODMAN_SWAGGER_SPEC"); found {
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 9634bd83b..b28818768 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -28,15 +28,28 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - in: query
// name: fromImage
// type: string
- // description: needs description
+ // description: Name of the image to pull. The name may include a tag or digest. This parameter may only be used when pulling an image. The pull is cancelled if the HTTP connection is closed.
// - in: query
// name: fromSrc
// type: string
- // description: needs description
+ // description: Source to import. The value may be a URL from which the image can be retrieved or - to read the image from the request body. This parameter may only be used when importing an image
+ // - in: query
+ // name: repo
+ // type: string
+ // description: Repository name given to an image when it is imported. The repo may include a tag. This parameter may only be used when importing an image.
// - in: query
// name: tag
// type: string
- // description: needs description
+ // description: Tag or digest. If empty when pulling an image, this causes all tags for the given image to be pulled.
+ // - in: query
+ // name: message
+ // type: string
+ // description: Set commit message for imported image.
+ // - in: query
+ // name: platform
+ // type: string
+ // description: Platform in the format os[/arch[/variant]]
+ // default: ""
// - in: header
// name: X-Registry-Auth
// type: string
@@ -45,6 +58,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// name: request
// schema:
// type: string
+ // format: binary
// description: Image content if fromSrc parameter was used
// responses:
// 200:
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index 9b2e187b2..69c6896b8 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -190,9 +190,12 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// 200:
// description: OK
// schema:
- // type: array
- // items:
- // type: string
+ // type: object
+ // properties:
+ // NetworksDeleted:
+ // type: array
+ // items:
+ // type: string
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/networks/prune"), s.APIHandler(compat.Prune)).Methods(http.MethodPost)
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index a81210855..ef51757c9 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -341,3 +341,12 @@ t GET containers/$cid/json 200 \
.HostConfig.NanoCpus=500000
t DELETE containers/$cid?v=true 204
+
+# Test Compat Create with default network mode (#10569)
+t POST containers/create Image=$IMAGE HostConfig='{"NetworkMode":"default"}' 201 \
+ .Id~[0-9a-f]\\{64\\}
+cid=$(jq -r '.Id' <<<"$output")
+t GET containers/$cid/json 200 \
+ .HostConfig.NetworkMode="bridge"
+
+t DELETE containers/$cid?v=true 204
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_image.py b/test/apiv2/python/rest_api/test_v2_0_0_image.py
index 243b1d5f5..2cd7bfa96 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_image.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_image.py
@@ -86,6 +86,11 @@ class ImageTestCase(APITestCase):
self.assertTrue(keys["id"], "Expected to find id stanza")
self.assertTrue(keys["images"], "Expected to find images stanza")
self.assertTrue(keys["stream"], "Expected to find stream progress stanza's")
+ def test_create(self):
+ r = requests.post(self.podman_url + "/v1.40/images/create?fromImage=alpine&platform=linux/amd64/v8", timeout=15)
+ self.assertEqual(r.status_code, 200, r.text)
+ r = requests.post(self.podman_url + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123", timeout=15)
+ self.assertEqual(r.status_code, 200, r.text)
def test_search_compat(self):
url = self.podman_url + "/v1.40/images/search"
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index 4d9cbb48b..b576fa072 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -173,9 +173,9 @@ var _ = Describe("Podman logs", func() {
})
It("streaming output: "+log, func() {
- containerName := "logs-f-rm"
+ containerName := "logs-f"
- logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--rm", "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman; sleep 1; echo podman"})
+ logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman-1; sleep 1; echo podman-2"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -183,10 +183,8 @@ var _ = Describe("Podman logs", func() {
results.WaitWithDefaultTimeout()
Expect(results).To(Exit(0))
- // TODO: we should actually check for two podman lines,
- // but as of 2020-06-17 there's a race condition in which
- // 'logs -f' may not catch all output from a container
- Expect(results.OutputToString()).To(ContainSubstring("podman"))
+ Expect(results.OutputToString()).To(ContainSubstring("podman-1"))
+ Expect(results.OutputToString()).To(ContainSubstring("podman-2"))
// Container should now be terminatING or terminatED, but we
// have no guarantee of which: 'logs -f' does not necessarily
@@ -199,6 +197,10 @@ var _ = Describe("Podman logs", func() {
} else {
Expect(inspect.ErrorToString()).To(ContainSubstring("no such container"))
}
+
+ results = podmanTest.Podman([]string{"rm", "-f", containerName})
+ results.WaitWithDefaultTimeout()
+ Expect(results).To(Exit(0))
})
It("follow output stopped container: "+log, func() {
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
new file mode 100644
index 000000000..9bfb44791
--- /dev/null
+++ b/test/system/255-auto-update.bats
@@ -0,0 +1,274 @@
+#!/usr/bin/env bats -*- bats -*-
+#
+# Tests for automatically update images for containerized services
+#
+
+load helpers
+
+UNIT_DIR="/usr/lib/systemd/system"
+SNAME_FILE=$BATS_TMPDIR/services
+
+function setup() {
+ skip_if_remote "systemd tests are meaningless over remote"
+ skip_if_rootless
+
+ basic_setup
+}
+
+function teardown() {
+ while read line; do
+ if [[ "$line" =~ "podman-auto-update" ]]; then
+ echo "Stop timer: $line.timer"
+ systemctl stop $line.timer
+ systemctl disable $line.timer
+ else
+ systemctl stop $line
+ fi
+ rm -f $UNIT_DIR/$line.{service,timer}
+ done < $SNAME_FILE
+
+ rm -f $SNAME_FILE
+ run_podman ? rmi quay.io/libpod/alpine:latest
+ run_podman ? rmi quay.io/libpod/alpine_nginx:latest
+ run_podman ? rmi quay.io/libpod/localtest:latest
+ basic_teardown
+}
+
+# This functions is used for handle the basic step in auto-update related
+# tests. Including following steps:
+# 1. Generate a random container name and echo it to output.
+# 2. Tag the fake image before test
+# 3. Start a container with io.containers.autoupdate
+# 4. Generate the service file from the container
+# 5. Remove the origin container
+# 6. Start the container from service
+function generate_service() {
+ local target_img_basename=$1
+ local autoupdate=$2
+
+ # Container name. Include the autoupdate type, to make debugging easier.
+ # IMPORTANT: variable 'cname' is passed (out of scope) up to caller!
+ cname=c_${autoupdate//\'/}_$(random_string)
+ target_img="quay.io/libpod/$target_img_basename:latest"
+ run_podman tag $IMAGE $target_img
+ if [[ -n "$autoupdate" ]]; then
+ label="--label io.containers.autoupdate=$autoupdate"
+ else
+ label=""
+ fi
+ run_podman run -d --name $cname $label $target_img top -d 120
+
+ run_podman generate systemd --new $cname
+ echo "$output" > "$UNIT_DIR/container-$cname.service"
+ echo "container-$cname" >> $SNAME_FILE
+ run_podman rm -f $cname
+
+ systemctl daemon-reload
+ systemctl start container-$cname
+ systemctl status container-$cname
+
+ # Original image ID.
+ # IMPORTANT: variable 'ori_image' is passed (out of scope) up to caller!
+ run_podman inspect --format "{{.Image}}" $cname
+ ori_image=$output
+}
+
+function _wait_service_ready() {
+ local sname=$1
+
+ local timeout=6
+ while [[ $timeout -gt 1 ]]; do
+ if systemctl -q is-active $sname; then
+ return
+ fi
+ sleep 1
+ let timeout=$timeout-1
+ done
+
+ # Print serivce status as debug information before failed the case
+ systemctl status $sname
+ die "Timed out waiting for $sname to start"
+}
+
+# Wait for container to update, as confirmed by its image ID changing
+function _confirm_update() {
+ local cname=$1
+ local old_iid=$2
+
+ # Image has already been pulled, so this shouldn't take too long
+ local timeout=5
+ while [[ $timeout -gt 0 ]]; do
+ run_podman '?' inspect --format "{{.Image}}" $cname
+ if [[ $status != 0 ]]; then
+ if [[ $output =~ (no such object|does not exist in database): ]]; then
+ # this is ok, it just means the container is being restarted
+ :
+ else
+ die "podman inspect $cname failed unexpectedly"
+ fi
+ elif [[ $output != $old_iid ]]; then
+ return
+ fi
+ sleep 1
+ done
+
+ die "Timed out waiting for $cname to update; old IID=$old_iid"
+}
+
+# This test can fail in dev. environment because of SELinux.
+# quick fix: chcon -t container_runtime_exec_t ./bin/podman
+@test "podman auto-update - label io.containers.autoupdate=image" {
+ generate_service alpine image
+
+ _wait_service_ready container-$cname.service
+ run_podman auto-update
+ is "$output" "Trying to pull.*" "Image is updated."
+ _confirm_update $cname $ori_image
+}
+
+@test "podman auto-update - label io.containers.autoupdate=disabled" {
+ generate_service alpine disabled
+
+ _wait_service_ready container-$cname.service
+ run_podman auto-update
+ is "$output" "" "Image is not updated when autoupdate=disabled."
+
+ run_podman inspect --format "{{.Image}}" $cname
+ is "$output" "$ori_image" "Image ID should not change"
+}
+
+@test "podman auto-update - label io.containers.autoupdate=fakevalue" {
+ fakevalue=fake_$(random_string)
+ generate_service alpine $fakevalue
+
+ _wait_service_ready container-$cname.service
+ run_podman 125 auto-update
+ is "$output" ".*invalid auto-update policy.*" "invalid policy setup"
+
+ run_podman inspect --format "{{.Image}}" $cname
+ is "$output" "$ori_image" "Image ID should not change"
+}
+
+@test "podman auto-update - label io.containers.autoupdate=local" {
+ generate_service localtest local
+ podman commit --change CMD=/bin/bash $cname quay.io/libpod/localtest:latest
+
+ _wait_service_ready container-$cname.service
+ run_podman auto-update
+ _confirm_update $cname $ori_image
+}
+
+@test "podman auto-update with multiple services" {
+ # Preserve original image ID, to confirm that it changes (or not)
+ run_podman inspect --format "{{.Id}}" $IMAGE
+ local img_id="$output"
+
+ local cnames=()
+ local -A expect_update
+ local -A will_update=([image]=1 [registry]=1 [local]=1)
+
+ local fakevalue=fake_$(random_string)
+ for auto_update in image registry "" disabled "''" $fakevalue local
+ do
+ local img_base="alpine"
+ if [[ $auto_update == "registry" ]]; then
+ img_base="alpine_nginx"
+ elif [[ $auto_update == "local" ]]; then
+ img_base="localtest"
+ fi
+ generate_service $img_base $auto_update
+ cnames+=($cname)
+ if [[ $auto_update == "local" ]]; then
+ local_cname=$cname
+ fi
+
+ if [[ -n "$auto_update" && -n "${will_update[$auto_update]}" ]]; then
+ expect_update[$cname]=1
+ fi
+ done
+
+ # Only check the last service is started. Previous services should already actived.
+ _wait_service_ready container-$cname.service
+ run_podman commit --change CMD=/bin/bash $local_cname quay.io/libpod/localtest:latest
+ # Exit code is expected, due to invalid 'fakevalue'
+ run_podman 125 auto-update
+ update_log=$output
+ is "$update_log" ".*invalid auto-update policy.*" "invalid policy setup"
+ is "$update_log" ".*1 error occurred.*" "invalid policy setup"
+
+ local n_updated=$(grep -c 'Trying to pull' <<<"$update_log")
+ is "$n_updated" "2" "Number of images updated from registry."
+
+ for cname in "${!expect_update[@]}"; do
+ is "$update_log" ".*$cname.*" "container with auto-update policy image updated"
+ # Just because podman says it fetched, doesn't mean it actually updated
+ _confirm_update $cname $img_id
+ done
+
+ # Final confirmation that all image IDs have/haven't changed
+ for cname in "${cnames[@]}"; do
+ run_podman inspect --format "{{.Image}}" $cname
+ if [[ -n "${expect_update[$cname]}" ]]; then
+ if [[ "$output" == "$img_id" ]]; then
+ die "$cname: image ID ($output) did not change"
+ fi
+ else
+ is "$output" "$img_id" "Image should not be changed."
+ fi
+ done
+}
+
+@test "podman auto-update using systemd" {
+ generate_service alpine image
+
+ cat >$UNIT_DIR/podman-auto-update-$cname.timer <<EOF
+[Unit]
+Description=Podman auto-update testing timer
+
+[Timer]
+OnCalendar=*-*-* *:*:0/2
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+EOF
+ cat >$UNIT_DIR/podman-auto-update-$cname.service <<EOF
+[Unit]
+Description=Podman auto-update testing service
+Documentation=man:podman-auto-update(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/podman auto-update
+
+[Install]
+WantedBy=multi-user.target default.target
+EOF
+
+ echo "podman-auto-update-$cname" >> $SNAME_FILE
+ systemctl enable --now podman-auto-update-$cname.timer
+ systemctl list-timers --all
+
+ local expect='Finished Podman auto-update testing service'
+ local failed_start=failed
+ local count=0
+ while [ $count -lt 120 ]; do
+ run journalctl -n 15 -u podman-auto-update-$cname.service
+ if [[ "$output" =~ $expect ]]; then
+ failed_start=
+ break
+ fi
+ ((count+=1))
+ sleep 1
+ done
+
+ if [[ -n "$failed_start" ]]; then
+ die "Did not find expected string '$expect' in journalctl output for $cname"
+ fi
+
+ _confirm_update $cname $ori_image
+}
+
+# vim: filetype=sh
diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md
index 7a0af9298..ab704400f 100644
--- a/vendor/github.com/containers/buildah/CHANGELOG.md
+++ b/vendor/github.com/containers/buildah/CHANGELOG.md
@@ -1,6 +1,9 @@
![buildah logo](https://cdn.rawgit.com/containers/buildah/master/logos/buildah-logo_large.png)
# Changelog
+## v1.21.1 (2021-06-02)
+ Fix handling of auth.json file while in a user namespace
+
## v1.21.0 (2021-05-19)
Don't blow up if cpp detects errors
Vendor in containers/common v0.38.4
diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt
index 3bde05a3e..ee0e9b61f 100644
--- a/vendor/github.com/containers/buildah/changelog.txt
+++ b/vendor/github.com/containers/buildah/changelog.txt
@@ -1,3 +1,6 @@
+- Changelog for v1.21.1 (2021-06-03)
+ * Fix handling of auth.json file while in a user namespace
+
- Changelog for v1.21.0 (2021-05-19)
* Don't blow up if cpp detects errors
* Vendor in containers/common v0.38.4
diff --git a/vendor/github.com/containers/buildah/define/types.go b/vendor/github.com/containers/buildah/define/types.go
index f2327e8df..ac2071b37 100644
--- a/vendor/github.com/containers/buildah/define/types.go
+++ b/vendor/github.com/containers/buildah/define/types.go
@@ -28,7 +28,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.21.0"
+ Version = "1.21.1"
// DefaultRuntime if containers.conf fails.
DefaultRuntime = "runc"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 786096f45..a00f1becc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -77,7 +77,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr
github.com/containernetworking/plugins/pkg/utils/sysctl
github.com/containernetworking/plugins/plugins/ipam/host-local/backend
github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator
-# github.com/containers/buildah v1.21.0
+# github.com/containers/buildah v1.21.1
github.com/containers/buildah
github.com/containers/buildah/bind
github.com/containers/buildah/chroot
diff --git a/version/version.go b/version/version.go
index 1cbd9e309..71292305d 100644
--- a/version/version.go
+++ b/version/version.go
@@ -27,7 +27,7 @@ const (
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-var Version = semver.MustParse("3.2.0-dev")
+var Version = semver.MustParse("3.3.0-dev")
// See https://docs.docker.com/engine/api/v1.40/
// libpod compat handlers are expected to honor docker API versions