summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--cmd/podman/common/create.go16
-rw-r--r--cmd/podman/machine/set.go2
-rw-r--r--cmd/podman/play/kube.go14
-rwxr-xr-xcontrib/cirrus/runner.sh12
-rw-r--r--docs/source/markdown/podman-container-clone.1.md6
-rw-r--r--docs/source/markdown/podman-machine-set.1.md4
-rw-r--r--go.mod1
-rw-r--r--go.sum3
-rwxr-xr-xhack/make-and-check-size30
-rw-r--r--libpod/container_path_resolution.go1
-rw-r--r--libpod/doc.go11
-rw-r--r--libpod/oci_conmon_exec_linux.go7
-rw-r--r--libpod/oci_conmon_linux.go6
-rw-r--r--nix/default-arm64.nix90
-rw-r--r--nix/default.nix88
-rw-r--r--nix/nixpkgs.json10
-rw-r--r--nix/nixpkgs.nix9
-rw-r--r--pkg/api/handlers/libpod/manifests.go2
-rw-r--r--pkg/api/handlers/libpod/play.go53
-rw-r--r--pkg/bindings/manifests/manifests.go64
-rw-r--r--pkg/bindings/play/play.go39
-rw-r--r--pkg/domain/entities/engine_container.go4
-rw-r--r--pkg/domain/infra/abi/containers.go29
-rw-r--r--pkg/domain/infra/abi/play.go28
-rw-r--r--pkg/domain/infra/tunnel/play.go9
-rw-r--r--pkg/machine/qemu/machine.go22
-rw-r--r--pkg/specgen/generate/container.go4
-rw-r--r--pkg/specgen/generate/security.go7
-rw-r--r--podman.spec.rpkg5
-rw-r--r--test/e2e/container_clone_test.go37
-rw-r--r--test/e2e/run_test.go6
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go28
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go111
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go31
-rw-r--r--vendor/modules.txt3
36 files changed, 404 insertions, 406 deletions
diff --git a/Makefile b/Makefile
index bef6b4b91..af9a2b7f6 100644
--- a/Makefile
+++ b/Makefile
@@ -292,7 +292,7 @@ validate: gofmt lint .gitvalidation validate.completions man-page-check swagger-
.PHONY: build-all-new-commits
build-all-new-commits:
# Validate that all the commits build on top of $(GIT_BASE_BRANCH)
- git rebase $(GIT_BASE_BRANCH) -x make
+ git rebase $(GIT_BASE_BRANCH) -x "$(MAKE)"
.PHONY: vendor
vendor:
@@ -435,22 +435,6 @@ local-cross: $(CROSS_BUILD_TARGETS) ## Cross compile podman binary for multiple
.PHONY: cross
cross: local-cross
-# Update nix/nixpkgs.json its latest stable commit
-.PHONY: nixpkgs
-nixpkgs:
- @nix run \
- -f channel:nixos-21.05 nix-prefetch-git \
- -c nix-prefetch-git \
- --no-deepClone \
- https://github.com/nixos/nixpkgs refs/heads/nixos-21.05 > nix/nixpkgs.json
-
-# Build statically linked binary
-.PHONY: static
-static:
- @nix build -f nix/
- mkdir -p ./bin
- cp -rfp ./result/bin/* ./bin/
-
.PHONY: build-no-cgo
build-no-cgo:
BUILDTAGS="containers_image_openpgp exclude_graphdriver_btrfs \
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 8d9a255ec..afaa1942e 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -394,14 +394,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
- podFlagName := "pod"
- createFlags.StringVar(
- &cf.Pod,
- podFlagName, "",
- "Run container in an existing pod",
- )
- _ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
-
podIDFileFlagName := "pod-id-file"
createFlags.StringVar(
&cf.PodIDFile,
@@ -837,6 +829,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
+ podFlagName := "pod"
+ createFlags.StringVar(
+ &cf.Pod,
+ podFlagName, "",
+ "Run container in an existing pod",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
+
cpuPeriodFlagName := "cpu-period"
createFlags.Uint64Var(
&cf.CPUPeriod,
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index 4a05a9c1c..4c15f1de1 100644
--- a/cmd/podman/machine/set.go
+++ b/cmd/podman/machine/set.go
@@ -17,7 +17,7 @@ var (
Long: "Sets an updatable virtual machine setting",
RunE: setMachine,
Args: cobra.MaximumNArgs(1),
- Example: `podman machine set --root=false`,
+ Example: `podman machine set --rootful=false`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index 3067f0d54..e92516eb4 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -209,10 +209,15 @@ func teardown(yamlfile string) error {
podRmErrors utils.OutputErrors
)
options := new(entities.PlayKubeDownOptions)
- reports, err := registry.ContainerEngine().PlayKubeDown(registry.GetContext(), yamlfile, *options)
+ f, err := os.Open(yamlfile)
if err != nil {
return err
}
+ defer f.Close()
+ reports, err := registry.ContainerEngine().PlayKubeDown(registry.GetContext(), f, *options)
+ if err != nil {
+ return errors.Wrap(err, yamlfile)
+ }
// Output stopped pods
fmt.Println("Pods stopped:")
@@ -242,10 +247,15 @@ func teardown(yamlfile string) error {
}
func playkube(yamlfile string) error {
- report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), yamlfile, kubeOptions.PlayKubeOptions)
+ f, err := os.Open(yamlfile)
if err != nil {
return err
}
+ defer f.Close()
+ report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), f, kubeOptions.PlayKubeOptions)
+ if err != nil {
+ return errors.Wrap(err, yamlfile)
+ }
// Print volumes report
for i, volume := range report.Volumes {
if i == 0 {
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index 1bff07203..f33c6af29 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -228,7 +228,17 @@ function _run_altbuild() {
case "$ALT_NAME" in
*Each*)
git fetch origin
- make build-all-new-commits GIT_BASE_BRANCH=origin/$DEST_BRANCH
+ # The check-size script, introduced 2022-03-22 in #13518,
+ # runs 'make' (the original purpose of this check) against
+ # each commit, then checks image sizes to make sure that
+ # none have grown beyond a given limit. That of course
+ # requires a baseline, which is why we use '^' to start
+ # with the *parent* commit of this PR, not the first commit.
+ context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
+ make build-all-new-commits \
+ GIT_BASE_BRANCH=origin/"${DEST_BRANCH}^" \
+ MAKE="hack/make-and-check-size $context_dir"
+ rm -rf $context_dir
;;
*Windows*)
make podman-remote-release-windows_amd64.zip
diff --git a/docs/source/markdown/podman-container-clone.1.md b/docs/source/markdown/podman-container-clone.1.md
index 870bf077c..eaf330373 100644
--- a/docs/source/markdown/podman-container-clone.1.md
+++ b/docs/source/markdown/podman-container-clone.1.md
@@ -141,6 +141,12 @@ If no memory limits are specified, the original container's will be used.
Set a custom name for the cloned container. The default if not specified is of the syntax: **<ORIGINAL_NAME>-clone**
+#### **--pod**=*name*
+
+Clone the container in an existing pod. It is helpful to move a container to an
+existing pod. The container will join the pod shared namespaces, losing its configuration
+that conflicts with the shared namespaces.
+
#### **--run**
When set to true, this flag runs the newly created container after the
diff --git a/docs/source/markdown/podman-machine-set.1.md b/docs/source/markdown/podman-machine-set.1.md
index ec89cfc28..a4918eacf 100644
--- a/docs/source/markdown/podman-machine-set.1.md
+++ b/docs/source/markdown/podman-machine-set.1.md
@@ -26,7 +26,9 @@ container execution. This option will also update the current podman
remote connection default if it is currently pointing at the specified
machine name (or `podman-machine-default` if no name is specified).
-API forwarding, if available, will follow this setting.
+Unlike [**podman system connection default**](podman-system-connection-default.1.md)
+this option will also make the API socket, if available, forward to the rootful/rootless
+socket in the VM.
## EXAMPLES
diff --git a/go.mod b/go.mod
index 224a4fe81..21d2fb989 100644
--- a/go.mod
+++ b/go.mod
@@ -54,6 +54,7 @@ require (
github.com/opencontainers/selinux v1.10.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
+ github.com/prometheus/client_golang v1.11.1 // indirect
github.com/rootless-containers/rootlesskit v0.14.6
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.4.0
diff --git a/go.sum b/go.sum
index eb78eb72a..49a22a413 100644
--- a/go.sum
+++ b/go.sum
@@ -1155,8 +1155,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
+github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
diff --git a/hack/make-and-check-size b/hack/make-and-check-size
index a6a77e8ca..71b382b44 100755
--- a/hack/make-and-check-size
+++ b/hack/make-and-check-size
@@ -2,28 +2,30 @@
#
# make-and-check-size - wrapper around 'make' that also checks binary growth
#
-# This script is intended to be run via 'git rebase -x', in a Makefile rule
-# such as:
+# This script is intended to be run via 'git rebase -x', in a form such as:
#
-# build-all-new-commits:
-# CONTEXT_DIR=$(shell mktemp -d --tmpdir make-size-check.XXXXXXX); \
-# git rebase $(GIT_BASE_BRANCH)^ -x "hack/make-and-check-size $$CONTEXT_DIR"; \
-# $(RM) -rf $$CONTEXT_DIR
+# context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
+# git rebase ${GIT_BASE_BRANCH}^ -x "hack/make-and-check-size $context_dir"
+# rm -rf $context_dir
#
-# ...which has long been a part of our usual CI, one that makes sure that
-# each commit (in a multi-commit PR) can be compiled individually. By
-# adding the '^' to GIT_BASE_BRANCH we establish a baseline and store
+# (Carefully note the '^' next to GIT_BASE_BRANCH!)
+#
+# A 'git rebase -x' has long been a part of our usual CI; it guarantees
+# that each commit (whether in a single- or multi-commit PR) can be
+# compiled individually.
+#
+# By adding the '^' to GIT_BASE_BRANCH we establish a baseline and store
# the binary sizes of each file (podman, podman-remote) prior to our PR.
#
-# CONTEXT_DIR is a temporary directory used to store the original sizes
+# context_dir is a temporary directory used to store the original sizes
# of each binary file under bin/
#
# *IMPORTANT NOTE*: this script will leave the git checkout in a funky state!
# (because we rebase onto a nonterminal commit). I believe this is OK, since
-# this makefile target is used only in CI and only in a scratch VM. Running
-# this in a development environment would yield unpredictable results anyway,
-# by rebasing onto origin/main by default and by leaving an aborted rebase
-# on failure.
+# this script is only invoked in CI from runner.sh and only in a scratch VM.
+# Running this in a development environment would yield unpredictable results
+# anyway, by rebasing onto origin/main by default and by leaving an aborted
+# rebase on failure.
#
ME=$(basename $0)
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index 7db23b783..80a3749f5 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -1,4 +1,3 @@
-// +linux
package libpod
import (
diff --git a/libpod/doc.go b/libpod/doc.go
new file mode 100644
index 000000000..948153181
--- /dev/null
+++ b/libpod/doc.go
@@ -0,0 +1,11 @@
+// The libpod library is not stable and we do not support use cases outside of
+// this repository. The API can change at any time even with patch releases.
+//
+// If you need a stable interface Podman provides a HTTP API which follows semver,
+// please see https://docs.podman.io/en/latest/markdown/podman-system-service.1.html
+// to start the api service and https://docs.podman.io/en/latest/_static/api.html
+// for the API reference.
+//
+// We also provide stable go bindings to talk to the api service from another go
+// program, see the pkg/bindings directory.
+package libpod
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index aa970bbde..65123b37e 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -758,11 +758,14 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio
} else {
pspec.Capabilities.Bounding = ctrSpec.Process.Capabilities.Bounding
}
+
+ // Always unset the inheritable capabilities similarly to what the Linux kernel does
+ // They are used only when using capabilities with uid != 0.
+ pspec.Capabilities.Inheritable = []string{}
+
if execUser.Uid == 0 {
pspec.Capabilities.Effective = pspec.Capabilities.Bounding
- pspec.Capabilities.Inheritable = pspec.Capabilities.Bounding
pspec.Capabilities.Permitted = pspec.Capabilities.Bounding
- pspec.Capabilities.Ambient = pspec.Capabilities.Bounding
} else {
if user == c.config.User {
pspec.Capabilities.Effective = ctrSpec.Process.Capabilities.Effective
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index ba4079bed..38bf85834 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1587,11 +1587,13 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int,
var si *syncInfo
rdr := bufio.NewReader(pipe)
b, err := rdr.ReadBytes('\n')
- if err != nil {
+ // ignore EOF here, error is returned even when data was read
+ // if it is no valid json unmarshal will fail below
+ if err != nil && !errors.Is(err, io.EOF) {
ch <- syncStruct{err: err}
}
if err := json.Unmarshal(b, &si); err != nil {
- ch <- syncStruct{err: err}
+ ch <- syncStruct{err: fmt.Errorf("conmon bytes %q: %w", string(b), err)}
return
}
ch <- syncStruct{si: si}
diff --git a/nix/default-arm64.nix b/nix/default-arm64.nix
deleted file mode 100644
index fa076f27d..000000000
--- a/nix/default-arm64.nix
+++ /dev/null
@@ -1,90 +0,0 @@
-let
- pkgs = (import ./nixpkgs.nix {
- crossSystem = {
- config = "aarch64-unknown-linux-gnu";
- };
- config = {
- packageOverrides = pkg: {
- gpgme = (static pkg.gpgme);
- libassuan = (static pkg.libassuan);
- libgpgerror = (static pkg.libgpgerror);
- libseccomp = (static pkg.libseccomp);
- glib = (static pkg.glib).overrideAttrs (x: {
- outputs = [ "bin" "out" "dev" ];
- mesonFlags = [
- "-Ddefault_library=static"
- "-Ddevbindir=${placeholder ''dev''}/bin"
- "-Dgtk_doc=false"
- "-Dnls=disabled"
- ];
- postInstall = ''
- moveToOutput "share/glib-2.0" "$dev"
- substituteInPlace "$dev/bin/gdbus-codegen" --replace "$out" "$dev"
- sed -i "$dev/bin/glib-gettextize" -e "s|^gettext_dir=.*|gettext_dir=$dev/share/glib-2.0/gettext|"
- sed '1i#line 1 "${x.pname}-${x.version}/include/glib-2.0/gobject/gobjectnotifyqueue.c"' \
- -i "$dev"/include/glib-2.0/gobject/gobjectnotifyqueue.c
- '';
- });
- pcsclite = (static pkg.pcsclite).overrideAttrs (x: {
- configureFlags = [
- "--enable-confdir=/etc"
- "--enable-usbdropdir=/var/lib/pcsc/drivers"
- "--disable-libsystemd"
- "--disable-libudev"
- "--disable-libusb"
- ];
- buildInputs = [ pkgs.python3 pkgs.dbus ];
- });
- systemd = (static pkg.systemd).overrideAttrs (x: {
- outputs = [ "out" "dev" ];
- mesonFlags = x.mesonFlags ++ [
- "-Dglib=false"
- "-Dstatic-libsystemd=true"
- ];
- });
- };
- };
- });
-
- static = pkg: pkg.overrideAttrs (x: {
- doCheck = false;
- configureFlags = (x.configureFlags or [ ]) ++ [
- "--without-shared"
- "--disable-shared"
- ];
- dontDisableStatic = true;
- enableSharedExecutables = false;
- enableStatic = true;
- });
-
- self = with pkgs; buildGoModule rec {
- name = "podman";
- src = builtins.filterSource
- (path: type: !(type == "directory" && baseNameOf path == "bin")) ./..;
- vendorSha256 = null;
- doCheck = false;
- enableParallelBuilding = true;
- outputs = [ "out" ];
- nativeBuildInputs = [ bash gitMinimal go-md2man pkg-config which ];
- buildInputs = [ glibc glibc.static glib gpgme libassuan libgpgerror libseccomp libapparmor libselinux ];
- prePatch = ''
- export CFLAGS='-static -pthread'
- export LDFLAGS='-s -w -static-libgcc -static'
- export EXTRA_LDFLAGS='-s -w -linkmode external -extldflags "-static -lm"'
- export BUILDTAGS='static netgo osusergo exclude_graphdriver_btrfs exclude_graphdriver_devicemapper seccomp apparmor selinux'
- export CGO_ENABLED=1
- '';
- buildPhase = ''
- patchShebangs .
- make bin/podman
- make bin/podman-remote
- make bin/rootlessport
- '';
- installPhase = ''
- install -Dm755 bin/podman $out/bin/podman
- install -Dm755 bin/podman-remote $out/bin/podman-remote
- install -Dm755 bin/rootlessport $out/libexec/podman/rootlessport
- '';
- };
-in
-self
diff --git a/nix/default.nix b/nix/default.nix
deleted file mode 100644
index 30ae21503..000000000
--- a/nix/default.nix
+++ /dev/null
@@ -1,88 +0,0 @@
-{ system ? builtins.currentSystem }:
-let
- pkgs = (import ./nixpkgs.nix {
- config = {
- packageOverrides = pkg: {
- gpgme = (static pkg.gpgme);
- libassuan = (static pkg.libassuan);
- libgpgerror = (static pkg.libgpgerror);
- libseccomp = (static pkg.libseccomp);
- glib = (static pkg.glib).overrideAttrs (x: {
- outputs = [ "bin" "out" "dev" ];
- mesonFlags = [
- "-Ddefault_library=static"
- "-Ddevbindir=${placeholder ''dev''}/bin"
- "-Dgtk_doc=false"
- "-Dnls=disabled"
- ];
- postInstall = ''
- moveToOutput "share/glib-2.0" "$dev"
- substituteInPlace "$dev/bin/gdbus-codegen" --replace "$out" "$dev"
- sed -i "$dev/bin/glib-gettextize" -e "s|^gettext_dir=.*|gettext_dir=$dev/share/glib-2.0/gettext|"
- sed '1i#line 1 "${x.pname}-${x.version}/include/glib-2.0/gobject/gobjectnotifyqueue.c"' \
- -i "$dev"/include/glib-2.0/gobject/gobjectnotifyqueue.c
- '';
- });
- pcsclite = (static pkg.pcsclite).overrideAttrs (x: {
- configureFlags = [
- "--enable-confdir=/etc"
- "--enable-usbdropdir=/var/lib/pcsc/drivers"
- "--disable-libsystemd"
- "--disable-libudev"
- "--disable-libusb"
- ];
- buildInputs = [ pkgs.python3 pkgs.dbus ];
- });
- systemd = (static pkg.systemd).overrideAttrs (x: {
- outputs = [ "out" "dev" ];
- mesonFlags = x.mesonFlags ++ [
- "-Dglib=false"
- "-Dstatic-libsystemd=true"
- ];
- });
- };
- };
- });
-
- static = pkg: pkg.overrideAttrs (x: {
- doCheck = false;
- configureFlags = (x.configureFlags or [ ]) ++ [
- "--without-shared"
- "--disable-shared"
- ];
- dontDisableStatic = true;
- enableSharedExecutables = false;
- enableStatic = true;
- });
-
- self = with pkgs; buildGoModule rec {
- name = "podman";
- src = builtins.filterSource
- (path: type: !(type == "directory" && baseNameOf path == "bin")) ./..;
- vendorSha256 = null;
- doCheck = false;
- enableParallelBuilding = true;
- outputs = [ "out" ];
- nativeBuildInputs = [ bash gitMinimal go-md2man pkg-config which ];
- buildInputs = [ glibc glibc.static glib gpgme libassuan libgpgerror libseccomp libapparmor libselinux ];
- prePatch = ''
- export CFLAGS='-static -pthread'
- export LDFLAGS='-s -w -static-libgcc -static'
- export EXTRA_LDFLAGS='-s -w -linkmode external -extldflags "-static -lm"'
- export BUILDTAGS='static netgo osusergo exclude_graphdriver_btrfs exclude_graphdriver_devicemapper seccomp apparmor selinux'
- export CGO_ENABLED=1
- '';
- buildPhase = ''
- patchShebangs .
- make bin/podman
- make bin/podman-remote
- make bin/rootlessport
- '';
- installPhase = ''
- install -Dm755 bin/podman $out/bin/podman
- install -Dm755 bin/podman-remote $out/bin/podman-remote
- install -Dm755 bin/rootlessport $out/libexec/podman/rootlessport
- '';
- };
-in
-self
diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json
deleted file mode 100644
index efcfe202e..000000000
--- a/nix/nixpkgs.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "url": "https://github.com/nixos/nixpkgs",
- "rev": "2a96414d7e350160a33ed0978449c9ff5b5a6eb3",
- "date": "2021-07-13T18:21:47+02:00",
- "path": "/nix/store/2ai9q8ac6vxb2rrngdz82y8jxnk15cvm-nixpkgs",
- "sha256": "1dzrfqdjq3yq5jjskiqflzy58l2xx6059gay9p1k07zrlm1wigy5",
- "fetchSubmodules": false,
- "deepClone": false,
- "leaveDotGit": false
-}
diff --git a/nix/nixpkgs.nix b/nix/nixpkgs.nix
deleted file mode 100644
index 11c20380a..000000000
--- a/nix/nixpkgs.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-let
- json = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
- nixpkgs = import (builtins.fetchTarball {
- name = "nixos-unstable";
- url = "${json.url}/archive/${json.rev}.tar.gz";
- inherit (json) sha256;
- });
-in
-nixpkgs
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 250736579..ad662f32c 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -401,7 +401,7 @@ func ManifestModify(w http.ResponseWriter, r *http.Request) {
case len(report.Errors) > 0 && len(report.Images) > 0:
statusCode = http.StatusConflict
case len(report.Errors) > 0:
- statusCode = http.StatusInternalServerError
+ statusCode = http.StatusBadRequest
}
utils.WriteResponse(w, statusCode, report)
}
diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go
index aed889298..ca9ada761 100644
--- a/pkg/api/handlers/libpod/play.go
+++ b/pkg/api/handlers/libpod/play.go
@@ -1,11 +1,8 @@
package libpod
import (
- "io"
- "io/ioutil"
"net"
"net/http"
- "os"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/libpod"
@@ -16,7 +13,6 @@ import (
"github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/gorilla/schema"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
func PlayKube(w http.ResponseWriter, r *http.Request) {
@@ -62,28 +58,6 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
staticMACs = append(staticMACs, mac)
}
- // Fetch the K8s YAML file from the body, and copy it to a temp file.
- tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
- if err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
- return
- }
- defer func() {
- if err := os.Remove(tmpfile.Name()); err != nil {
- logrus.Warn(err)
- }
- }()
- if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
- if err := tmpfile.Close(); err != nil {
- logrus.Warn(err)
- }
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
- return
- }
- if err := tmpfile.Close(); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
- return
- }
authConf, authfile, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, http.StatusBadRequest, err)
@@ -116,7 +90,8 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
if _, found := r.URL.Query()["start"]; found {
options.Start = types.NewOptionalBool(query.Start)
}
- report, err := containerEngine.PlayKube(r.Context(), tmpfile.Name(), options)
+ report, err := containerEngine.PlayKube(r.Context(), r.Body, options)
+ _ = r.Body.Close()
if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "error playing YAML file"))
return
@@ -126,30 +101,10 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
func PlayKubeDown(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
- if err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
- return
- }
- defer func() {
- if err := os.Remove(tmpfile.Name()); err != nil {
- logrus.Warn(err)
- }
- }()
- if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
- if err := tmpfile.Close(); err != nil {
- logrus.Warn(err)
- }
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
- return
- }
- if err := tmpfile.Close(); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
- return
- }
containerEngine := abi.ContainerEngine{Libpod: runtime}
options := new(entities.PlayKubeDownOptions)
- report, err := containerEngine.PlayKubeDown(r.Context(), tmpfile.Name(), *options)
+ report, err := containerEngine.PlayKubeDown(r.Context(), r.Body, *options)
+ _ = r.Body.Close()
if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "error tearing down YAML file"))
return
diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go
index 458cb913a..f7cd0d262 100644
--- a/pkg/bindings/manifests/manifests.go
+++ b/pkg/bindings/manifests/manifests.go
@@ -2,10 +2,9 @@ package manifests
import (
"context"
- "errors"
"fmt"
+ "io/ioutil"
"net/http"
- "net/url"
"strconv"
"strings"
@@ -14,8 +13,11 @@ import (
"github.com/containers/podman/v4/pkg/api/handlers"
"github.com/containers/podman/v4/pkg/bindings"
"github.com/containers/podman/v4/pkg/bindings/images"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/version"
jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
)
// Create creates a manifest for the given name. Optional images to be associated with
@@ -135,30 +137,8 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
func Remove(ctx context.Context, name, digest string, _ *RemoveOptions) (string, error) {
- if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) {
- optionsv4 := new(ModifyOptions).WithOperation("remove")
- return Modify(ctx, name, []string{digest}, optionsv4)
- }
-
- // API Version < 4.0.0
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return "", err
- }
-
- headers := http.Header{}
- headers.Add("API-Version", "3.4.0")
-
- params := url.Values{}
- params.Set("digest", digest)
- response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/manifests/%s", params, headers, name)
- if err != nil {
- return "", err
- }
- defer response.Body.Close()
-
- var idr handlers.IDResponse
- return idr.ID, response.Process(&idr)
+ optionsv4 := new(ModifyOptions).WithOperation("remove")
+ return Modify(ctx, name, []string{digest}, optionsv4)
}
// Push takes a manifest list and pushes to a destination. If the destination is not specified,
@@ -229,8 +209,36 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp
}
defer response.Body.Close()
- var idr handlers.IDResponse
- return idr.ID, response.Process(&idr)
+ data, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ return "", errors.Wrap(err, "unable to process API response")
+ }
+
+ if response.IsSuccess() || response.IsRedirection() {
+ var report entities.ManifestModifyReport
+ if err = jsoniter.Unmarshal(data, &report); err != nil {
+ return "", errors.Wrap(err, "unable to decode API response")
+ }
+
+ err = errorhandling.JoinErrors(report.Errors)
+ if err != nil {
+ errModel := errorhandling.ErrorModel{
+ Because: (errors.Cause(err)).Error(),
+ Message: err.Error(),
+ ResponseCode: response.StatusCode,
+ }
+ return report.ID, &errModel
+ }
+ return report.ID, nil
+ }
+
+ errModel := errorhandling.ErrorModel{
+ ResponseCode: response.StatusCode,
+ }
+ if err = jsoniter.Unmarshal(data, &errModel); err != nil {
+ return "", errors.Wrap(err, "unable to decode API response")
+ }
+ return "", &errModel
}
// Annotate modifies the given manifest list using options and the optional list of images
diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go
index d4018b6b3..8058a8514 100644
--- a/pkg/bindings/play/play.go
+++ b/pkg/bindings/play/play.go
@@ -2,6 +2,7 @@ package play
import (
"context"
+ "io"
"net/http"
"os"
"strconv"
@@ -14,20 +15,25 @@ import (
)
func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.PlayKubeReport, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return KubeWithBody(ctx, f, options)
+}
+
+func KubeWithBody(ctx context.Context, body io.Reader, options *KubeOptions) (*entities.PlayKubeReport, error) {
var report entities.PlayKubeReport
if options == nil {
options = new(KubeOptions)
}
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return nil, err
- }
- f, err := os.Open(path)
+ conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- defer f.Close()
params, err := options.ToParams()
if err != nil {
@@ -46,7 +52,7 @@ func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.Pla
return nil, err
}
- response, err := conn.DoRequest(ctx, f, http.MethodPost, "/play/kube", params, header)
+ response, err := conn.DoRequest(ctx, body, http.MethodPost, "/play/kube", params, header)
if err != nil {
return nil, err
}
@@ -60,12 +66,6 @@ func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.Pla
}
func KubeDown(ctx context.Context, path string) (*entities.PlayKubeReport, error) {
- var report entities.PlayKubeReport
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return nil, err
- }
-
f, err := os.Open(path)
if err != nil {
return nil, err
@@ -75,7 +75,18 @@ func KubeDown(ctx context.Context, path string) (*entities.PlayKubeReport, error
logrus.Warn(err)
}
}()
- response, err := conn.DoRequest(ctx, f, http.MethodDelete, "/play/kube", nil, nil)
+
+ return KubeDownWithBody(ctx, f)
+}
+
+func KubeDownWithBody(ctx context.Context, body io.Reader) (*entities.PlayKubeReport, error) {
+ var report entities.PlayKubeReport
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := conn.DoRequest(ctx, body, http.MethodDelete, "/play/kube", nil, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 7cf7ca17f..6b70a3452 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -68,8 +68,8 @@ type ContainerEngine interface {
NetworkPrune(ctx context.Context, options NetworkPruneOptions) ([]*NetworkPruneReport, error)
NetworkReload(ctx context.Context, names []string, options NetworkReloadOptions) ([]*NetworkReloadReport, error)
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
- PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error)
- PlayKubeDown(ctx context.Context, path string, opts PlayKubeDownOptions) (*PlayKubeReport, error)
+ PlayKube(ctx context.Context, body io.Reader, opts PlayKubeOptions) (*PlayKubeReport, error)
+ PlayKubeDown(ctx context.Context, body io.Reader, opts PlayKubeDownOptions) (*PlayKubeReport, error)
PodCreate(ctx context.Context, specg PodSpec) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 1986228a6..f45bdeba5 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -1496,6 +1496,35 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
return nil, err
}
+ if ctrCloneOpts.CreateOpts.Pod != "" {
+ pod, err := ic.Libpod.LookupPod(ctrCloneOpts.CreateOpts.Pod)
+ if err != nil {
+ return nil, err
+ }
+
+ allNamespaces := []struct {
+ isShared bool
+ value *specgen.Namespace
+ }{
+ {pod.SharesPID(), &spec.PidNS},
+ {pod.SharesNet(), &spec.NetNS},
+ {pod.SharesCgroup(), &spec.CgroupNS},
+ {pod.SharesIPC(), &spec.IpcNS},
+ {pod.SharesUTS(), &spec.UtsNS},
+ }
+
+ printWarning := false
+ for _, n := range allNamespaces {
+ if n.isShared && !n.value.IsDefault() {
+ *n.value = specgen.Namespace{NSMode: specgen.Default}
+ printWarning = true
+ }
+ }
+ if printWarning {
+ logrus.Warning("At least one namespace was reset to the default configuration")
+ }
+ }
+
err = specgenutil.FillOutSpecGen(spec, &ctrCloneOpts.CreateOpts, []string{})
if err != nil {
return nil, err
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 236d56053..1423ab06e 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -33,12 +33,12 @@ import (
yamlv2 "gopkg.in/yaml.v2"
)
-func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
+func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
report := &entities.PlayKubeReport{}
validKinds := 0
// read yaml document
- content, err := ioutil.ReadFile(path)
+ content, err := ioutil.ReadAll(body)
if err != nil {
return nil, err
}
@@ -52,7 +52,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
// sort kube kinds
documentList, err = sortKubeKinds(documentList)
if err != nil {
- return nil, errors.Wrapf(err, "unable to sort kube kinds in %q", path)
+ return nil, errors.Wrap(err, "unable to sort kube kinds")
}
ipIndex := 0
@@ -64,7 +64,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
for _, document := range documentList {
kind, err := getKubeKind(document)
if err != nil {
- return nil, errors.Wrapf(err, "unable to read %q as kube YAML", path)
+ return nil, errors.Wrap(err, "unable to read kube YAML")
}
switch kind {
@@ -73,7 +73,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
var podTemplateSpec v1.PodTemplateSpec
if err := yaml.Unmarshal(document, &podYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Pod", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube Pod")
}
podTemplateSpec.ObjectMeta = podYAML.ObjectMeta
@@ -97,7 +97,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
var deploymentYAML v1apps.Deployment
if err := yaml.Unmarshal(document, &deploymentYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Deployment", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube Deployment")
}
r, err := ic.playKubeDeployment(ctx, &deploymentYAML, options, &ipIndex, configMaps)
@@ -111,7 +111,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
var pvcYAML v1.PersistentVolumeClaim
if err := yaml.Unmarshal(document, &pvcYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube PersistentVolumeClaim", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube PersistentVolumeClaim")
}
r, err := ic.playKubePVC(ctx, &pvcYAML, options)
@@ -125,7 +125,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en
var configMap v1.ConfigMap
if err := yaml.Unmarshal(document, &configMap); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube ConfigMap", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube ConfigMap")
}
configMaps = append(configMaps, configMap)
default:
@@ -773,14 +773,14 @@ func getBuildFile(imageName string, cwd string) (string, error) {
return "", err
}
-func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
+func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
var (
podNames []string
)
reports := new(entities.PlayKubeReport)
// read yaml document
- content, err := ioutil.ReadFile(path)
+ content, err := ioutil.ReadAll(body)
if err != nil {
return nil, err
}
@@ -794,27 +794,27 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ enti
// sort kube kinds
documentList, err = sortKubeKinds(documentList)
if err != nil {
- return nil, errors.Wrapf(err, "unable to sort kube kinds in %q", path)
+ return nil, errors.Wrap(err, "unable to sort kube kinds")
}
for _, document := range documentList {
kind, err := getKubeKind(document)
if err != nil {
- return nil, errors.Wrapf(err, "unable to read %q as kube YAML", path)
+ return nil, errors.Wrap(err, "unable to read as kube YAML")
}
switch kind {
case "Pod":
var podYAML v1.Pod
if err := yaml.Unmarshal(document, &podYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Pod", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube Pod")
}
podNames = append(podNames, podYAML.ObjectMeta.Name)
case "Deployment":
var deploymentYAML v1apps.Deployment
if err := yaml.Unmarshal(document, &deploymentYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Deployment", path)
+ return nil, errors.Wrap(err, "unable to read YAML as Kube Deployment")
}
var numReplicas int32 = 1
deploymentName := deploymentYAML.ObjectMeta.Name
diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go
index cd51262d0..d9637254a 100644
--- a/pkg/domain/infra/tunnel/play.go
+++ b/pkg/domain/infra/tunnel/play.go
@@ -2,13 +2,14 @@ package tunnel
import (
"context"
+ "io"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/pkg/bindings/play"
"github.com/containers/podman/v4/pkg/domain/entities"
)
-func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
+func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
options := new(play.KubeOptions).WithAuthfile(opts.Authfile).WithUsername(opts.Username).WithPassword(opts.Password)
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Networks).WithSeccompProfileRoot(opts.SeccompProfileRoot)
@@ -26,9 +27,9 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entit
if start := opts.Start; start != types.OptionalBoolUndefined {
options.WithStart(start == types.OptionalBoolTrue)
}
- return play.Kube(ic.ClientCtx, path, options)
+ return play.KubeWithBody(ic.ClientCtx, body, options)
}
-func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
- return play.KubeDown(ic.ClientCtx, path)
+func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
+ return play.KubeDownWithBody(ic.ClientCtx, body)
}
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 3b14572a6..287b93612 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -98,7 +98,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
return nil, err
}
- cmd := append([]string{execPath})
+ cmd := []string{execPath}
// Add memory
cmd = append(cmd, []string{"-m", strconv.Itoa(int(vm.Memory))}...)
// Add cpus
@@ -430,13 +430,29 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
// Disable graphic window when not in debug mode
// Done in start, so we're not suck with the debug level we used on init
- if logrus.GetLevel() != logrus.DebugLevel {
+ if !logrus.IsLevelEnabled(logrus.DebugLevel) {
cmd = append(cmd, "-display", "none")
}
_, err = os.StartProcess(v.CmdLine[0], cmd, attr)
if err != nil {
- return err
+ // check if qemu was not found
+ if !errors.Is(err, os.ErrNotExist) {
+ return err
+ }
+ // lookup qemu again maybe the path was changed, https://github.com/containers/podman/issues/13394
+ cfg, err := config.Default()
+ if err != nil {
+ return err
+ }
+ cmd[0], err = cfg.FindHelperBinary(QemuCommand, true)
+ if err != nil {
+ return err
+ }
+ _, err = os.StartProcess(cmd[0], cmd, attr)
+ if err != nil {
+ return err
+ }
}
fmt.Println("Waiting for VM ...")
socketPath, err := getRuntimeDir()
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 64669f34d..0e9d33dd8 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -338,8 +338,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
}
// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an exisiting container
-func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID string) (*libpod.Container, error) {
- c, err := rt.LookupContainer(contaierID)
+func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, containerID string) (*libpod.Container, error) {
+ c, err := rt.LookupContainer(containerID)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 9c6709905..988c29832 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -146,6 +146,10 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
configSpec := g.Config
configSpec.Process.Capabilities.Ambient = []string{}
+
+ // Always unset the inheritable capabilities similarly to what the Linux kernel does
+ // They are used only when using capabilities with uid != 0.
+ configSpec.Process.Capabilities.Inheritable = []string{}
configSpec.Process.Capabilities.Bounding = caplist
user := strings.Split(s.User, ":")[0]
@@ -153,7 +157,6 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
if (user == "" && s.UserNS.NSMode != specgen.KeepID) || user == "root" || user == "0" {
configSpec.Process.Capabilities.Effective = caplist
configSpec.Process.Capabilities.Permitted = caplist
- configSpec.Process.Capabilities.Inheritable = caplist
} else {
mergedCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil)
if err != nil {
@@ -175,12 +178,12 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
}
configSpec.Process.Capabilities.Effective = userCaps
configSpec.Process.Capabilities.Permitted = userCaps
- configSpec.Process.Capabilities.Inheritable = userCaps
// Ambient capabilities were added to Linux 4.3. Set ambient
// capabilities only when the kernel supports them.
if supportAmbientCapabilities() {
configSpec.Process.Capabilities.Ambient = userCaps
+ configSpec.Process.Capabilities.Inheritable = userCaps
}
}
diff --git a/podman.spec.rpkg b/podman.spec.rpkg
index 41385dba6..937253918 100644
--- a/podman.spec.rpkg
+++ b/podman.spec.rpkg
@@ -144,10 +144,7 @@ Summary: (Experimental) Remote client for managing %{name} containers
%description remote
Remote client for managing %{name} containers.
-This experimental remote client is under heavy development. Please do not
-run %{name}-remote in production.
-
-%{name}-remote uses the version 2 API to connect to a %{name} client to
+%{name}-remote uses the libpod REST API to connect to a %{name} client to
manage pods, containers and container images. %{name}-remote supports ssh
connections as well.
diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go
index bebc6872b..a327bb8ed 100644
--- a/test/e2e/container_clone_test.go
+++ b/test/e2e/container_clone_test.go
@@ -184,4 +184,41 @@ var _ = Describe("Podman container clone", func() {
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Equal(runInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode))
})
+ It("podman container clone to a pod", func() {
+ createPod := podmanTest.Podman([]string{"pod", "create", "--share", "uts", "--name", "foo-pod"})
+ createPod.WaitWithDefaultTimeout()
+ Expect(createPod).To(Exit(0))
+
+ ctr := podmanTest.RunTopContainer("ctr")
+ ctr.WaitWithDefaultTimeout()
+ Expect(ctr).Should(Exit(0))
+
+ clone := podmanTest.Podman([]string{"container", "clone", "--name", "cloned", "--pod", "foo-pod", "ctr"})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ ctrInspect := podmanTest.Podman([]string{"inspect", "cloned"})
+ ctrInspect.WaitWithDefaultTimeout()
+ Expect(ctrInspect).Should(Exit(0))
+
+ Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
+
+ Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Not(ContainSubstring("container:")))
+
+ createPod = podmanTest.Podman([]string{"pod", "create", "--share", "uts,net", "--name", "bar-pod"})
+ createPod.WaitWithDefaultTimeout()
+ Expect(createPod).To(Exit(0))
+
+ clone = podmanTest.Podman([]string{"container", "clone", "--name", "cloned2", "--pod", "bar-pod", "ctr"})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ ctrInspect = podmanTest.Podman([]string{"inspect", "cloned2"})
+ ctrInspect.WaitWithDefaultTimeout()
+ Expect(ctrInspect).Should(Exit(0))
+
+ Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
+
+ Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(ContainSubstring("container:"))
+ })
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 91a2eddad..f4a6e5733 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -498,7 +498,7 @@ var _ = Describe("Podman run", func() {
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
+ Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
@@ -533,7 +533,7 @@ var _ = Describe("Podman run", func() {
session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
+ Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
if os.Geteuid() > 0 {
if os.Getenv("SKIP_USERNS") != "" {
@@ -550,7 +550,7 @@ var _ = Describe("Podman run", func() {
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
+ Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
session.WaitWithDefaultTimeout()
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
index 83c49b66a..861b4d21c 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
@@ -49,7 +49,10 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
// http.RoundTripper to observe the request result with the provided CounterVec.
// The CounterVec must have zero, one, or two non-const non-curried labels. For
// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. Partitioning of the CounterVec happens by HTTP status code
+// panics otherwise. For the "method" label a predefined default label value set
+// is used to filter given values. Values besides predefined values will count
+// as `unknown` method.`WithExtraMethods` can be used to add more
+// methods to the set. Partitioning of the CounterVec happens by HTTP status code
// and/or HTTP method if the respective instance label names are present in the
// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
//
@@ -57,13 +60,18 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
// is not incremented.
//
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
+func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
+ rtOpts := &option{}
+ for _, o := range opts {
+ o(rtOpts)
+ }
+
code, method := checkLabels(counter)
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
resp, err := next.RoundTrip(r)
if err == nil {
- counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
+ counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc()
}
return resp, err
})
@@ -73,7 +81,10 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
// http.RoundTripper to observe the request duration with the provided
// ObserverVec. The ObserverVec must have zero, one, or two non-const
// non-curried labels. For those, the only allowed label names are "code" and
-// "method". The function panics otherwise. The Observe method of the Observer
+// "method". The function panics otherwise. For the "method" label a predefined
+// default label value set is used to filter given values. Values besides
+// predefined values will count as `unknown` method. `WithExtraMethods`
+// can be used to add more methods to the set. The Observe method of the Observer
// in the ObserverVec is called with the request duration in
// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
// respective instance label names are present in the ObserverVec. For
@@ -85,14 +96,19 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
//
// Note that this method is only guaranteed to never observe negative durations
// if used with Go1.9+.
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
+func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
+ rtOpts := &option{}
+ for _, o := range opts {
+ o(rtOpts)
+ }
+
code, method := checkLabels(obs)
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
start := time.Now()
resp, err := next.RoundTrip(r)
if err == nil {
- obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
+ obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds())
}
return resp, err
})
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
index ab037db86..a23f0edc6 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
@@ -45,7 +45,10 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
// http.Handler to observe the request duration with the provided ObserverVec.
// The ObserverVec must have valid metric and label names and must have zero,
// one, or two non-const non-curried labels. For those, the only allowed label
-// names are "code" and "method". The function panics otherwise. The Observe
+// names are "code" and "method". The function panics otherwise. For the "method"
+// label a predefined default label value set is used to filter given values.
+// Values besides predefined values will count as `unknown` method.
+//`WithExtraMethods` can be used to add more methods to the set. The Observe
// method of the Observer in the ObserverVec is called with the request duration
// in seconds. Partitioning happens by HTTP status code and/or HTTP method if
// the respective instance label names are present in the ObserverVec. For
@@ -58,7 +61,12 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
//
// Note that this method is only guaranteed to never observe negative durations
// if used with Go1.9+.
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
+func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
+ mwOpts := &option{}
+ for _, o := range opts {
+ o(mwOpts)
+ }
+
code, method := checkLabels(obs)
if code {
@@ -67,14 +75,14 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
d := newDelegator(w, nil)
next.ServeHTTP(d, r)
- obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
})
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
now := time.Now()
next.ServeHTTP(w, r)
- obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
})
}
@@ -82,7 +90,10 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
// to observe the request result with the provided CounterVec. The CounterVec
// must have valid metric and label names and must have zero, one, or two
// non-const non-curried labels. For those, the only allowed label names are
-// "code" and "method". The function panics otherwise. Partitioning of the
+// "code" and "method". The function panics otherwise. For the "method"
+// label a predefined default label value set is used to filter given values.
+// Values besides predefined values will count as `unknown` method.
+// `WithExtraMethods` can be used to add more methods to the set. Partitioning of the
// CounterVec happens by HTTP status code and/or HTTP method if the respective
// instance label names are present in the CounterVec. For unpartitioned
// counting, use a CounterVec with zero labels.
@@ -92,20 +103,25 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
// If the wrapped Handler panics, the Counter is not incremented.
//
// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
+func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {
+ mwOpts := &option{}
+ for _, o := range opts {
+ o(mwOpts)
+ }
+
code, method := checkLabels(counter)
if code {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
d := newDelegator(w, nil)
next.ServeHTTP(d, r)
- counter.With(labels(code, method, r.Method, d.Status())).Inc()
+ counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc()
})
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
- counter.With(labels(code, method, r.Method, 0)).Inc()
+ counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc()
})
}
@@ -114,7 +130,10 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
// until the response headers are written. The ObserverVec must have valid
// metric and label names and must have zero, one, or two non-const non-curried
// labels. For those, the only allowed label names are "code" and "method". The
-// function panics otherwise. The Observe method of the Observer in the
+// function panics otherwise. For the "method" label a predefined default label
+// value set is used to filter given values. Values besides predefined values
+// will count as `unknown` method.`WithExtraMethods` can be used to add more
+// methods to the set. The Observe method of the Observer in the
// ObserverVec is called with the request duration in seconds. Partitioning
// happens by HTTP status code and/or HTTP method if the respective instance
// label names are present in the ObserverVec. For unpartitioned observations,
@@ -128,13 +147,18 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
// if used with Go1.9+.
//
// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
+func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
+ mwOpts := &option{}
+ for _, o := range opts {
+ o(mwOpts)
+ }
+
code, method := checkLabels(obs)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
now := time.Now()
d := newDelegator(w, func(status int) {
- obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
+ obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
})
next.ServeHTTP(d, r)
})
@@ -144,8 +168,11 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha
// http.Handler to observe the request size with the provided ObserverVec. The
// ObserverVec must have valid metric and label names and must have zero, one,
// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. The Observe method of
-// the Observer in the ObserverVec is called with the request size in
+// are "code" and "method". The function panics otherwise. For the "method"
+// label a predefined default label value set is used to filter given values.
+// Values besides predefined values will count as `unknown` method.
+// `WithExtraMethods` can be used to add more methods to the set. The Observe
+// method of the Observer in the ObserverVec is called with the request size in
// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
// respective instance label names are present in the ObserverVec. For
// unpartitioned observations, use an ObserverVec with zero labels. Note that
@@ -156,7 +183,12 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha
// If the wrapped Handler panics, no values are reported.
//
// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
+func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
+ mwOpts := &option{}
+ for _, o := range opts {
+ o(mwOpts)
+ }
+
code, method := checkLabels(obs)
if code {
@@ -164,14 +196,14 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
d := newDelegator(w, nil)
next.ServeHTTP(d, r)
size := computeApproximateRequestSize(r)
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size))
})
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
size := computeApproximateRequestSize(r)
- obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size))
})
}
@@ -179,8 +211,11 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
// http.Handler to observe the response size with the provided ObserverVec. The
// ObserverVec must have valid metric and label names and must have zero, one,
// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. The Observe method of
-// the Observer in the ObserverVec is called with the response size in
+// are "code" and "method". The function panics otherwise. For the "method"
+// label a predefined default label value set is used to filter given values.
+// Values besides predefined values will count as `unknown` method.
+// `WithExtraMethods` can be used to add more methods to the set. The Observe
+// method of the Observer in the ObserverVec is called with the response size in
// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
// respective instance label names are present in the ObserverVec. For
// unpartitioned observations, use an ObserverVec with zero labels. Note that
@@ -191,12 +226,18 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
// If the wrapped Handler panics, no values are reported.
//
// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
+func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {
+ mwOpts := &option{}
+ for _, o := range opts {
+ o(mwOpts)
+ }
+
code, method := checkLabels(obs)
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
d := newDelegator(w, nil)
next.ServeHTTP(d, r)
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written()))
})
}
@@ -290,7 +331,7 @@ func isLabelCurried(c prometheus.Collector, label string) bool {
// unnecessary allocations on each request.
var emptyLabels = prometheus.Labels{}
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
+func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
if !(code || method) {
return emptyLabels
}
@@ -300,7 +341,7 @@ func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
labels["code"] = sanitizeCode(status)
}
if method {
- labels["method"] = sanitizeMethod(reqMethod)
+ labels["method"] = sanitizeMethod(reqMethod, extraMethods...)
}
return labels
@@ -330,7 +371,12 @@ func computeApproximateRequestSize(r *http.Request) int {
return s
}
-func sanitizeMethod(m string) string {
+// If the wrapped http.Handler has a known method, it will be sanitized and returned.
+// Otherwise, "unknown" will be returned. The known method list can be extended
+// as needed by using extraMethods parameter.
+func sanitizeMethod(m string, extraMethods ...string) string {
+ // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for
+ // the methods chosen as default.
switch m {
case "GET", "get":
return "get"
@@ -348,15 +394,25 @@ func sanitizeMethod(m string) string {
return "options"
case "NOTIFY", "notify":
return "notify"
+ case "TRACE", "trace":
+ return "trace"
+ case "PATCH", "patch":
+ return "patch"
default:
- return strings.ToLower(m)
+ for _, method := range extraMethods {
+ if strings.EqualFold(m, method) {
+ return strings.ToLower(m)
+ }
+ }
+ return "unknown"
}
}
// If the wrapped http.Handler has not set a status code, i.e. the value is
-// currently 0, santizeCode will return 200, for consistency with behavior in
+// currently 0, sanitizeCode will return 200, for consistency with behavior in
// the stdlib.
func sanitizeCode(s int) string {
+ // See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
switch s {
case 100:
return "100"
@@ -453,6 +509,9 @@ func sanitizeCode(s int) string {
return "511"
default:
- return strconv.Itoa(s)
+ if s >= 100 && s <= 599 {
+ return strconv.Itoa(s)
+ }
+ return "unknown"
}
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
new file mode 100644
index 000000000..35e41bd1e
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
@@ -0,0 +1,31 @@
+// Copyright 2022 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package promhttp
+
+// Option are used to configure a middleware or round tripper..
+type Option func(*option)
+
+type option struct {
+ extraMethods []string
+}
+
+// WithExtraMethods adds additional HTTP methods to the list of allowed methods.
+// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.
+//
+// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.
+func WithExtraMethods(methods ...string) Option {
+ return func(o *option) {
+ o.extraMethods = methods
+ }
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f75c3810d..62fa45067 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -603,7 +603,8 @@ github.com/pkg/errors
github.com/pmezard/go-difflib/difflib
# github.com/proglottis/gpgme v0.1.1
github.com/proglottis/gpgme
-# github.com/prometheus/client_golang v1.11.0
+# github.com/prometheus/client_golang v1.11.1
+## explicit
github.com/prometheus/client_golang/prometheus
github.com/prometheus/client_golang/prometheus/internal
github.com/prometheus/client_golang/prometheus/promhttp