summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rwxr-xr-xcontrib/build_rpm.sh1
-rw-r--r--contrib/spec/podman.spec.in7
-rw-r--r--docs/source/markdown/podman-build.1.md4
-rw-r--r--docs/source/markdown/podman-create.1.md4
-rw-r--r--docs/source/markdown/podman-info.1.md27
-rw-r--r--docs/source/markdown/podman-run.1.md4
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rwxr-xr-xhack/systemd_tag.sh7
-rw-r--r--install.md6
-rw-r--r--libpod/config/config.go14
-rw-r--r--libpod/container_api.go7
-rw-r--r--libpod/container_internal.go40
-rw-r--r--libpod/container_internal_linux.go98
-rw-r--r--libpod/diff.go44
-rw-r--r--libpod/oci.go6
-rw-r--r--libpod/oci_conmon_linux.go22
-rw-r--r--libpod/oci_missing.go5
-rw-r--r--libpod/runtime.go20
-rw-r--r--pkg/adapter/checkpoint_restore.go1
-rw-r--r--pkg/registries/registries.go7
-rw-r--r--test/e2e/checkpoint_test.go20
-rw-r--r--test/e2e/e2e.coverprofile11
-rw-r--r--troubleshooting.md43
-rw-r--r--vendor/github.com/uber/jaeger-client-go/CHANGELOG.md10
-rw-r--r--vendor/github.com/uber/jaeger-client-go/config/config.go34
-rw-r--r--vendor/github.com/uber/jaeger-client-go/constants.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler.go3
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote.go3
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go48
-rw-r--r--vendor/modules.txt2
32 files changed, 379 insertions, 143 deletions
diff --git a/Makefile b/Makefile
index 864724f73..fb6e48585 100644
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,7 @@ endif
ifeq (,$(findstring systemd,$(BUILDTAGS)))
$(warning \
Podman is being compiled without the systemd build tag.\
- Install libsystemd for journald support)
+ Install libsystemd on Ubuntu or systemd-devel on rpm based distro for journald support)
endif
BUILDTAGS_CROSS ?= containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
@@ -73,11 +73,12 @@ endif
LIBPOD := ${PROJECT}/libpod
GCFLAGS ?= all=-trimpath=${PWD}
ASMFLAGS ?= all=-trimpath=${PWD}
-LDFLAGS_PODMAN ?= $(LDFLAGS) \
+LDFLAGS_PODMAN ?= \
-X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT) \
-X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \
-X $(LIBPOD)/config._installPrefix=$(PREFIX) \
- -X $(LIBPOD)/config._etcDir=$(ETCDIR)
+ -X $(LIBPOD)/config._etcDir=$(ETCDIR) \
+ -extldflags "$(LDFLAGS)"
#Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too.
LIBSECCOMP_COMMIT := release-2.3
# Rarely if ever should integration tests take more than 50min,
@@ -158,10 +159,10 @@ gofmt: ## Verify the source code gofmt
git diff --exit-code
test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
- $(GO_BUILD) -ldflags '$(LDFLAGS)' -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/test/checkseccomp
+ $(GO_BUILD) -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/test/checkseccomp
test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
- $(GO_BUILD) -ldflags '$(LDFLAGS)' -o $@ $(PROJECT)/test/goecho
+ $(GO_BUILD) -ldflags '$(LDFLAGS_PODMAN)' -o $@ $(PROJECT)/test/goecho
podman: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build with podman
$(GO_BUILD) $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o bin/$@ $(PROJECT)/cmd/podman
@@ -240,6 +241,7 @@ testunit: libpodimage ## Run unittest on the built image
localunit: test/goecho/goecho varlink_generate
ginkgo \
-r \
+ $(TESTFLAGS) \
--skipPackage test/e2e,pkg/apparmor,test/endpoint \
--cover \
--covermode atomic \
@@ -247,13 +249,13 @@ localunit: test/goecho/goecho varlink_generate
--succinct
ginkgo:
- ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/.
ginkgo-remote:
- ginkgo -v -tags "$(BUILDTAGS) remoteclient" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS) remoteclient" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
endpoint:
- ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -debug test/endpoint/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -debug test/endpoint/.
localintegration: varlink_generate test-binaries ginkgo
diff --git a/contrib/build_rpm.sh b/contrib/build_rpm.sh
index e41763fa7..088d8b7a5 100755
--- a/contrib/build_rpm.sh
+++ b/contrib/build_rpm.sh
@@ -26,6 +26,7 @@ declare -a PKGS=(device-mapper-devel \
make \
rpm-build \
go-compilers-golang-compiler \
+ systemd-devel \
)
if [[ $pkg_manager == *dnf ]]; then
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 2b9621dbc..9676a3fb4 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -22,6 +22,9 @@
%define gobuild(o:) go build -tags="$BUILDTAGS" -ldflags "${LDFLAGS:-} -B 0x$(head -c20 /dev/urandom|od -An -tx1|tr -d ' \\n')" -a -v -x %{?**};
#% endif
+# libpod hack directory
+%define hackdir %{_builddir}/%{repo}-%{shortcommit0}
+
%global provider github
%global provider_tld com
%global project containers
@@ -384,7 +387,7 @@ ln -s ../../../../ src/%{import_path}
popd
ln -s vendor src
export GOPATH=$(pwd)/_build:$(pwd):$(pwd):%{gopath}
-export BUILDTAGS="varlink selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/btrfs_tag.sh) $(hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
+export BUILDTAGS="varlink selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh) $(%{hackdir}/hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
GOPATH=$GOPATH go generate ./cmd/podman/varlink/...
@@ -402,7 +405,7 @@ mkdir -p src/%{provider}.%{provider_tld}/{containers,opencontainers}
ln -s $(dirs +1 -l) src/%{import_path_conmon}
popd
-export BUILDTAGS="selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/btrfs_tag.sh)"
+export BUILDTAGS="selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh)"
BUILDTAGS=$BUILDTAGS make
popd
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 6c8f239a6..fac8296ad 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -176,6 +176,10 @@ value can be entered. The password is entered without echo.
Add a host device to the container. The format is `<device-on-host>[:<device-on-container>][:<permissions>]` (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
+Note: if the user only has access rights via a group then accessing the device
+from inside a rootless container will fail. The `crun` runtime offers a
+workaround for this by adding the option `--annotation io.crun.keep_original_groups=1`.
+
**--disable-compression, -D**
Don't compress filesystem layers when building the image unless it is required
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 82d2e8f6a..85aa81553 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -204,6 +204,10 @@ Specify the key sequence for detaching a container. Format is a single character
Add a host device to the container. The format is `<device-on-host>[:<device-on-container>][:<permissions>]` (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
+Note: if the user only has access rights via a group then accessing the device
+from inside a rootless container will fail. The `crun` runtime offers a
+workaround for this by adding the option `--annotation io.crun.keep_original_groups=1`.
+
**--device-read-bps**=*path*
Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)
diff --git a/docs/source/markdown/podman-info.1.md b/docs/source/markdown/podman-info.1.md
index 9721755ef..b539f1d3c 100644
--- a/docs/source/markdown/podman-info.1.md
+++ b/docs/source/markdown/podman-info.1.md
@@ -53,13 +53,26 @@ host:
os: linux
uptime: 218h 49m 33.66s (Approximately 9.08 days)
registries:
- blocked: null
- insecure: null
- search:
- - quay.io
- - registry.fedoraproject.org
- - docker.io
- - registry.redhat.io
+ docker.io:
+ Blocked: true
+ Insecure: true
+ Location: docker.io
+ MirrorByDigestOnly: false
+ Mirrors:
+ - Insecure: true
+ Location: example2.io/example/ubi8-minimal
+ Prefix: docker.io
+ redhat.com:
+ Blocked: false
+ Insecure: false
+ Location: registry.access.redhat.com/ubi8
+ MirrorByDigestOnly: true
+ Mirrors:
+ - Insecure: false
+ Location: example.io/example/ubi8-minimal
+ - Insecure: true
+ Location: example3.io/example/ubi8-minimal
+ Prefix: redhat.com
store:
ConfigFile: /etc/containers/storage.conf
ContainerStore:
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index e1177cb34..e8744de35 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -210,6 +210,10 @@ Specify the key sequence for detaching a container. Format is a single character
Add a host device to the container. The format is `<device-on-host>[:<device-on-container>][:<permissions>]` (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
+Note: if the user only has access rights via a group then accessing the device
+from inside a rootless container will fail. The `crun` runtime offers a
+workaround for this by adding the option `--annotation io.crun.keep_original_groups=1`.
+
**--device-read-bps**=*path*
Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)
diff --git a/go.mod b/go.mod
index b0ac61926..82649bda6 100644
--- a/go.mod
+++ b/go.mod
@@ -59,7 +59,7 @@ require (
github.com/stretchr/testify v1.4.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/uber-go/atomic v1.4.0 // indirect
- github.com/uber/jaeger-client-go v2.20.0+incompatible
+ github.com/uber/jaeger-client-go v2.20.1+incompatible
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5 // indirect
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b
github.com/vishvananda/netlink v1.0.0
diff --git a/go.sum b/go.sum
index 9dd59ff65..2db8cce4a 100644
--- a/go.sum
+++ b/go.sum
@@ -466,6 +466,8 @@ github.com/uber/jaeger-client-go v2.19.0+incompatible h1:pbwbYfHUoaase0oPQOdZ1Gc
github.com/uber/jaeger-client-go v2.19.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-client-go v2.20.0+incompatible h1:ttG9wKdl2ikV/BGOtu+eb+VPp+R7jMeuM177Ihs5Fdc=
github.com/uber/jaeger-client-go v2.20.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU=
+github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5 h1:CwmGyzHTzCqCdZJkWR0A7ucZXgrCY7spRcpvm7ci//s=
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
diff --git a/hack/systemd_tag.sh b/hack/systemd_tag.sh
index c59cad559..19a7bf6a6 100755
--- a/hack/systemd_tag.sh
+++ b/hack/systemd_tag.sh
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
-if pkg-config --exists libsystemd; then
- echo systemd
+cc -E - > /dev/null 2> /dev/null << EOF
+#include <systemd/sd-daemon.h>
+EOF
+if test $? -eq 0 ; then
+ echo systemd
fi
diff --git a/install.md b/install.md
index 218994587..5771fff45 100644
--- a/install.md
+++ b/install.md
@@ -149,6 +149,12 @@ sudo apt-get install \
uidmap
```
+On openSUSE Leap 15.x and Tumbleweed:
+
+```bash
+sudo zypper -n in libseccomp-devel libgpgme-devel
+```
+
On Manjaro (and maybe other Linux distributions):
Make sure that the Linux kernel supports user namespaces:
diff --git a/libpod/config/config.go b/libpod/config/config.go
index 0e867a50e..6240bccb0 100644
--- a/libpod/config/config.go
+++ b/libpod/config/config.go
@@ -448,20 +448,27 @@ func NewConfig(userConfigPath string) (*Config, error) {
if err != nil {
return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath)
}
- if err := cgroupV2Check(userConfigPath, config); err != nil {
- return nil, errors.Wrapf(err, "error rewriting configuration file %s", userConfigPath)
- }
}
// Now, check if the user can access system configs and merge them if needed.
if configs, err := systemConfigs(); err != nil {
return nil, errors.Wrapf(err, "error finding config on system")
} else {
+ migrated := false
for _, path := range configs {
systemConfig, err := readConfigFromFile(path)
if err != nil {
return nil, errors.Wrapf(err, "error reading system config %q", path)
}
+ // Handle CGroups v2 configuration migration.
+ // Migrate only the first config, and do it before
+ // merging.
+ if !migrated {
+ if err := cgroupV2Check(path, systemConfig); err != nil {
+ return nil, errors.Wrapf(err, "error rewriting configuration file %s", userConfigPath)
+ }
+ migrated = true
+ }
// Merge the it into the config. Any unset field in config will be
// over-written by the systemConfig.
if err := config.mergeConfig(systemConfig); err != nil {
@@ -564,6 +571,7 @@ func (c *Config) checkCgroupsAndLogger() {
// TODO Once runc has support for cgroups, this function should be removed.
func cgroupV2Check(configPath string, tmpConfig *Config) error {
if !tmpConfig.CgroupCheck && rootless.IsRootless() {
+ logrus.Debugf("Rewriting %s for CGroup v2 upgrade", configPath)
cgroupsV2, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return err
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 153a1d628..5168dbc68 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -594,7 +594,12 @@ func (c *Container) Cleanup(ctx context.Context) error {
// If we didn't restart, we perform a normal cleanup
- // Check if we have active exec sessions
+ // Reap exec sessions first.
+ if err := c.reapExecSessions(); err != nil {
+ return err
+ }
+
+ // Check if we have active exec sessions after reaping.
if len(c.state.ExecSessions) != 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s has active exec sessions, refusing to clean up", c.ID())
}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 1e8a8a580..37801162a 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1749,6 +1749,11 @@ func (c *Container) checkReadyForRemoval() error {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot remove container %s as it is %s - running or paused containers cannot be removed without force", c.ID(), c.state.State.String())
}
+ // Reap exec sessions
+ if err := c.reapExecSessions(); err != nil {
+ return err
+ }
+
if len(c.state.ExecSessions) != 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot remove container %s as it has active exec sessions", c.ID())
}
@@ -1855,3 +1860,38 @@ func (c *Container) checkExitFile() error {
// Read the exit file to get our stopped time and exit code.
return c.handleExitFile(exitFile, info)
}
+
+// Reap dead exec sessions
+func (c *Container) reapExecSessions() error {
+ // Instead of saving once per iteration, use a defer to do it once at
+ // the end.
+ var lastErr error
+ needSave := false
+ for id := range c.state.ExecSessions {
+ alive, err := c.ociRuntime.ExecUpdateStatus(c, id)
+ if err != nil {
+ if lastErr != nil {
+ logrus.Errorf("Error reaping exec sessions for container %s: %v", c.ID(), lastErr)
+ }
+ lastErr = err
+ continue
+ }
+ if !alive {
+ // Clean up lingering files and remove the exec session
+ if err := c.ociRuntime.ExecContainerCleanup(c, id); err != nil {
+ return errors.Wrapf(err, "error cleaning up container %s exec session %s files", c.ID(), id)
+ }
+ delete(c.state.ExecSessions, id)
+ needSave = true
+ }
+ }
+ if needSave {
+ if err := c.save(); err != nil {
+ if lastErr != nil {
+ logrus.Errorf("Error reaping exec sessions for container %s: %v", c.ID(), lastErr)
+ }
+ lastErr = err
+ }
+ }
+ return lastErr
+}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 1b0570998..6ec06943f 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -593,22 +593,68 @@ func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error)
// Get root file-system changes included in the checkpoint archive
rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
+ deleteFilesList := filepath.Join(c.bundlePath(), "deleted.files")
if !ignoreRootfs {
- rootfsDiffFile, err := os.Create(rootfsDiffPath)
- if err != nil {
- return errors.Wrapf(err, "error creating root file-system diff file %q", rootfsDiffPath)
- }
- tarStream, err := c.runtime.GetDiffTarStream("", c.ID())
+ // To correctly track deleted files, let's go through the output of 'podman diff'
+ tarFiles, err := c.runtime.GetDiff("", c.ID())
if err != nil {
return errors.Wrapf(err, "error exporting root file-system diff to %q", rootfsDiffPath)
}
- _, err = io.Copy(rootfsDiffFile, tarStream)
- if err != nil {
- return errors.Wrapf(err, "error exporting root file-system diff to %q", rootfsDiffPath)
+ var rootfsIncludeFiles []string
+ var deletedFiles []string
+
+ for _, file := range tarFiles {
+ if file.Kind == archive.ChangeAdd {
+ rootfsIncludeFiles = append(rootfsIncludeFiles, file.Path)
+ continue
+ }
+ if file.Kind == archive.ChangeDelete {
+ deletedFiles = append(deletedFiles, file.Path)
+ continue
+ }
+ fileName, err := os.Stat(file.Path)
+ if err != nil {
+ continue
+ }
+ if !fileName.IsDir() && file.Kind == archive.ChangeModify {
+ rootfsIncludeFiles = append(rootfsIncludeFiles, file.Path)
+ continue
+ }
+ }
+
+ if len(rootfsIncludeFiles) > 0 {
+ rootfsTar, err := archive.TarWithOptions(c.state.Mountpoint, &archive.TarOptions{
+ Compression: archive.Uncompressed,
+ IncludeSourceDir: true,
+ IncludeFiles: rootfsIncludeFiles,
+ })
+ if err != nil {
+ return errors.Wrapf(err, "error exporting root file-system diff to %q", rootfsDiffPath)
+ }
+ rootfsDiffFile, err := os.Create(rootfsDiffPath)
+ if err != nil {
+ return errors.Wrapf(err, "error creating root file-system diff file %q", rootfsDiffPath)
+ }
+ defer rootfsDiffFile.Close()
+ _, err = io.Copy(rootfsDiffFile, rootfsTar)
+ if err != nil {
+ return err
+ }
+
+ includeFiles = append(includeFiles, "rootfs-diff.tar")
+ }
+
+ if len(deletedFiles) > 0 {
+ formatJSON, err := json.MarshalIndent(deletedFiles, "", " ")
+ if err != nil {
+ return errors.Wrapf(err, "error creating delete files list file %q", deleteFilesList)
+ }
+ if err := ioutil.WriteFile(deleteFilesList, formatJSON, 0600); err != nil {
+ return errors.Wrapf(err, "error creating delete files list file %q", deleteFilesList)
+ }
+
+ includeFiles = append(includeFiles, "deleted.files")
}
- tarStream.Close()
- rootfsDiffFile.Close()
- includeFiles = append(includeFiles, "rootfs-diff.tar")
}
input, err := archive.TarWithOptions(c.bundlePath(), &archive.TarOptions{
@@ -637,6 +683,7 @@ func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error)
}
os.Remove(rootfsDiffPath)
+ os.Remove(deleteFilesList)
return nil
}
@@ -941,10 +988,35 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
if err != nil {
return errors.Wrapf(err, "Failed to open root file-system diff file %s", rootfsDiffPath)
}
+ defer rootfsDiffFile.Close()
if err := c.runtime.ApplyDiffTarStream(c.ID(), rootfsDiffFile); err != nil {
return errors.Wrapf(err, "Failed to apply root file-system diff file %s", rootfsDiffPath)
}
- rootfsDiffFile.Close()
+ }
+ deletedFilesPath := filepath.Join(c.bundlePath(), "deleted.files")
+ if _, err := os.Stat(deletedFilesPath); err == nil {
+ deletedFilesFile, err := os.Open(deletedFilesPath)
+ if err != nil {
+ return errors.Wrapf(err, "Failed to open deleted files file %s", deletedFilesPath)
+ }
+ defer deletedFilesFile.Close()
+
+ var deletedFiles []string
+ deletedFilesJSON, err := ioutil.ReadAll(deletedFilesFile)
+ if err != nil {
+ return errors.Wrapf(err, "Failed to read deleted files file %s", deletedFilesPath)
+ }
+ if err := json.Unmarshal(deletedFilesJSON, &deletedFiles); err != nil {
+ return errors.Wrapf(err, "Failed to read deleted files file %s", deletedFilesPath)
+ }
+ for _, deleteFile := range deletedFiles {
+ // Using RemoveAll as deletedFiles, which is generated from 'podman diff'
+ // lists completely deleted directories as a single entry: 'D /root'.
+ err = os.RemoveAll(filepath.Join(c.state.Mountpoint, deleteFile))
+ if err != nil {
+ return errors.Wrapf(err, "Failed to delete file %s from container %s during restore", deletedFilesPath, c.ID())
+ }
+ }
}
}
@@ -965,7 +1037,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
if err != nil {
logrus.Debugf("Non-fatal: removal of checkpoint directory (%s) failed: %v", c.CheckpointPath(), err)
}
- cleanup := [...]string{"restore.log", "dump.log", "stats-dump", "stats-restore", "network.status", "rootfs-diff.tar"}
+ cleanup := [...]string{"restore.log", "dump.log", "stats-dump", "stats-restore", "network.status", "rootfs-diff.tar", "deleted.files"}
for _, del := range cleanup {
file := filepath.Join(c.bundlePath(), del)
err = os.Remove(file)
diff --git a/libpod/diff.go b/libpod/diff.go
index 925bda927..baa4d6ad7 100644
--- a/libpod/diff.go
+++ b/libpod/diff.go
@@ -1,7 +1,6 @@
package libpod
import (
- "archive/tar"
"io"
"github.com/containers/libpod/libpod/layers"
@@ -47,49 +46,6 @@ func (r *Runtime) GetDiff(from, to string) ([]archive.Change, error) {
return rchanges, err
}
-// skipFileInTarAchive is an archive.TarModifierFunc function
-// which tells archive.ReplaceFileTarWrapper to skip files
-// from the tarstream
-func skipFileInTarAchive(path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
- return nil, nil, nil
-}
-
-// GetDiffTarStream returns the differences between the two images, layers, or containers.
-// It is the same functionality as GetDiff() except that it returns a tarstream
-func (r *Runtime) GetDiffTarStream(from, to string) (io.ReadCloser, error) {
- toLayer, err := r.getLayerID(to)
- if err != nil {
- return nil, err
- }
- fromLayer := ""
- if from != "" {
- fromLayer, err = r.getLayerID(from)
- if err != nil {
- return nil, err
- }
- }
- rc, err := r.store.Diff(fromLayer, toLayer, nil)
- if err != nil {
- return nil, err
- }
-
- // Skip files in the tar archive which are listed
- // in containerMounts map. Just as in the GetDiff()
- // function from above
- filterMap := make(map[string]archive.TarModifierFunc)
- for key := range containerMounts {
- filterMap[key[1:]] = skipFileInTarAchive
- // In the tarstream directories always include a trailing '/'.
- // For simplicity this duplicates every entry from
- // containerMounts with a trailing '/', as containerMounts
- // does not use trailing '/' for directories.
- filterMap[key[1:]+"/"] = skipFileInTarAchive
- }
-
- filteredTarStream := archive.ReplaceFileTarWrapper(rc, filterMap)
- return filteredTarStream, nil
-}
-
// ApplyDiffTarStream applies the changes stored in 'diff' to the layer 'to'
func (r *Runtime) ApplyDiffTarStream(to string, diff io.Reader) error {
toLayer, err := r.getLayerID(to)
diff --git a/libpod/oci.go b/libpod/oci.go
index 9e761788e..05a2f37db 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -23,9 +23,6 @@ type OCIRuntime interface {
// CreateContainer creates the container in the OCI runtime.
CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) error
// UpdateContainerStatus updates the status of the given container.
- // It includes a switch for whether to perform a hard query of the
- // runtime. If unset, the exit file (if supported by the implementation)
- // will be used.
UpdateContainerStatus(ctr *Container) error
// StartContainer starts the given container.
StartContainer(ctr *Container) error
@@ -59,6 +56,9 @@ type OCIRuntime interface {
// If timeout is 0, SIGKILL will be sent immediately, and SIGTERM will
// be omitted.
ExecStopContainer(ctr *Container, sessionID string, timeout uint) error
+ // ExecUpdateStatus checks the status of a given exec session.
+ // Returns true if the session is still running, or false if it exited.
+ ExecUpdateStatus(ctr *Container, sessionID string) (bool, error)
// ExecContainerCleanup cleans up after an exec session exits.
// It removes any files left by the exec session that are no longer
// needed, including the attach socket.
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 026b13129..37aa71cbb 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -687,6 +687,28 @@ func (r *ConmonOCIRuntime) ExecStopContainer(ctr *Container, sessionID string, t
return nil
}
+// ExecUpdateStatus checks if the given exec session is still running.
+func (r *ConmonOCIRuntime) ExecUpdateStatus(ctr *Container, sessionID string) (bool, error) {
+ session, ok := ctr.state.ExecSessions[sessionID]
+ if !ok {
+ // TODO This should probably be a separate error
+ return false, errors.Wrapf(define.ErrInvalidArg, "no exec session with ID %s found in container %s", sessionID, ctr.ID())
+ }
+
+ logrus.Debugf("Checking status of container %s exec session %s", ctr.ID(), sessionID)
+
+ // Is the session dead?
+ // Ping the PID with signal 0 to see if it still exists.
+ if err := unix.Kill(session.PID, 0); err != nil {
+ if err == unix.ESRCH {
+ return false, nil
+ }
+ return false, errors.Wrapf(err, "error pinging container %s exec session %s PID %d with signal 0", ctr.ID(), sessionID, session.PID)
+ }
+
+ return true, nil
+}
+
// ExecCleanupContainer cleans up files created when a command is run via
// ExecContainer. This includes the attach socket for the exec session.
func (r *ConmonOCIRuntime) ExecContainerCleanup(ctr *Container, sessionID string) error {
diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go
index d4524cd34..0faa1805b 100644
--- a/libpod/oci_missing.go
+++ b/libpod/oci_missing.go
@@ -120,6 +120,11 @@ func (r *MissingRuntime) ExecStopContainer(ctr *Container, sessionID string, tim
return r.printError()
}
+// ExecUpdateStatus is not available as the runtime is missing.
+func (r *MissingRuntime) ExecUpdateStatus(ctr *Container, sessionID string) (bool, error) {
+ return false, r.printError()
+}
+
// ExecContainerCleanup is not available as the runtime is missing
func (r *MissingRuntime) ExecContainerCleanup(ctr *Container, sessionID string) error {
return r.printError()
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 3873079ce..001d850b0 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -691,24 +691,22 @@ func (r *Runtime) Info() ([]define.InfoData, error) {
}
info = append(info, define.InfoData{Type: "store", Data: storeInfo})
- reg, err := sysreg.GetRegistries()
- if err != nil {
- return nil, errors.Wrapf(err, "error getting registries")
- }
registries := make(map[string]interface{})
- registries["search"] = reg
-
- ireg, err := sysreg.GetInsecureRegistries()
+ data, err := sysreg.GetRegistriesData()
if err != nil {
return nil, errors.Wrapf(err, "error getting registries")
}
- registries["insecure"] = ireg
-
- breg, err := sysreg.GetBlockedRegistries()
+ for _, reg := range data {
+ registries[reg.Prefix] = reg
+ }
+ regs, err := sysreg.GetRegistries()
if err != nil {
return nil, errors.Wrapf(err, "error getting registries")
}
- registries["blocked"] = breg
+ if len(regs) > 0 {
+ registries["search"] = regs
+ }
+
info = append(info, define.InfoData{Type: "registries", Data: registries})
return info, nil
}
diff --git a/pkg/adapter/checkpoint_restore.go b/pkg/adapter/checkpoint_restore.go
index 15f9e8105..7f80b782a 100644
--- a/pkg/adapter/checkpoint_restore.go
+++ b/pkg/adapter/checkpoint_restore.go
@@ -60,6 +60,7 @@ func crImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input stri
"ctr.log",
"rootfs-diff.tar",
"network.status",
+ "deleted.files",
},
}
dir, err := ioutil.TempDir("", "checkpoint")
diff --git a/pkg/registries/registries.go b/pkg/registries/registries.go
index 9643c947f..ba7de7cf9 100644
--- a/pkg/registries/registries.go
+++ b/pkg/registries/registries.go
@@ -34,7 +34,8 @@ func SystemRegistriesConfPath() string {
return ""
}
-func getRegistries() ([]sysregistriesv2.Registry, error) {
+// GetRegistriesData obtains the list of registries
+func GetRegistriesData() ([]sysregistriesv2.Registry, error) {
registries, err := sysregistriesv2.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: SystemRegistriesConfPath()})
if err != nil {
return nil, errors.Wrapf(err, "unable to parse the registries.conf file")
@@ -50,7 +51,7 @@ func GetRegistries() ([]string, error) {
// GetBlockedRegistries obtains the list of blocked registries defined in the global registries file.
func GetBlockedRegistries() ([]string, error) {
var blockedRegistries []string
- registries, err := getRegistries()
+ registries, err := GetRegistriesData()
if err != nil {
return nil, err
}
@@ -65,7 +66,7 @@ func GetBlockedRegistries() ([]string, error) {
// GetInsecureRegistries obtains the list of insecure registries from the global registration file.
func GetInsecureRegistries() ([]string, error) {
var insecureRegistries []string
- registries, err := getRegistries()
+ registries, err := GetRegistriesData()
if err != nil {
return nil, err
}
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index f208a4cf0..237223283 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -439,6 +439,18 @@ var _ = Describe("Podman checkpoint", func() {
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
+ result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "rm /etc/motd"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+
+ result = podmanTest.Podman([]string{"diff", "-l"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(ContainSubstring("C /etc"))
+ Expect(result.OutputToString()).To(ContainSubstring("A /test.output"))
+ Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd"))
+ Expect(len(result.OutputToStringArray())).To(Equal(3))
+
// Checkpoint the container
result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName})
result.WaitWithDefaultTimeout()
@@ -462,6 +474,14 @@ var _ = Describe("Podman checkpoint", func() {
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test"))
+ result = podmanTest.Podman([]string{"diff", "-l"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(ContainSubstring("C /etc"))
+ Expect(result.OutputToString()).To(ContainSubstring("A /test.output"))
+ Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd"))
+ Expect(len(result.OutputToStringArray())).To(Equal(3))
+
// Remove exported checkpoint
os.Remove(fileName)
})
diff --git a/test/e2e/e2e.coverprofile b/test/e2e/e2e.coverprofile
deleted file mode 100644
index d413679ea..000000000
--- a/test/e2e/e2e.coverprofile
+++ /dev/null
@@ -1,11 +0,0 @@
-mode: atomic
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:14.46,21.20 2 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:32.2,32.19 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:39.2,39.53 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:66.2,66.52 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:21.20,23.17 2 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:26.3,29.36 4 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:23.17,25.4 1 0
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:32.19,37.3 3 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:39.53,64.3 20 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:66.52,91.3 20 3 \ No newline at end of file
diff --git a/troubleshooting.md b/troubleshooting.md
index 9def0e08b..d122983d7 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -442,3 +442,46 @@ Attempts to run podman result in
#### Solution
One workaround is to disable Secure Boot in your BIOS.
+
+### 19) error creating libpod runtime: there might not be enough IDs available in the namespace
+
+Unable to pull images
+
+#### Symptom
+
+```console
+$ podman unshare cat /proc/self/uid_map
+ 0 1000 1
+```
+
+#### Solution
+
+```console
+$ podman system migrate
+```
+
+Original command now returns
+
+```
+$ podman unshare cat /proc/self/uid_map
+ 0 1000 1
+ 1 100000 65536
+```
+
+Reference [subuid](http://man7.org/linux/man-pages/man5/subuid.5.html) and [subgid](http://man7.org/linux/man-pages/man5/subgid.5.html) man pages for more detail.
+
+### 20) Passed-in device can't be accessed in rootless container
+
+As a non-root user you have group access rights to a device that you want to
+pass into a rootless container with `--device=...`.
+
+#### Symptom
+
+Any access inside the container is rejected with "Permission denied".
+
+#### Solution
+
+The runtime uses `setgroups(2)` hence the process looses all additional groups
+the non-root user has. If you use the `crun` runtime, 0.10.4 or newer,
+then you can enable a workaround by adding `--annotation io.crun.keep_original_groups=1`
+to the `podman` command line.
diff --git a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
index c4590bf93..5e7e9d5e5 100644
--- a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
+++ b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
@@ -1,6 +1,16 @@
Changes by Version
==================
+2.20.1 (2019-11-08)
+-------------------
+
+Minor patch via https://github.com/jaegertracing/jaeger-client-go/pull/468
+
+- Make `AdaptiveSamplerUpdater` usable with default values; Resolves #467
+- Create `OperationNameLateBinding` sampler option and config option
+- Make `SamplerOptions` var of public type, so that its functions are discoverable via godoc
+
+
2.20.0 (2019-11-06)
-------------------
diff --git a/vendor/github.com/uber/jaeger-client-go/config/config.go b/vendor/github.com/uber/jaeger-client-go/config/config.go
index 965f7c3ee..a0c32d804 100644
--- a/vendor/github.com/uber/jaeger-client-go/config/config.go
+++ b/vendor/github.com/uber/jaeger-client-go/config/config.go
@@ -76,17 +76,26 @@ type SamplerConfig struct {
// Can be set by exporting an environment variable named JAEGER_SAMPLER_MANAGER_HOST_PORT
SamplingServerURL string `yaml:"samplingServerURL"`
- // MaxOperations is the maximum number of operations that the sampler
- // will keep track of. If an operation is not tracked, a default probabilistic
- // sampler will be used rather than the per operation specific sampler.
- // Can be set by exporting an environment variable named JAEGER_SAMPLER_MAX_OPERATIONS
- MaxOperations int `yaml:"maxOperations"`
-
// SamplingRefreshInterval controls how often the remotely controlled sampler will poll
// jaeger-agent for the appropriate sampling strategy.
// Can be set by exporting an environment variable named JAEGER_SAMPLER_REFRESH_INTERVAL
SamplingRefreshInterval time.Duration `yaml:"samplingRefreshInterval"`
+ // MaxOperations is the maximum number of operations that the PerOperationSampler
+ // will keep track of. If an operation is not tracked, a default probabilistic
+ // sampler will be used rather than the per operation specific sampler.
+ // Can be set by exporting an environment variable named JAEGER_SAMPLER_MAX_OPERATIONS.
+ MaxOperations int `yaml:"maxOperations"`
+
+ // Opt-in feature for applications that require late binding of span name via explicit
+ // call to SetOperationName when using PerOperationSampler. When this feature is enabled,
+ // the sampler will return retryable=true from OnCreateSpan(), thus leaving the sampling
+ // decision as non-final (and the span as writeable). This may lead to degraded performance
+ // in applications that always provide the correct span name on trace creation.
+ //
+ // For backwards compatibility this option is off by default.
+ OperationNameLateBinding bool `yaml:"operationNameLateBinding"`
+
// Options can be used to programmatically pass additional options to the Remote sampler.
Options []jaeger.SamplerOption
}
@@ -335,7 +344,7 @@ func (sc *SamplerConfig) NewSampler(
return jaeger.NewProbabilisticSampler(sc.Param)
}
return nil, fmt.Errorf(
- "Invalid Param for probabilistic sampler: %v. Expecting value between 0 and 1",
+ "invalid Param for probabilistic sampler; expecting value between 0 and 1, received %v",
sc.Param,
)
}
@@ -353,17 +362,14 @@ func (sc *SamplerConfig) NewSampler(
jaeger.SamplerOptions.Metrics(metrics),
jaeger.SamplerOptions.InitialSampler(initSampler),
jaeger.SamplerOptions.SamplingServerURL(sc.SamplingServerURL),
- }
- if sc.MaxOperations != 0 {
- options = append(options, jaeger.SamplerOptions.MaxOperations(sc.MaxOperations))
- }
- if sc.SamplingRefreshInterval != 0 {
- options = append(options, jaeger.SamplerOptions.SamplingRefreshInterval(sc.SamplingRefreshInterval))
+ jaeger.SamplerOptions.MaxOperations(sc.MaxOperations),
+ jaeger.SamplerOptions.OperationNameLateBinding(sc.OperationNameLateBinding),
+ jaeger.SamplerOptions.SamplingRefreshInterval(sc.SamplingRefreshInterval),
}
options = append(options, sc.Options...)
return jaeger.NewRemotelyControlledSampler(serviceName, options...), nil
}
- return nil, fmt.Errorf("Unknown sampler type %v", sc.Type)
+ return nil, fmt.Errorf("unknown sampler type (%s)", sc.Type)
}
// NewReporter instantiates a new reporter that submits spans to the collector
diff --git a/vendor/github.com/uber/jaeger-client-go/constants.go b/vendor/github.com/uber/jaeger-client-go/constants.go
index 0da47b02f..5d27b628d 100644
--- a/vendor/github.com/uber/jaeger-client-go/constants.go
+++ b/vendor/github.com/uber/jaeger-client-go/constants.go
@@ -22,7 +22,7 @@ import (
const (
// JaegerClientVersion is the version of the client library reported as Span tag.
- JaegerClientVersion = "Go-2.20.0"
+ JaegerClientVersion = "Go-2.20.1"
// JaegerClientVersionTagKey is the name of the tag used to report client version.
JaegerClientVersionTagKey = "jaeger.version"
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler.go b/vendor/github.com/uber/jaeger-client-go/sampler.go
index 6195d59c5..f47004b1f 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler.go
@@ -363,6 +363,9 @@ type PerOperationSamplerParams struct {
// NewPerOperationSampler returns a new PerOperationSampler.
func NewPerOperationSampler(params PerOperationSamplerParams) *PerOperationSampler {
+ if params.MaxOperations <= 0 {
+ params.MaxOperations = defaultMaxOperations
+ }
samplers := make(map[string]*GuaranteedThroughputProbabilisticSampler)
for _, strategy := range params.Strategies.PerOperationStrategies {
sampler := newGuaranteedThroughputProbabilisticSampler(
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_remote.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
index 9bd0c9822..4448b8f64 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
@@ -258,8 +258,9 @@ func (u *RateLimitingSamplerUpdater) Update(sampler SamplerV2, strategy interfac
// -----------------------
// AdaptiveSamplerUpdater is used by RemotelyControlledSampler to parse sampling configuration.
+// Fields have the same meaning as in PerOperationSamplerParams.
type AdaptiveSamplerUpdater struct {
- MaxOperations int // required
+ MaxOperations int
OperationNameLateBinding bool
}
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
index 7a292effc..3b5c6aa9c 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
@@ -23,12 +23,17 @@ import (
// SamplerOption is a function that sets some option on the sampler
type SamplerOption func(options *samplerOptions)
-// SamplerOptions is a factory for all available SamplerOption's
-var SamplerOptions samplerOptions
+// SamplerOptions is a factory for all available SamplerOption's.
+var SamplerOptions SamplerOptionsFactory
+
+// SamplerOptionsFactory is a factory for all available SamplerOption's.
+// The type acts as a namespace for factory functions. It is public to
+// make the functions discoverable via godoc. Recommended to be used
+// via global SamplerOptions variable.
+type SamplerOptionsFactory struct{}
type samplerOptions struct {
metrics *Metrics
- maxOperations int
sampler SamplerV2
logger Logger
samplingServerURL string
@@ -36,11 +41,12 @@ type samplerOptions struct {
samplingFetcher SamplingStrategyFetcher
samplingParser SamplingStrategyParser
updaters []SamplerUpdater
+ posParams PerOperationSamplerParams
}
// Metrics creates a SamplerOption that initializes Metrics on the sampler,
// which is used to emit statistics.
-func (samplerOptions) Metrics(m *Metrics) SamplerOption {
+func (SamplerOptionsFactory) Metrics(m *Metrics) SamplerOption {
return func(o *samplerOptions) {
o.metrics = m
}
@@ -48,22 +54,30 @@ func (samplerOptions) Metrics(m *Metrics) SamplerOption {
// MaxOperations creates a SamplerOption that sets the maximum number of
// operations the sampler will keep track of.
-func (samplerOptions) MaxOperations(maxOperations int) SamplerOption {
+func (SamplerOptionsFactory) MaxOperations(maxOperations int) SamplerOption {
+ return func(o *samplerOptions) {
+ o.posParams.MaxOperations = maxOperations
+ }
+}
+
+// OperationNameLateBinding creates a SamplerOption that sets the respective
+// field in the PerOperationSamplerParams.
+func (SamplerOptionsFactory) OperationNameLateBinding(enable bool) SamplerOption {
return func(o *samplerOptions) {
- o.maxOperations = maxOperations
+ o.posParams.OperationNameLateBinding = enable
}
}
// InitialSampler creates a SamplerOption that sets the initial sampler
// to use before a remote sampler is created and used.
-func (samplerOptions) InitialSampler(sampler Sampler) SamplerOption {
+func (SamplerOptionsFactory) InitialSampler(sampler Sampler) SamplerOption {
return func(o *samplerOptions) {
o.sampler = samplerV1toV2(sampler)
}
}
// Logger creates a SamplerOption that sets the logger used by the sampler.
-func (samplerOptions) Logger(logger Logger) SamplerOption {
+func (SamplerOptionsFactory) Logger(logger Logger) SamplerOption {
return func(o *samplerOptions) {
o.logger = logger
}
@@ -71,7 +85,7 @@ func (samplerOptions) Logger(logger Logger) SamplerOption {
// SamplingServerURL creates a SamplerOption that sets the sampling server url
// of the local agent that contains the sampling strategies.
-func (samplerOptions) SamplingServerURL(samplingServerURL string) SamplerOption {
+func (SamplerOptionsFactory) SamplingServerURL(samplingServerURL string) SamplerOption {
return func(o *samplerOptions) {
o.samplingServerURL = samplingServerURL
}
@@ -79,28 +93,28 @@ func (samplerOptions) SamplingServerURL(samplingServerURL string) SamplerOption
// SamplingRefreshInterval creates a SamplerOption that sets how often the
// sampler will poll local agent for the appropriate sampling strategy.
-func (samplerOptions) SamplingRefreshInterval(samplingRefreshInterval time.Duration) SamplerOption {
+func (SamplerOptionsFactory) SamplingRefreshInterval(samplingRefreshInterval time.Duration) SamplerOption {
return func(o *samplerOptions) {
o.samplingRefreshInterval = samplingRefreshInterval
}
}
// SamplingStrategyFetcher creates a SamplerOption that initializes sampling strategy fetcher.
-func (samplerOptions) SamplingStrategyFetcher(fetcher SamplingStrategyFetcher) SamplerOption {
+func (SamplerOptionsFactory) SamplingStrategyFetcher(fetcher SamplingStrategyFetcher) SamplerOption {
return func(o *samplerOptions) {
o.samplingFetcher = fetcher
}
}
// SamplingStrategyParser creates a SamplerOption that initializes sampling strategy parser.
-func (samplerOptions) SamplingStrategyParser(parser SamplingStrategyParser) SamplerOption {
+func (SamplerOptionsFactory) SamplingStrategyParser(parser SamplingStrategyParser) SamplerOption {
return func(o *samplerOptions) {
o.samplingParser = parser
}
}
// Updaters creates a SamplerOption that initializes sampler updaters.
-func (samplerOptions) Updaters(updaters ...SamplerUpdater) SamplerOption {
+func (SamplerOptionsFactory) Updaters(updaters ...SamplerUpdater) SamplerOption {
return func(o *samplerOptions) {
o.updaters = updaters
}
@@ -116,9 +130,6 @@ func (o *samplerOptions) applyOptionsAndDefaults(opts ...SamplerOption) *sampler
if o.logger == nil {
o.logger = log.NullLogger
}
- if o.maxOperations <= 0 {
- o.maxOperations = defaultMaxOperations
- }
if o.samplingServerURL == "" {
o.samplingServerURL = DefaultSamplingServerURL
}
@@ -139,7 +150,10 @@ func (o *samplerOptions) applyOptionsAndDefaults(opts ...SamplerOption) *sampler
}
if o.updaters == nil {
o.updaters = []SamplerUpdater{
- &AdaptiveSamplerUpdater{MaxOperations: o.maxOperations},
+ &AdaptiveSamplerUpdater{
+ MaxOperations: o.posParams.MaxOperations,
+ OperationNameLateBinding: o.posParams.OperationNameLateBinding,
+ },
new(ProbabilisticSamplerUpdater),
new(RateLimitingSamplerUpdater),
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 580b4e8cd..ba692e089 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -451,7 +451,7 @@ github.com/stretchr/testify/require
github.com/syndtr/gocapability/capability
# github.com/tchap/go-patricia v2.3.0+incompatible
github.com/tchap/go-patricia/patricia
-# github.com/uber/jaeger-client-go v2.20.0+incompatible
+# github.com/uber/jaeger-client-go v2.20.1+incompatible
github.com/uber/jaeger-client-go
github.com/uber/jaeger-client-go/config
github.com/uber/jaeger-client-go/internal/baggage