diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 17 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 13 | ||||
-rw-r--r-- | cmd/podman/containers/run.go | 2 | ||||
-rw-r--r-- | cmd/podman/system/service.go | 5 | ||||
-rw-r--r-- | docs/source/markdown/podman-generate-systemd.1.md | 12 | ||||
-rw-r--r-- | libpod/define/errors.go | 13 | ||||
-rw-r--r-- | libpod/image/errors.go | 11 | ||||
-rw-r--r-- | libpod/oci_conmon_exec_linux.go | 17 | ||||
-rw-r--r-- | pkg/api/server/register_ping.go | 9 | ||||
-rw-r--r-- | pkg/specgen/generate/namespaces.go | 4 | ||||
-rw-r--r-- | test/apiv2/01-basic.at | 8 | ||||
-rw-r--r-- | test/apiv2/rest_api/test_rest_v1_0_0.py | 21 | ||||
-rw-r--r-- | test/e2e/run_test.go | 6 | ||||
-rw-r--r-- | utils/utils.go | 3 |
15 files changed, 92 insertions, 51 deletions
@@ -5,7 +5,7 @@ Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers. Podman is based on libpod, a library for container lifecycle management that is also contained in this repository. The libpod library provides APIs for managing containers, pods, container images, and volumes. -* [Latest Version: 2.0.3](https://github.com/containers/podman/releases/latest) +* [Latest Version: 2.0.4](https://github.com/containers/podman/releases/latest) * Latest Remote client for Windows * Latest Remote client for MacOs * Latest Static Remote client for Linux diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 48fe68ef9..d6b0eb3dd 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,22 @@ # Release Notes +## 2.0.4 +### Bugfixes +- Fixed a bug where the output of `podman image search` did not populate the Description field as it was mistakenly assigned to the ID field. +- Fixed a bug where `podman build -` and `podman build` on an HTTP target would fail. +- Fixed a bug where rootless Podman would improperly chown the copied-up contents of anonymous volumes ([#7130](https://github.com/containers/podman/issues/7130)). +- Fixed a bug where Podman would sometimes HTML-escape special characters in its CLI output. +- Fixed a bug where the `podman start --attach --interactive` command would print the container ID of the container attached to when exiting ([#7068](https://github.com/containers/podman/pull/7068)). +- Fixed a bug where `podman run --ipc=host --pid=host` would only set `--pid=host` and not `--ipc=host` ([#7100](https://github.com/containers/podman/issues/7100)). +- Fixed a bug where the `--publish` argument to `podman run`, `podman create` and `podman pod create` would not allow binding the same container port to more than one host port ([#7062](https://github.com/containers/podman/issues/7062)). +- Fixed a bug where incorrect arguments to `podman images --format` could cause Podman to segfault. +- Fixed a bug where `podman rmi --force` on an image ID with more than one name and at least one container using the image would not completely remove containers using the image ([#7153](https://github.com/containers/podman/issues/7153)). +- Fixed a bug where memory usage in bytes and memory use percentage were swapped in the output of `podman stats --format=json`. + +### API +- Fixed a bug where the libpod and compat events endpoints would fail if no filters were specified ([#7078](https://github.com/containers/podman/issues/7078)). +- Fixed a bug where the `CgroupVersion` field in responses from the compat Info endpoint was prefixed by "v" (instead of just being "1" or "2", as is documented). + ## 2.0.3 ### Features - The `podman search` command now allows wildcards in search terms. diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index dd77dc9d7..1516d15e9 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -124,7 +124,7 @@ func create(cmd *cobra.Command, args []string) error { return err } - if _, err := createPodIfNecessary(s); err != nil { + if _, err := createPodIfNecessary(s, cliVals.Net); err != nil { return err } @@ -283,7 +283,7 @@ func openCidFile(cidfile string) (*os.File, error) { // createPodIfNecessary automatically creates a pod when requested. if the pod name // has the form new:ID, the pod ID is created and the name in the spec generator is replaced // with ID. -func createPodIfNecessary(s *specgen.SpecGenerator) (*entities.PodCreateReport, error) { +func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions) (*entities.PodCreateReport, error) { if !strings.HasPrefix(s.Pod, "new:") { return nil, nil } @@ -292,11 +292,10 @@ func createPodIfNecessary(s *specgen.SpecGenerator) (*entities.PodCreateReport, return nil, errors.Errorf("new pod name must be at least one character") } createOptions := entities.PodCreateOptions{ - Name: podName, - Infra: true, - Net: &entities.NetOptions{ - PublishPorts: s.PortMappings, - }, + Name: podName, + Infra: true, + Net: netOpts, + CreateCommand: os.Args, } s.Pod = podName return registry.ContainerEngine().PodCreate(context.Background(), createOptions) diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 646c52645..d26aed826 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -176,7 +176,7 @@ func run(cmd *cobra.Command, args []string) error { } runOpts.Spec = s - if _, err := createPodIfNecessary(s); err != nil { + if _, err := createPodIfNecessary(s, cliVals.Net); err != nil { return err } diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go index 2d511f0ec..7c692b07e 100644 --- a/cmd/podman/system/service.go +++ b/cmd/podman/system/service.go @@ -49,7 +49,7 @@ func init() { flags := srvCmd.Flags() flags.Int64VarP(&srvArgs.Timeout, "time", "t", 5, "Time until the service session expires in seconds. Use 0 to disable the timeout") - flags.BoolVar(&srvArgs.Varlink, "varlink", false, "Use legacy varlink service instead of REST") + flags.BoolVar(&srvArgs.Varlink, "varlink", false, "Use legacy varlink service instead of REST. Unit of --time changes from seconds to milliseconds.") _ = flags.MarkDeprecated("varlink", "valink API is deprecated.") flags.SetNormalizeFunc(aliasTimeoutFlag) @@ -88,14 +88,15 @@ func service(cmd *cobra.Command, args []string) error { opts := entities.ServiceOptions{ URI: apiURI, - Timeout: time.Duration(srvArgs.Timeout) * time.Second, Command: cmd, } if srvArgs.Varlink { + opts.Timeout = time.Duration(srvArgs.Timeout) * time.Millisecond return registry.ContainerEngine().VarlinkService(registry.GetContext(), opts) } + opts.Timeout = time.Duration(srvArgs.Timeout) * time.Second return restService(opts, cmd.Flags(), registry.PodmanConfig()) } diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 466c7e2bf..d0b1b3588 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -149,9 +149,9 @@ WantedBy=multi-user.target default.target Podman-generated unit files include an `[Install]` section, which carries installation information for the unit. It is used by the enable and disable commands of systemctl(1) during installation. -Once you have generated the systemd unit file, you can copy the generated systemd file to ```/usr/lib/systemd/system``` for installing as a root user and to ```$HOME/.config/systemd/user ``` for installing it as a non-root user. Enable the copied unit file or files using `systemctl enable`. +Once you have generated the systemd unit file, you can copy the generated systemd file to ```/etc/systemd/system``` for installing as a root user and to ```$HOME/.config/systemd/user``` for installing it as a non-root user. Enable the copied unit file or files using `systemctl enable`. -Note: Coping unit files to ```/usr/lib/systemd/system``` and enabling it marks the unit file to be automatically started at boot. And smillarly, coping a unit file to ```$HOME/.config/systemd/user ``` and enabling it marks the unit file to be automatically started on user login. +Note: Coping unit files to ```/etc/systemd/system``` and enabling it marks the unit file to be automatically started at boot. And smillarly, coping a unit file to ```$HOME/.config/systemd/user``` and enabling it marks the unit file to be automatically started on user login. ``` @@ -162,14 +162,14 @@ $ podman generate systemd --files --name systemd-pod # Copy all the generated files. -$ sudo cp pod-systemd-pod.service container-great_payne.service /usr/lib/systemd/system +$ sudo cp pod-systemd-pod.service container-great_payne.service /etc/systemd/system $ systemctl enable pod-systemd-pod.service -Created symlink /etc/systemd/system/multi-user.target.wants/pod-systemd-pod.service → /usr/lib/systemd/system/pod-systemd-pod.service. -Created symlink /etc/systemd/system/default.target.wants/pod-systemd-pod.service → /usr/lib/systemd/system/pod-systemd-pod.service. +Created symlink /etc/systemd/system/multi-user.target.wants/pod-systemd-pod.service → /etc/systemd/system/pod-systemd-pod.service. +Created symlink /etc/systemd/system/default.target.wants/pod-systemd-pod.service → /etc/systemd/system/pod-systemd-pod.service. $ systemctl is-enabled pod-systemd-pod.service enabled ``` -To run the user services placed in `$HOME/.config/systemd/user/` on first login of that user, enable the service with --user flag. +To run the user services placed in `$HOME/.config/systemd/user` on first login of that user, enable the service with --user flag. ``` $ systemctl --user enable <.service> diff --git a/libpod/define/errors.go b/libpod/define/errors.go index 23d10f527..4a0df3983 100644 --- a/libpod/define/errors.go +++ b/libpod/define/errors.go @@ -2,23 +2,20 @@ package define import ( "errors" - - "github.com/containers/podman/v2/libpod/image" - "github.com/containers/podman/v2/utils" ) var ( // ErrNoSuchCtr indicates the requested container does not exist - ErrNoSuchCtr = image.ErrNoSuchCtr + ErrNoSuchCtr = errors.New("no such container") // ErrNoSuchPod indicates the requested pod does not exist - ErrNoSuchPod = image.ErrNoSuchPod + ErrNoSuchPod = errors.New("no such pod") // ErrNoSuchImage indicates the requested image does not exist - ErrNoSuchImage = image.ErrNoSuchImage + ErrNoSuchImage = errors.New("no such image") // ErrNoSuchTag indicates the requested image tag does not exist - ErrNoSuchTag = image.ErrNoSuchTag + ErrNoSuchTag = errors.New("no such tag") // ErrNoSuchVolume indicates the requested volume does not exist ErrNoSuchVolume = errors.New("no such volume") @@ -76,7 +73,7 @@ var ( // ErrDetach indicates that an attach session was manually detached by // the user. - ErrDetach = utils.ErrDetach + ErrDetach = errors.New("detached from container") // ErrWillDeadlock indicates that the requested operation will cause a // deadlock. This is usually caused by upgrade issues, and is resolved diff --git a/libpod/image/errors.go b/libpod/image/errors.go index ddbf7be4b..3f58b1c6a 100644 --- a/libpod/image/errors.go +++ b/libpod/image/errors.go @@ -1,17 +1,16 @@ package image import ( - "errors" + "github.com/containers/podman/v2/libpod/define" ) -// Copied directly from libpod errors to avoid circular imports var ( // ErrNoSuchCtr indicates the requested container does not exist - ErrNoSuchCtr = errors.New("no such container") + ErrNoSuchCtr = define.ErrNoSuchCtr // ErrNoSuchPod indicates the requested pod does not exist - ErrNoSuchPod = errors.New("no such pod") + ErrNoSuchPod = define.ErrNoSuchPod // ErrNoSuchImage indicates the requested image does not exist - ErrNoSuchImage = errors.New("no such image") + ErrNoSuchImage = define.ErrNoSuchImage // ErrNoSuchTag indicates the requested image tag does not exist - ErrNoSuchTag = errors.New("no such tag") + ErrNoSuchTag = define.ErrNoSuchTag ) diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go index f8d87759a..cfe3745fa 100644 --- a/libpod/oci_conmon_exec_linux.go +++ b/libpod/oci_conmon_exec_linux.go @@ -449,9 +449,12 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex return nil, nil, err } + var filesToClose []*os.File if options.PreserveFDs > 0 { for fd := 3; fd < int(3+options.PreserveFDs); fd++ { - execCmd.ExtraFiles = append(execCmd.ExtraFiles, os.NewFile(uintptr(fd), fmt.Sprintf("fd-%d", fd))) + f := os.NewFile(uintptr(fd), fmt.Sprintf("fd-%d", fd)) + filesToClose = append(filesToClose, f) + execCmd.ExtraFiles = append(execCmd.ExtraFiles, f) } } @@ -483,14 +486,10 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex return nil, nil, err } - if options.PreserveFDs > 0 { - for fd := 3; fd < int(3+options.PreserveFDs); fd++ { - // These fds were passed down to the runtime. Close them - // and not interfere - if err := os.NewFile(uintptr(fd), fmt.Sprintf("fd-%d", fd)).Close(); err != nil { - logrus.Debugf("unable to close file fd-%d", fd) - } - } + // These fds were passed down to the runtime. Close them + // and not interfere + for _, f := range filesToClose { + errorhandling.CloseQuiet(f) } return execCmd, pipes, nil diff --git a/pkg/api/server/register_ping.go b/pkg/api/server/register_ping.go index 4a8d2c768..4e299008c 100644 --- a/pkg/api/server/register_ping.go +++ b/pkg/api/server/register_ping.go @@ -9,9 +9,8 @@ import ( func (s *APIServer) registerPingHandlers(r *mux.Router) error { - r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet) - r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodHead) - + r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) + r.Handle(VersionedPath("/_ping"), s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) // swagger:operation GET /libpod/_ping libpod libpodPingGet // --- // summary: Ping service @@ -62,7 +61,7 @@ func (s *APIServer) registerPingHandlers(r *mux.Router) error { // determine if talking to Podman engine or another engine // 500: // $ref: "#/responses/InternalError" - r.Handle("/libpod/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet) - r.Handle("/libpod/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodHead) + r.Handle("/libpod/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) + r.Handle(VersionedPath("/libpod/_ping"), s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) return nil } diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index b8ab1399e..7adb8be6a 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -462,6 +462,10 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt func GetNamespaceOptions(ns []string) ([]libpod.PodCreateOption, error) { var options []libpod.PodCreateOption var erroredOptions []libpod.PodCreateOption + if ns == nil { + //set the default namespaces + ns = strings.Split(specgen.DefaultKernelNamespaces, ",") + } for _, toShare := range ns { switch toShare { case "cgroup": diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at index 79dac990a..96b6aef7c 100644 --- a/test/apiv2/01-basic.at +++ b/test/apiv2/01-basic.at @@ -5,9 +5,15 @@ # NOTE: paths with a leading slash will be interpreted as-is; # paths without will have '/v1.40/' prepended. -t GET /_ping 200 OK +t GET /_ping 200 OK t HEAD /_ping 200 t GET /libpod/_ping 200 OK +t HEAD /libpod/_ping 200 + +t GET _ping 200 OK +t HEAD _ping 200 +t GET libpod/_ping 200 OK +t HEAD libpod/_ping 200 for i in /version version; do t GET $i 200 \ diff --git a/test/apiv2/rest_api/test_rest_v1_0_0.py b/test/apiv2/rest_api/test_rest_v1_0_0.py index 7c53623cb..2e574e015 100644 --- a/test/apiv2/rest_api/test_rest_v1_0_0.py +++ b/test/apiv2/rest_api/test_rest_v1_0_0.py @@ -13,9 +13,11 @@ from multiprocessing import Process import requests from dateutil.parser import parse +PODMAN_URL = "http://localhost:8080" + def _url(path): - return "http://localhost:8080/v1.0.0/libpod" + path + return PODMAN_URL + "/v1.0.0/libpod" + path def podman(): @@ -205,7 +207,21 @@ class TestApi(unittest.TestCase): search.join(timeout=10) self.assertFalse(search.is_alive(), "/images/search took too long") - def validateObjectFields(self, buffer): + def test_ping(self): + r = requests.get(PODMAN_URL + "/_ping") + self.assertEqual(r.status_code, 200, r.text) + + r = requests.head(PODMAN_URL + "/_ping") + self.assertEqual(r.status_code, 200, r.text) + + r = requests.get(_url("/_ping")) + self.assertEqual(r.status_code, 200, r.text) + + r = requests.get(_url("/_ping")) + self.assertEqual(r.status_code, 200, r.text) + + +def validateObjectFields(self, buffer): objs = json.loads(buffer) if not isinstance(objs, dict): for o in objs: @@ -214,6 +230,5 @@ class TestApi(unittest.TestCase): _ = objs["Id"] return objs - if __name__ == '__main__': unittest.main() diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 1f9cc3cb0..6bb12b54a 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -812,7 +812,11 @@ USER mail` }) It("podman run --pod automatically", func() { - session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8080"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8080"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/utils/utils.go b/utils/utils.go index 27ce1821d..a6ef663d7 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" + "github.com/containers/podman/v2/libpod/define" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -51,7 +52,7 @@ func ExecCmdWithStdStreams(stdin io.Reader, stdout, stderr io.Writer, env []stri // ErrDetach is an error indicating that the user manually detached from the // container. -var ErrDetach = errors.New("detached from container") +var ErrDetach = define.ErrDetach // CopyDetachable is similar to io.Copy but support a detach key sequence to break out. func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) { |