summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.copr/prepare.sh2
-rw-r--r--Dockerfile2
-rw-r--r--Dockerfile.centos2
-rw-r--r--Dockerfile.fedora2
-rw-r--r--cmd/podman/cliconfig/create.go1
-rw-r--r--cmd/podman/container.go1
-rw-r--r--cmd/podman/cp.go71
-rw-r--r--cmd/podman/main_local.go44
-rw-r--r--cmd/podman/shared/container.go5
-rw-r--r--cmd/podman/shared/create.go7
-rw-r--r--completions/bash/podman11
-rw-r--r--contrib/cirrus/container_test.sh2
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--docs/podman-build.1.md12
-rw-r--r--docs/podman-container.1.md1
-rw-r--r--docs/podman-cp.1.md4
-rw-r--r--docs/podman-create.1.md2
-rw-r--r--docs/podman-logs.1.md12
-rw-r--r--docs/podman-run.1.md2
-rwxr-xr-xhack/get_ci_vm.sh8
-rw-r--r--libpod/container.go16
-rw-r--r--libpod/container_log.go20
-rw-r--r--libpod/container_log_linux.go143
-rw-r--r--libpod/container_log_unsupported.go11
-rw-r--r--libpod/oci.go4
-rw-r--r--libpod/oci_linux.go9
-rw-r--r--libpod/options.go21
-rw-r--r--libpod/runtime_ctr.go4
-rw-r--r--pkg/inspect/inspect.go2
-rw-r--r--pkg/rootless/rootless_linux.c149
-rw-r--r--pkg/rootless/rootless_linux.go133
-rw-r--r--pkg/rootless/rootless_unsupported.go14
-rw-r--r--pkg/spec/createconfig.go3
-rw-r--r--test/e2e/attach_test.go2
-rw-r--r--test/e2e/checkpoint_test.go3
-rw-r--r--test/e2e/commit_test.go2
-rw-r--r--test/e2e/common_test.go109
-rw-r--r--test/e2e/config.go1
-rw-r--r--test/e2e/config_amd64.go2
-rw-r--r--test/e2e/config_ppc64le.go2
-rw-r--r--test/e2e/cp_test.go62
-rw-r--r--test/e2e/create_staticip_test.go2
-rw-r--r--test/e2e/create_test.go2
-rw-r--r--test/e2e/diff_test.go2
-rw-r--r--test/e2e/events_test.go2
-rw-r--r--test/e2e/exec_test.go3
-rw-r--r--test/e2e/exists_test.go8
-rw-r--r--test/e2e/export_test.go2
-rw-r--r--test/e2e/generate_kube_test.go2
-rw-r--r--test/e2e/generate_systemd_test.go2
-rw-r--r--test/e2e/healthcheck_run_test.go5
-rw-r--r--test/e2e/history_test.go2
-rw-r--r--test/e2e/images_test.go49
-rw-r--r--test/e2e/import_test.go9
-rw-r--r--test/e2e/init_test.go2
-rw-r--r--test/e2e/inspect_test.go2
-rw-r--r--test/e2e/kill_test.go2
-rw-r--r--test/e2e/libpod_suite_remoteclient_test.go26
-rw-r--r--test/e2e/libpod_suite_test.go43
-rw-r--r--test/e2e/load_test.go87
-rw-r--r--test/e2e/logs_test.go80
-rw-r--r--test/e2e/mount_test.go2
-rw-r--r--test/e2e/namespace_test.go2
-rw-r--r--test/e2e/pause_test.go4
-rw-r--r--test/e2e/pod_create_test.go2
-rw-r--r--test/e2e/pod_infra_container_test.go7
-rw-r--r--test/e2e/pod_inspect_test.go2
-rw-r--r--test/e2e/pod_kill_test.go2
-rw-r--r--test/e2e/pod_pause_test.go2
-rw-r--r--test/e2e/pod_pod_namespaces.go3
-rw-r--r--test/e2e/pod_prune_test.go2
-rw-r--r--test/e2e/pod_ps_test.go2
-rw-r--r--test/e2e/pod_restart_test.go2
-rw-r--r--test/e2e/pod_rm_test.go2
-rw-r--r--test/e2e/pod_start_test.go2
-rw-r--r--test/e2e/pod_stats_test.go2
-rw-r--r--test/e2e/pod_stop_test.go2
-rw-r--r--test/e2e/pod_top_test.go2
-rw-r--r--test/e2e/port_test.go6
-rw-r--r--test/e2e/prune_test.go12
-rw-r--r--test/e2e/ps_test.go2
-rw-r--r--test/e2e/pull_test.go64
-rw-r--r--test/e2e/push_test.go44
-rw-r--r--test/e2e/restart_test.go2
-rw-r--r--test/e2e/rm_test.go2
-rw-r--r--test/e2e/rmi_test.go84
-rw-r--r--test/e2e/run_cgroup_parent_test.go2
-rw-r--r--test/e2e/run_cleanup_test.go2
-rw-r--r--test/e2e/run_cpu_test.go2
-rw-r--r--test/e2e/run_device_test.go2
-rw-r--r--test/e2e/run_dns_test.go2
-rw-r--r--test/e2e/run_entrypoint_test.go2
-rw-r--r--test/e2e/run_exit_test.go2
-rw-r--r--test/e2e/run_memory_test.go2
-rw-r--r--test/e2e/run_networking_test.go3
-rw-r--r--test/e2e/run_ns_test.go2
-rw-r--r--test/e2e/run_passwd_test.go2
-rw-r--r--test/e2e/run_privileged_test.go2
-rw-r--r--test/e2e/run_restart_test.go2
-rw-r--r--test/e2e/run_selinux_test.go2
-rw-r--r--test/e2e/run_signal_test.go2
-rw-r--r--test/e2e/run_staticip_test.go2
-rw-r--r--test/e2e/run_test.go27
-rw-r--r--test/e2e/run_userns_test.go2
-rw-r--r--test/e2e/run_volume_test.go2
-rw-r--r--test/e2e/runlabel_test.go2
-rw-r--r--test/e2e/save_test.go18
-rw-r--r--test/e2e/search_test.go33
-rw-r--r--test/e2e/start_test.go2
-rw-r--r--test/e2e/stats_test.go2
-rw-r--r--test/e2e/stop_test.go2
-rw-r--r--test/e2e/system_df_test.go5
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--test/e2e/tag_test.go18
-rw-r--r--test/e2e/top_test.go2
-rw-r--r--test/e2e/tree_test.go13
-rw-r--r--test/e2e/trust_test.go2
-rw-r--r--test/e2e/unshare_test.go2
-rw-r--r--test/e2e/version_test.go1
-rw-r--r--test/e2e/volume_create_test.go2
-rw-r--r--test/e2e/volume_inspect_test.go2
-rw-r--r--test/e2e/volume_ls_test.go2
-rw-r--r--test/e2e/volume_prune_test.go2
-rw-r--r--test/e2e/volume_rm_test.go2
-rw-r--r--test/e2e/wait_test.go2
-rw-r--r--test/utils/podmantest_test.go2
-rw-r--r--test/utils/utils.go24
-rw-r--r--transfer.md3
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/coreos/go-systemd/NOTICE5
-rw-r--r--vendor/github.com/coreos/go-systemd/README.md21
-rw-r--r--vendor/github.com/coreos/go-systemd/activation/files.go19
-rw-r--r--vendor/github.com/coreos/go-systemd/activation/listeners.go51
-rw-r--r--vendor/github.com/coreos/go-systemd/activation/packetconns.go5
-rw-r--r--vendor/github.com/coreos/go-systemd/dbus/dbus.go31
-rw-r--r--vendor/github.com/coreos/go-systemd/dbus/methods.go43
-rw-r--r--vendor/github.com/coreos/go-systemd/dbus/set.go2
-rw-r--r--vendor/github.com/coreos/go-systemd/dbus/subscription.go157
-rw-r--r--vendor/github.com/coreos/go-systemd/journal/journal.go7
-rw-r--r--vendor/github.com/coreos/go-systemd/sdjournal/journal.go134
-rw-r--r--vendor/github.com/coreos/go-systemd/sdjournal/read.go124
141 files changed, 1633 insertions, 672 deletions
diff --git a/.copr/prepare.sh b/.copr/prepare.sh
index a40e2aadb..57c380b02 100644
--- a/.copr/prepare.sh
+++ b/.copr/prepare.sh
@@ -29,4 +29,4 @@ fi
mkdir build/
git archive --prefix "libpod-${COMMIT_SHORT}/" --format "tar.gz" HEAD -o "build/libpod-${COMMIT_SHORT}.tar.gz"
git clone https://github.com/containers/conmon
-cd conmon && git checkout f02c053eb37010fc76d1e2966de7f2cb9f969ef2 && git archive --prefix "conmon/" --format "tar.gz" HEAD -o "../build/conmon.tar.gz"
+cd conmon && git checkout 59952292a3b07ac125575024ae21956efe0ecdfb && git archive --prefix "conmon/" --format "tar.gz" HEAD -o "../build/conmon.tar.gz"
diff --git a/Dockerfile b/Dockerfile
index f3afd5e25..4fc85e959 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -56,7 +56,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install conmon
-ENV CONMON_COMMIT f02c053eb37010fc76d1e2966de7f2cb9f969ef2
+ENV CONMON_COMMIT 59952292a3b07ac125575024ae21956efe0ecdfb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containers/conmon.git "$GOPATH/src/github.com/containers/conmon.git" \
diff --git a/Dockerfile.centos b/Dockerfile.centos
index 47f7182b6..159449c63 100644
--- a/Dockerfile.centos
+++ b/Dockerfile.centos
@@ -64,7 +64,7 @@ RUN set -x \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
# Install conmon
-ENV CONMON_COMMIT f02c053eb37010fc76d1e2966de7f2cb9f969ef2
+ENV CONMON_COMMIT 59952292a3b07ac125575024ae21956efe0ecdfb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containers/conmon.git "$GOPATH/src/github.com/containers/conmon.git" \
diff --git a/Dockerfile.fedora b/Dockerfile.fedora
index 290fe3f82..74a770a90 100644
--- a/Dockerfile.fedora
+++ b/Dockerfile.fedora
@@ -68,7 +68,7 @@ RUN set -x \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
# Install conmon
-ENV CONMON_COMMIT f02c053eb37010fc76d1e2966de7f2cb9f969ef2
+ENV CONMON_COMMIT 59952292a3b07ac125575024ae21956efe0ecdfb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containers/conmon.git "$GOPATH/src/github.com/containers/conmon.git" \
diff --git a/cmd/podman/cliconfig/create.go b/cmd/podman/cliconfig/create.go
index 49ab3d827..5fb2eed10 100644
--- a/cmd/podman/cliconfig/create.go
+++ b/cmd/podman/cliconfig/create.go
@@ -24,4 +24,5 @@ type BuildValues struct {
type CpValues struct {
PodmanCommand
Extract bool
+ Pause bool
}
diff --git a/cmd/podman/container.go b/cmd/podman/container.go
index 530175a55..839ae3a0e 100644
--- a/cmd/podman/container.go
+++ b/cmd/podman/container.go
@@ -54,6 +54,7 @@ var (
_checkpointCommand,
_containerExistsCommand,
_contInspectSubCommand,
+ _cpCommand,
_diffCommand,
_exportCommand,
_createCommand,
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 8240cc193..907bde4b9 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -13,10 +13,12 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/idtools"
+ securejoin "github.com/cyphar/filepath-securejoin"
digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -49,6 +51,7 @@ func init() {
cpCommand.Command = _cpCommand
flags := cpCommand.Flags()
flags.BoolVar(&cpCommand.Extract, "extract", false, "Extract the tar file into the destination directory.")
+ flags.BoolVar(&cpCommand.Pause, "pause", true, "Pause the container while copying")
cpCommand.SetHelpTemplate(HelpTemplate())
cpCommand.SetUsageTemplate(UsageTemplate())
rootCmd.AddCommand(cpCommand.Command)
@@ -66,11 +69,10 @@ func cpCmd(c *cliconfig.CpValues) error {
}
defer runtime.Shutdown(false)
- extract := c.Flag("extract").Changed
- return copyBetweenHostAndContainer(runtime, args[0], args[1], extract)
+ return copyBetweenHostAndContainer(runtime, args[0], args[1], c.Extract, c.Pause)
}
-func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string, extract bool) error {
+func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string, extract bool, pause bool) error {
srcCtr, srcPath := parsePath(runtime, src)
destCtr, destPath := parsePath(runtime, dest)
@@ -93,6 +95,38 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
return err
}
defer ctr.Unmount(false)
+
+ // We can't pause rootless containers.
+ if pause && rootless.IsRootless() {
+ state, err := ctr.State()
+ if err != nil {
+ return err
+ }
+ if state == libpod.ContainerStateRunning {
+ return errors.Errorf("cannot copy into running rootless container with pause set - pass --pause=false to force copying")
+ }
+ }
+
+ if pause && !rootless.IsRootless() {
+ if err := ctr.Pause(); err != nil {
+ // An invalid state error is fine.
+ // The container isn't running or is already paused.
+ // TODO: We can potentially start the container while
+ // the copy is running, which still allows a race where
+ // malicious code could mess with the symlink.
+ if errors.Cause(err) != libpod.ErrCtrStateInvalid {
+ return err
+ }
+ } else if err == nil {
+ // Only add the defer if we actually paused
+ defer func() {
+ if err := ctr.Unpause(); err != nil {
+ logrus.Errorf("Error unpausing container after copying: %v", err)
+ }
+ }()
+ }
+ }
+
user, err := getUser(mountPoint, ctr.User())
if err != nil {
return err
@@ -112,19 +146,38 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
var glob []string
if isFromHostToCtr {
if filepath.IsAbs(destPath) {
- destPath = filepath.Join(mountPoint, destPath)
-
+ cleanedPath, err := securejoin.SecureJoin(mountPoint, destPath)
+ if err != nil {
+ return err
+ }
+ destPath = cleanedPath
} else {
- if err = idtools.MkdirAllAndChownNew(filepath.Join(mountPoint, ctr.WorkingDir()), 0755, hostOwner); err != nil {
+ ctrWorkDir, err := securejoin.SecureJoin(mountPoint, ctr.WorkingDir())
+ if err != nil {
+ return err
+ }
+ if err = idtools.MkdirAllAndChownNew(ctrWorkDir, 0755, hostOwner); err != nil {
return errors.Wrapf(err, "error creating directory %q", destPath)
}
- destPath = filepath.Join(mountPoint, ctr.WorkingDir(), destPath)
+ cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), destPath))
+ if err != nil {
+ return err
+ }
+ destPath = cleanedPath
}
} else {
if filepath.IsAbs(srcPath) {
- srcPath = filepath.Join(mountPoint, srcPath)
+ cleanedPath, err := securejoin.SecureJoin(mountPoint, srcPath)
+ if err != nil {
+ return err
+ }
+ srcPath = cleanedPath
} else {
- srcPath = filepath.Join(mountPoint, ctr.WorkingDir(), srcPath)
+ cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), srcPath))
+ if err != nil {
+ return err
+ }
+ srcPath = cleanedPath
}
}
glob, err = filepath.Glob(srcPath)
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 5af05a11e..b4f21bd0c 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -4,11 +4,9 @@ package main
import (
"context"
- "io/ioutil"
"log/syslog"
"os"
"runtime/pprof"
- "strconv"
"strings"
"syscall"
@@ -120,18 +118,10 @@ func setupRootless(cmd *cobra.Command, args []string) error {
return errors.Wrapf(err, "could not get pause process pid file path")
}
- data, err := ioutil.ReadFile(pausePidPath)
- if err != nil && !os.IsNotExist(err) {
- return errors.Wrapf(err, "cannot read pause process pid file %s", pausePidPath)
- }
- if err == nil {
- pausePid, err := strconv.Atoi(string(data))
- if err != nil {
- return errors.Wrapf(err, "cannot parse pause pid file %s", pausePidPath)
- }
- became, ret, err := rootless.JoinUserAndMountNS(uint(pausePid), "")
+ if _, err := os.Stat(pausePidPath); err == nil {
+ became, ret, err := rootless.TryJoinFromFilePaths("", false, []string{pausePidPath})
if err != nil {
- logrus.Errorf("cannot join pause process pid %d. You may need to remove %s and stop all containers", pausePid, pausePidPath)
+ logrus.Errorf("cannot join pause process. You may need to remove %s and stop all containers", pausePidPath)
logrus.Errorf("you can use `system migrate` to recreate the pause process")
logrus.Errorf(err.Error())
os.Exit(1)
@@ -154,28 +144,13 @@ func setupRootless(cmd *cobra.Command, args []string) error {
logrus.Errorf(err.Error())
os.Exit(1)
}
- var became bool
- var ret int
- if len(ctrs) == 0 {
- became, ret, err = rootless.BecomeRootInUserNS(pausePidPath)
- } else {
- for _, ctr := range ctrs {
- data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
- if err != nil {
- logrus.Errorf(err.Error())
- continue
- }
- conmonPid, err := strconv.Atoi(string(data))
- if err != nil {
- logrus.Errorf(err.Error())
- continue
- }
- became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid), pausePidPath)
- if err == nil {
- break
- }
- }
+
+ paths := []string{}
+ for _, ctr := range ctrs {
+ paths = append(paths, ctr.Config().ConmonPidFile)
}
+
+ became, ret, err := rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
if err != nil {
logrus.Errorf(err.Error())
os.Exit(1)
@@ -185,6 +160,7 @@ func setupRootless(cmd *cobra.Command, args []string) error {
}
return nil
}
+
func setRLimits() error {
rlimits := new(syscall.Rlimit)
rlimits.Cur = 1048576
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index fe447d10d..55cc529e0 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -631,6 +631,10 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.C
memKernel, memReservation, memSwap, memSwappiness, memDisableOOMKiller := getMemoryInfo(spec)
pidsLimit := getPidsInfo(spec)
cgroup := getCgroup(spec)
+ logConfig := inspect.LogConfig{
+ config.LogDriver,
+ make(map[string]string),
+ }
data := &inspect.ContainerData{
ctrInspectData,
@@ -681,6 +685,7 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.C
Ulimits: createArtifact.Resources.Ulimit,
SecurityOpt: createArtifact.SecurityOpts,
Tmpfs: createArtifact.Tmpfs,
+ LogConfig: &logConfig,
},
&inspect.CtrConfig{
Hostname: spec.Hostname,
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index 3c9b17804..7cf230605 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -603,6 +603,11 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
memorySwappiness := c.Int64("memory-swappiness")
+ logDriver := libpod.KubernetesLogging
+ if c.Changed("log-driver") {
+ logDriver = c.String("log-driver")
+ }
+
config := &cc.CreateConfig{
Annotations: annotations,
BuiltinImgVolumes: ImageVolumes,
@@ -635,7 +640,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
IPAddress: c.String("ip"),
Labels: labels,
//LinkLocalIP: c.StringSlice("link-local-ip"), // Not implemented yet
- LogDriver: c.String("log-driver"),
+ LogDriver: logDriver,
LogDriverOpt: c.StringSlice("log-opt"),
MacAddress: c.String("mac-address"),
Name: c.String("name"),
diff --git a/completions/bash/podman b/completions/bash/podman
index 60d5fde52..49c8c0e52 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -486,6 +486,7 @@ __podman_complete_log_drivers() {
none
splunk
syslog
+ k8s-file
" -- "$cur" ) )
}
@@ -500,6 +501,7 @@ __podman_complete_log_options() {
local logentries_options="logentries-token"
local syslog_options="env labels syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag"
local splunk_options="env labels splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag"
+ local k8s_file_options="env labels max-file max-size"
local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options"
@@ -525,6 +527,9 @@ __podman_complete_log_options() {
json-file)
COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
;;
+ k8s-file)
+ COMPREPLY=( $( compgen -W "$k8s_file_options" -S = -- "$cur" ) )
+ ;;
logentries)
COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) )
;;
@@ -764,6 +769,10 @@ _podman_container_commit() {
_podman_commit
}
+_podman_container_cp() {
+ _podman_cp
+}
+
_podman_container_create() {
_podman_create
}
@@ -961,6 +970,7 @@ _podman_container() {
attach
checkpoint
commit
+ cp
create
diff
exec
@@ -2378,6 +2388,7 @@ _podman_cp() {
--help
-h
--extract
+ --pause
"
_complete_ "$boolean_options"
}
diff --git a/contrib/cirrus/container_test.sh b/contrib/cirrus/container_test.sh
index 1fd9551db..6bd925f17 100644
--- a/contrib/cirrus/container_test.sh
+++ b/contrib/cirrus/container_test.sh
@@ -35,7 +35,7 @@ options=0
noremote=0
install_tools_made=0
-while getopts "biptuv" opt; do
+while getopts "bitnuv" opt; do
case "$opt" in
b) build=1
options=1
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 985dbbc74..a1c11a5a6 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -35,7 +35,7 @@
# People want conmon packaged with the copr rpm
%global import_path_conmon github.com/containers/conmon
%global git_conmon https://%{import_path_conmon}
-%global commit_conmon f02c053eb37010fc76d1e2966de7f2cb9f969ef2
+%global commit_conmon 59952292a3b07ac125575024ae21956efe0ecdfb
%global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7})
Name: podman
diff --git a/docs/podman-build.1.md b/docs/podman-build.1.md
index 4a26c0981..e2769c2a9 100644
--- a/docs/podman-build.1.md
+++ b/docs/podman-build.1.md
@@ -174,6 +174,18 @@ This is a Docker specific option to disable image verification to a Docker
registry and is not supported by Podman. This flag is a NOOP and provided
soley for scripting compatibility.
+**--dns**=[]
+
+Set custom DNS servers
+
+**--dns-option**=[]
+
+Set custom DNS options
+
+**--dns-search**=[]
+
+Set custom DNS search domains
+
**--file, -f** *Dockerfile*
Specifies a Dockerfile which contains instructions for building the image,
diff --git a/docs/podman-container.1.md b/docs/podman-container.1.md
index 564d791fa..eb53149bd 100644
--- a/docs/podman-container.1.md
+++ b/docs/podman-container.1.md
@@ -17,6 +17,7 @@ The container command allows you to manage containers
| checkpoint | [podman-container-checkpoint(1)](podman-container-checkpoint.1.md) | Checkpoints one or more containers. |
| cleanup | [podman-container-cleanup(1)](podman-container-cleanup.1.md) | Cleanup containers network and mountpoints. |
| commit | [podman-commit(1)](podman-commit.1.md) | Create new image based on the changed container. |
+| cp | [podman-cp(1)](podman-cp.1.md) | Copy files/folders between a container and the local filesystem. |
| create | [podman-create(1)](podman-create.1.md) | Create a new container. |
| diff | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. |
| exec | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. |
diff --git a/docs/podman-cp.1.md b/docs/podman-cp.1.md
index 406dd51df..76fe57a9e 100644
--- a/docs/podman-cp.1.md
+++ b/docs/podman-cp.1.md
@@ -61,6 +61,10 @@ If you use a : in a local machine path, you must be explicit with a relative or
Extract the tar file into the destination directory. If the destination directory is not provided, extract the tar file into the root directory.
+**--pause**
+
+Pause the container while copying into it to avoid potential security issues around symlinks. Defaults to *true*.
+
## ALTERNATIVES
Podman has much stronger capabilities than just `podman cp` to achieve copy files between host and container.
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index cbd6d9a99..eafc6e27f 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -380,7 +380,7 @@ Read in a line delimited file of labels
Not implemented
-**--log-driver**="*json-file*"
+**--log-driver**="*k8s-file*"
Logging driver for the container. Currently not supported. This flag is a NOOP provided soley for scripting compatibility.
diff --git a/docs/podman-logs.1.md b/docs/podman-logs.1.md
index ce5d890ce..7feae1b76 100644
--- a/docs/podman-logs.1.md
+++ b/docs/podman-logs.1.md
@@ -50,7 +50,7 @@ Show timestamps in the log outputs. The default is false
To view a container's logs:
```
-podman logs b3f2436bdb978c1d33b1387afb5d7ba7e3243ed2ce908db431ac0069da86cb45
+podman logs -t b3f2436bdb978c1d33b1387afb5d7ba7e3243ed2ce908db431ac0069da86cb45
2017/08/07 10:16:21 Seeked /var/log/crio/pods/eb296bd56fab164d4d3cc46e5776b54414af3bf543d138746b25832c816b933b/c49f49788da14f776b7aa93fb97a2a71f9912f4e5a3e30397fca7dfe0ee0367b.log - &{Offset:0 Whence:0}
1:C 07 Aug 14:10:09.055 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
@@ -68,13 +68,13 @@ To view only the last two lines in container's log:
```
podman logs --tail 2 b3f2436bdb97
-1:M 07 Aug 14:10:09.056 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
-1:M 07 Aug 14:10:09.056 # Server initialized
+# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
+# Server initialized
```
To view a containers logs since a certain time:
```
-podman logs --since 2017-08-07T10:10:09.055837383-04:00 myserver
+podman logs -t --since 2017-08-07T10:10:09.055837383-04:00 myserver
1:M 07 Aug 14:10:09.055 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
1:M 07 Aug 14:10:09.055 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
@@ -87,8 +87,8 @@ To view a container's logs generated in the last 10 minutes:
```
podman logs --since 10m myserver
-1:M 07 Aug 14:10:09.055 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
-1:M 07 Aug 14:10:09.055 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
+# Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
+# Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
```
## SEE ALSO
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 78e8a5d6e..a7091e89a 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -394,7 +394,7 @@ Read in a line delimited file of labels
Not implemented
-**--log-driver**="*json-file*"
+**--log-driver**="*k8s-file*"
Logging driver for the container. Currently not supported. This flag is a NOOP provided soley for scripting compatibility.
diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh
index aed0042fb..12dd211f4 100755
--- a/hack/get_ci_vm.sh
+++ b/hack/get_ci_vm.sh
@@ -11,7 +11,7 @@ ${YEL}WARNING: This will not work without local sudo access to run podman,${NOR}
${YEL}possession of the proper ssh private key is required.${NOR}
"
# TODO: Many/most of these values should come from .cirrus.yml
-ZONE="us-central1-a"
+ZONE="${ZONE:-us-central1-a}"
CPUS="2"
MEMORY="4Gb"
DISK="200"
@@ -238,10 +238,14 @@ showrun --background tar cjf $TMPDIR/$TARBALL --warning=no-file-changed --exclud
trap delvm INT # Allow deleting VM if CTRL-C during create
# This fails if VM already exists: permit this usage to re-init
-echo -e "\n${YEL}Trying to creating a VM named $VMNAME\n${RED}(might take a minute/two. Errors ignored).${NOR}"
+echo -e "\n${YEL}Trying to creating a VM named $VMNAME${NOR}\n${YEL}in GCE region/zone $ZONE${NOR}"
+echo -e "For faster access, export ZONE='something-closer-<any letter>'"
+echo 'List of regions and zones: https://cloud.google.com/compute/docs/regions-zones/'
+echo -e "${RED}(might take a minute/two. Errors ignored).${NOR}"
showrun $CREATE_CMD || true # allow re-running commands below when "delete: N"
# Any subsequent failure should prompt for VM deletion
+trap - INT
trap delvm EXIT
echo -e "\n${YEL}Waiting up to 30s for ssh port to open${NOR}"
diff --git a/libpod/container.go b/libpod/container.go
index c07f4c78d..c8ab42fc3 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -51,6 +51,15 @@ const CgroupfsDefaultCgroupParent = "/libpod_parent"
// manager in libpod
const SystemdDefaultCgroupParent = "machine.slice"
+// JournaldLogging is the string conmon expects to specify journald logging
+const JournaldLogging = "journald"
+
+// KubernetesLogging is the string conmon expects when specifying to use the kubernetes logging format
+const KubernetesLogging = "k8s-file"
+
+// JSONLogging is the string conmon expects when specifying to use the json logging format
+const JSONLogging = "json-file"
+
// DefaultWaitInterval is the default interval between container status checks
// while waiting.
const DefaultWaitInterval = 250 * time.Millisecond
@@ -368,6 +377,8 @@ type ContainerConfig struct {
CgroupParent string `json:"cgroupParent"`
// LogPath log location
LogPath string `json:"logPath"`
+ // LogDriver driver for logs
+ LogDriver string `json:"logDriver"`
// File containing the conmon PID
ConmonPidFile string `json:"conmonPidFile,omitempty"`
// RestartPolicy indicates what action the container will take upon
@@ -775,6 +786,11 @@ func (c *Container) RestartRetries() uint {
return c.config.RestartRetries
}
+// LogDriver returns the log driver for this container
+func (c *Container) LogDriver() string {
+ return c.config.LogDriver
+}
+
// RuntimeName returns the name of the runtime
func (c *Container) RuntimeName() string {
return c.runtime.ociRuntime.name
diff --git a/libpod/container_log.go b/libpod/container_log.go
index e998ad316..374e5a1fc 100644
--- a/libpod/container_log.go
+++ b/libpod/container_log.go
@@ -19,6 +19,13 @@ const (
// zeroes are not trimmed, taken from
// https://github.com/golang/go/issues/19635
logTimeFormat = "2006-01-02T15:04:05.000000000Z07:00"
+
+ // partialLogType signifies a log line that exceeded the buffer
+ // length and needed to spill into a new line
+ partialLogType = "P"
+
+ // fullLogType signifies a log line is full
+ fullLogType = "F"
)
// LogOptions is the options you can use for logs
@@ -53,6 +60,15 @@ func (r *Runtime) Log(containers []*Container, options *LogOptions, logChannel c
// ReadLog reads a containers log based on the input options and returns loglines over a channel
func (c *Container) ReadLog(options *LogOptions, logChannel chan *LogLine) error {
+ // TODO Skip sending logs until journald logs can be read
+ // TODO make this not a magic string
+ if c.LogDriver() == JournaldLogging {
+ return c.readFromJournal(options, logChannel)
+ }
+ return c.readFromLogFile(options, logChannel)
+}
+
+func (c *Container) readFromLogFile(options *LogOptions, logChannel chan *LogLine) error {
t, tailLog, err := getLogFile(c.LogPath(), options)
if err != nil {
// If the log file does not exist, this is not fatal.
@@ -191,7 +207,7 @@ func newLogLine(line string) (*LogLine, error) {
if len(splitLine) < 4 {
return nil, errors.Errorf("'%s' is not a valid container log line", line)
}
- logTime, err := time.Parse(time.RFC3339Nano, splitLine[0])
+ logTime, err := time.Parse(logTimeFormat, splitLine[0])
if err != nil {
return nil, errors.Wrapf(err, "unable to convert time %s from container log", splitLine[0])
}
@@ -206,7 +222,7 @@ func newLogLine(line string) (*LogLine, error) {
// Partial returns a bool if the log line is a partial log type
func (l *LogLine) Partial() bool {
- if l.ParseLogType == "P" {
+ if l.ParseLogType == partialLogType {
return true
}
return false
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
new file mode 100644
index 000000000..e549673a6
--- /dev/null
+++ b/libpod/container_log_linux.go
@@ -0,0 +1,143 @@
+//+build linux
+//+build systemd
+
+package libpod
+
+import (
+ "fmt"
+ "io"
+ "strings"
+ "time"
+
+ journal "github.com/coreos/go-systemd/sdjournal"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // journaldLogOut is the journald priority signifying stdout
+ journaldLogOut = "6"
+
+ // journaldLogErr is the journald priority signifying stderr
+ journaldLogErr = "3"
+
+ // bufLen is the length of the buffer to read from a k8s-file
+ // formatted log line
+ // let's set it as 2k just to be safe if k8s-file format ever changes
+ bufLen = 16384
+)
+
+func (c *Container) readFromJournal(options *LogOptions, logChannel chan *LogLine) error {
+ var config journal.JournalReaderConfig
+ config.NumFromTail = options.Tail
+ config.Formatter = journalFormatter
+ defaultTime := time.Time{}
+ if options.Since != defaultTime {
+ // coreos/go-systemd/sdjournal doesn't correctly handle requests for data in the future
+ // return nothing instead of fasely printing
+ if time.Now().Before(options.Since) {
+ return nil
+ }
+ config.Since = time.Since(options.Since)
+ }
+ config.Matches = append(config.Matches, journal.Match{
+ Field: "CONTAINER_ID_FULL",
+ Value: c.ID(),
+ })
+ options.WaitGroup.Add(1)
+
+ r, err := journal.NewJournalReader(config)
+ if err != nil {
+ return err
+ }
+ if r == nil {
+ return errors.Errorf("journal reader creation failed")
+ }
+ if options.Tail == 0 {
+ r.Rewind()
+ }
+
+ if options.Follow {
+ go func() {
+ follower := FollowBuffer{logChannel}
+ err := r.Follow(nil, follower)
+ if err != nil {
+ logrus.Debugf(err.Error())
+ }
+ r.Close()
+ options.WaitGroup.Done()
+ return
+ }()
+ return nil
+ }
+
+ go func() {
+ bytes := make([]byte, bufLen)
+ // /me complains about no do-while in go
+ ec, err := r.Read(bytes)
+ for ec != 0 && err == nil {
+ // because we are reusing bytes, we need to make
+ // sure the old data doesn't get into the new line
+ bytestr := string(bytes[:ec])
+ logLine, err2 := newLogLine(bytestr)
+ if err2 != nil {
+ logrus.Error(err2)
+ continue
+ }
+ logChannel <- logLine
+ ec, err = r.Read(bytes)
+ }
+ if err != nil && err != io.EOF {
+ logrus.Error(err)
+ }
+ r.Close()
+ options.WaitGroup.Done()
+ }()
+ return nil
+}
+
+func journalFormatter(entry *journal.JournalEntry) (string, error) {
+ usec := entry.RealtimeTimestamp
+ tsString := time.Unix(0, int64(usec)*int64(time.Microsecond)).Format(logTimeFormat)
+ output := fmt.Sprintf("%s ", tsString)
+ priority, ok := entry.Fields["PRIORITY"]
+ if !ok {
+ return "", errors.Errorf("no PRIORITY field present in journal entry")
+ }
+ if priority == journaldLogOut {
+ output += "stdout "
+ } else if priority == journaldLogErr {
+ output += "stderr "
+ } else {
+ return "", errors.Errorf("unexpected PRIORITY field in journal entry")
+ }
+
+ // if CONTAINER_PARTIAL_MESSAGE is defined, the log type is "P"
+ if _, ok := entry.Fields["CONTAINER_PARTIAL_MESSAGE"]; ok {
+ output += fmt.Sprintf("%s ", partialLogType)
+ } else {
+ output += fmt.Sprintf("%s ", fullLogType)
+ }
+
+ // Finally, append the message
+ msg, ok := entry.Fields["MESSAGE"]
+ if !ok {
+ return "", fmt.Errorf("no MESSAGE field present in journal entry")
+ }
+ output += strings.TrimSpace(msg)
+ return output, nil
+}
+
+type FollowBuffer struct {
+ logChannel chan *LogLine
+}
+
+func (f FollowBuffer) Write(p []byte) (int, error) {
+ bytestr := string(p)
+ logLine, err := newLogLine(bytestr)
+ if err != nil {
+ return -1, err
+ }
+ f.logChannel <- logLine
+ return len(p), nil
+}
diff --git a/libpod/container_log_unsupported.go b/libpod/container_log_unsupported.go
new file mode 100644
index 000000000..0ec5740e2
--- /dev/null
+++ b/libpod/container_log_unsupported.go
@@ -0,0 +1,11 @@
+//+build !linux !systemd
+
+package libpod
+
+import (
+ "github.com/pkg/errors"
+)
+
+func (c *Container) readFromJournal(options *LogOptions, logChannel chan *LogLine) error {
+ return errors.Wrapf(ErrOSNotSupported, "Journald logging only enabled with systemd on linux")
+}
diff --git a/libpod/oci.go b/libpod/oci.go
index abc6214b9..7138108c5 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -367,8 +367,6 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty
args := []string{}
// TODO - should we maintain separate logpaths for exec sessions?
- args = append(args, "--log", c.LogPath())
-
args = append(args, "exec")
if cwd != "" {
@@ -402,7 +400,7 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty
args = append(args, "--env", envVar)
}
- // Append container ID and command
+ // Append container ID, name and command
args = append(args, c.ID())
args = append(args, cmd...)
diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go
index 1c1e4a203..7c1c18052 100644
--- a/libpod/oci_linux.go
+++ b/libpod/oci_linux.go
@@ -214,10 +214,10 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res
}
args = append(args, "-c", ctr.ID())
args = append(args, "-u", ctr.ID())
+ args = append(args, "-n", ctr.Name())
args = append(args, "-r", r.path)
args = append(args, "-b", ctr.bundlePath())
args = append(args, "-p", filepath.Join(ctr.state.RunDir, "pidfile"))
- args = append(args, "-l", ctr.LogPath())
args = append(args, "--exit-dir", r.exitsDir)
if ctr.config.ConmonPidFile != "" {
args = append(args, "--conmon-pidfile", ctr.config.ConmonPidFile)
@@ -237,6 +237,13 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res
if r.logSizeMax >= 0 {
args = append(args, "--log-size-max", fmt.Sprintf("%v", r.logSizeMax))
}
+
+ logDriver := KubernetesLogging
+ if ctr.LogDriver() != "" {
+ logDriver = ctr.LogDriver()
+ }
+ args = append(args, "-l", fmt.Sprintf("%s:%s", logDriver, ctr.LogPath()))
+
if r.noPivot {
args = append(args, "--no-pivot")
}
diff --git a/libpod/options.go b/libpod/options.go
index 7ec7dfe63..20aa51981 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -979,6 +979,27 @@ func WithStaticIP(ip net.IP) CtrCreateOption {
}
}
+// WithLogDriver sets the log driver for the container
+func WithLogDriver(driver string) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+ switch driver {
+ case "":
+ return errors.Wrapf(ErrInvalidArg, "log driver must be set")
+ case JournaldLogging, KubernetesLogging, JSONLogging:
+ break
+ default:
+ return errors.Wrapf(ErrInvalidArg, "invalid log driver")
+ }
+
+ ctr.config.LogDriver = driver
+
+ return nil
+ }
+}
+
// WithLogPath sets the path to the log file.
func WithLogPath(path string) CtrCreateOption {
return func(ctr *Container) error {
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index c7758055f..0c8d3edab 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -167,7 +167,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
}()
if rootless.IsRootless() && ctr.config.ConmonPidFile == "" {
- ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid")
+ ctr.config.ConmonPidFile = filepath.Join(ctr.state.RunDir, "conmon.pid")
}
// Go through named volumes and add them.
@@ -196,7 +196,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
}
}
- if ctr.config.LogPath == "" {
+ if ctr.config.LogPath == "" && ctr.config.LogDriver != JournaldLogging {
ctr.config.LogPath = filepath.Join(ctr.config.StaticDir, "ctr.log")
}
diff --git a/pkg/inspect/inspect.go b/pkg/inspect/inspect.go
index 693755aa8..2082bb3a6 100644
--- a/pkg/inspect/inspect.go
+++ b/pkg/inspect/inspect.go
@@ -103,7 +103,7 @@ type CtrConfig struct {
// LogConfig holds the log information for a container
type LogConfig struct {
- Type string `json:"Type"` // TODO
+ Type string `json:"Type"`
Config map[string]string `json:"Config"` //idk type, TODO
}
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 098ca7830..2356882e7 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -69,6 +69,19 @@ rootless_gid ()
static void
do_pause ()
{
+ int i;
+ struct sigaction act;
+ int const sig[] =
+ {
+ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, SIGPOLL,
+ SIGPROF, SIGVTALRM, SIGXCPU, SIGXFSZ, 0
+ };
+
+ act.sa_handler = SIG_IGN;
+
+ for (i = 0; sig[i]; i++)
+ sigaction (sig[i], &act, NULL);
+
prctl (PR_SET_NAME, "podman pause", NULL, NULL, NULL);
while (1)
pause ();
@@ -333,6 +346,26 @@ syscall_clone (unsigned long flags, void *child_stack)
#endif
}
+int
+reexec_in_user_namespace_wait (int pid, int options)
+{
+ pid_t p;
+ int status;
+
+ do
+ p = waitpid (pid, &status, 0);
+ while (p < 0 && errno == EINTR);
+
+ if (p < 0)
+ return -1;
+
+ if (WIFEXITED (status))
+ return WEXITSTATUS (status);
+ if (WIFSIGNALED (status))
+ return 128 + WTERMSIG (status);
+ return -1;
+}
+
static int
create_pause_process (const char *pause_pid_file_path, char **argv)
{
@@ -356,6 +389,8 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
while (r < 0 && errno == EINTR);
close (p[0]);
+ reexec_in_user_namespace_wait(r, 0);
+
return r == 1 && b == '0' ? 0 : -1;
}
else
@@ -560,8 +595,51 @@ check_proc_sys_userns_file (const char *path)
}
}
+static int
+copy_file_to_fd (const char *file_to_read, int outfd)
+{
+ char buf[512];
+ int fd;
+
+ fd = open (file_to_read, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ for (;;)
+ {
+ ssize_t r, w, t = 0;
+
+ do
+ r = read (fd, buf, sizeof buf);
+ while (r < 0 && errno == EINTR);
+ if (r < 0)
+ {
+ close (fd);
+ return r;
+ }
+
+ if (r == 0)
+ break;
+
+ while (t < r)
+ {
+ do
+ w = write (outfd, &buf[t], r - t);
+ while (w < 0 && errno == EINTR);
+ if (w < 0)
+ {
+ close (fd);
+ return w;
+ }
+ t += w;
+ }
+ }
+ close (fd);
+ return 0;
+}
+
int
-reexec_in_user_namespace (int ready, char *pause_pid_file_path)
+reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_read, int outputfd)
{
int ret;
pid_t pid;
@@ -574,6 +652,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
char *listen_pid = NULL;
bool do_socket_activation = false;
char *cwd = getcwd (NULL, 0);
+ sigset_t sigset, oldsigset;
if (cwd == NULL)
{
@@ -584,11 +663,11 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
listen_pid = getenv("LISTEN_PID");
listen_fds = getenv("LISTEN_FDS");
- if (listen_pid != NULL && listen_fds != NULL) {
- if (strtol(listen_pid, NULL, 10) == getpid()) {
- do_socket_activation = true;
+ if (listen_pid != NULL && listen_fds != NULL)
+ {
+ if (strtol(listen_pid, NULL, 10) == getpid())
+ do_socket_activation = true;
}
- }
sprintf (uid, "%d", geteuid ());
sprintf (gid, "%d", getegid ());
@@ -621,6 +700,22 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
return pid;
}
+ if (sigfillset (&sigset) < 0)
+ {
+ fprintf (stderr, "cannot fill sigset: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+ if (sigdelset (&sigset, SIGCHLD) < 0)
+ {
+ fprintf (stderr, "cannot sigdelset(SIGCHLD): %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+ if (sigprocmask (SIG_BLOCK, &sigset, &oldsigset) < 0)
+ {
+ fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+
argv = get_cmd_line_args (ppid);
if (argv == NULL)
{
@@ -628,11 +723,12 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
_exit (EXIT_FAILURE);
}
- if (do_socket_activation) {
- char s[32];
- sprintf (s, "%d", getpid());
- setenv ("LISTEN_PID", s, true);
- }
+ if (do_socket_activation)
+ {
+ char s[32];
+ sprintf (s, "%d", getpid());
+ setenv ("LISTEN_PID", s, true);
+ }
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
@@ -685,27 +781,20 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
while (ret < 0 && errno == EINTR);
close (ready);
- execvp (argv[0], argv);
-
- _exit (EXIT_FAILURE);
-}
-
-int
-reexec_in_user_namespace_wait (int pid)
-{
- pid_t p;
- int status;
+ if (sigprocmask (SIG_SETMASK, &oldsigset, NULL) < 0)
+ {
+ fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
- do
- p = waitpid (pid, &status, 0);
- while (p < 0 && errno == EINTR);
+ if (file_to_read && file_to_read[0])
+ {
+ ret = copy_file_to_fd (file_to_read, outputfd);
+ close (outputfd);
+ _exit (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ }
- if (p < 0)
- return -1;
+ execvp (argv[0], argv);
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- if (WIFSIGNALED (status))
- return 128 + WTERMSIG (status);
- return -1;
+ _exit (EXIT_FAILURE);
}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 9132c0fe5..d302b1777 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -26,8 +26,8 @@ import (
#include <stdlib.h>
extern uid_t rootless_uid();
extern uid_t rootless_gid();
-extern int reexec_in_user_namespace(int ready, char *pause_pid_file_path);
-extern int reexec_in_user_namespace_wait(int pid);
+extern int reexec_in_user_namespace(int ready, char *pause_pid_file_path, char *file_to_read, int fd);
+extern int reexec_in_user_namespace_wait(int pid, int options);
extern int reexec_userns_join(int userns, int mountns, char *pause_pid_file_path);
*/
import "C"
@@ -194,10 +194,24 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) {
}
}
-// JoinUserAndMountNS re-exec podman in a new userNS and join the user and mount
+func enableLinger(pausePid string) {
+ if pausePid == "" {
+ return
+ }
+ // If we are trying to write a pause pid file, make sure we can leave processes
+ // running longer than the user session.
+ err := exec.Command("loginctl", "enable-linger", fmt.Sprintf("%d", GetRootlessUID())).Run()
+ if err != nil {
+ logrus.Warnf("cannot run `loginctl enable-linger` for the current user: %v", err)
+ }
+}
+
+// joinUserAndMountNS re-exec podman in a new userNS and join the user and mount
// namespace of the specified PID without looking up its parent. Useful to join directly
// the conmon process.
-func JoinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
+func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
+ enableLinger(pausePid)
+
if os.Geteuid() == 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
return false, -1, nil
}
@@ -226,7 +240,7 @@ func JoinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
return false, -1, errors.Errorf("cannot re-exec process")
}
- ret := C.reexec_in_user_namespace_wait(pidC)
+ ret := C.reexec_in_user_namespace_wait(pidC, 0)
if ret < 0 {
return false, -1, errors.New("error waiting for the re-exec process")
}
@@ -234,11 +248,7 @@ func JoinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
return true, int(ret), nil
}
-// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
-// into a new user namespace and the return code from the re-executed podman process.
-// If podman was re-executed the caller needs to propagate the error code returned by the child
-// process.
-func BecomeRootInUserNS(pausePid string) (bool, int, error) {
+func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool, int, error) {
if os.Geteuid() == 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
if os.Getenv("_CONTAINERS_USERNS_CONFIGURED") == "init" {
return false, 0, runInUser()
@@ -249,6 +259,13 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
cPausePid := C.CString(pausePid)
defer C.free(unsafe.Pointer(cPausePid))
+ cFileToRead := C.CString(fileToRead)
+ defer C.free(unsafe.Pointer(cFileToRead))
+ var fileOutputFD C.int
+ if fileOutput != nil {
+ fileOutputFD = C.int(fileOutput.Fd())
+ }
+
runtime.LockOSThread()
defer runtime.UnlockOSThread()
@@ -262,7 +279,7 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
defer w.Close()
defer w.Write([]byte("0"))
- pidC := C.reexec_in_user_namespace(C.int(r.Fd()), cPausePid)
+ pidC := C.reexec_in_user_namespace(C.int(r.Fd()), cPausePid, cFileToRead, fileOutputFD)
pid := int(pidC)
if pid < 0 {
return false, -1, errors.Errorf("cannot re-exec process")
@@ -328,6 +345,10 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
return false, -1, errors.Wrapf(err, "read from sync pipe")
}
+ if fileOutput != nil {
+ return true, 0, nil
+ }
+
if b[0] == '2' {
// We have lost the race for writing the PID file, as probably another
// process created a namespace and wrote the PID.
@@ -336,7 +357,7 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
if err == nil {
pid, err := strconv.ParseUint(string(data), 10, 0)
if err == nil {
- return JoinUserAndMountNS(uint(pid), "")
+ return joinUserAndMountNS(uint(pid), "")
}
}
return false, -1, errors.Wrapf(err, "error setting up the process")
@@ -368,10 +389,96 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
}
}()
- ret := C.reexec_in_user_namespace_wait(pidC)
+ ret := C.reexec_in_user_namespace_wait(pidC, 0)
if ret < 0 {
return false, -1, errors.New("error waiting for the re-exec process")
}
return true, int(ret), nil
}
+
+// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
+// into a new user namespace and the return code from the re-executed podman process.
+// If podman was re-executed the caller needs to propagate the error code returned by the child
+// process.
+func BecomeRootInUserNS(pausePid string) (bool, int, error) {
+ enableLinger(pausePid)
+ return becomeRootInUserNS(pausePid, "", nil)
+}
+
+// TryJoinFromFilePaths attempts to join the namespaces of the pid files in paths.
+// This is useful when there are already running containers and we
+// don't have a pause process yet. We can use the paths to the conmon
+// processes to attempt joining their namespaces.
+// If needNewNamespace is set, the file is read from a temporary user
+// namespace, this is useful for containers that are running with a
+// different uidmap and the unprivileged user has no way to read the
+// file owned by the root in the container.
+func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []string) (bool, int, error) {
+ if len(paths) == 0 {
+ return BecomeRootInUserNS(pausePidPath)
+ }
+
+ var lastErr error
+ var pausePid int
+
+ for _, path := range paths {
+ if !needNewNamespace {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+
+ pausePid, err = strconv.Atoi(string(data))
+ if err != nil {
+ lastErr = errors.Wrapf(err, "cannot parse file %s", path)
+ continue
+ }
+
+ lastErr = nil
+ break
+ } else {
+ fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+
+ r, w := os.NewFile(uintptr(fds[0]), "read file"), os.NewFile(uintptr(fds[1]), "write file")
+
+ defer w.Close()
+ defer r.Close()
+
+ if _, _, err := becomeRootInUserNS("", path, w); err != nil {
+ lastErr = err
+ continue
+ }
+
+ w.Close()
+ defer func() {
+ r.Close()
+ C.reexec_in_user_namespace_wait(-1, 0)
+ }()
+
+ b := make([]byte, 32)
+
+ n, err := r.Read(b)
+ if err != nil {
+ lastErr = errors.Wrapf(err, "cannot read %s\n", path)
+ continue
+ }
+
+ pausePid, err = strconv.Atoi(string(b[:n]))
+ if err == nil {
+ lastErr = nil
+ break
+ }
+ }
+ }
+ if lastErr != nil {
+ return false, 0, lastErr
+ }
+
+ return joinUserAndMountNS(uint(pausePid), pausePidPath)
+}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
index 221baff97..c063adee5 100644
--- a/pkg/rootless/rootless_unsupported.go
+++ b/pkg/rootless/rootless_unsupported.go
@@ -29,10 +29,14 @@ func GetRootlessGID() int {
return -1
}
-// JoinUserAndMountNS re-exec podman in a new userNS and join the user and mount
-// namespace of the specified PID without looking up its parent. Useful to join directly
-// the conmon process. It is a convenience function for JoinUserAndMountNSWithOpts
-// with a default configuration.
-func JoinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
+// TryJoinFromFilePaths attempts to join the namespaces of the pid files in paths.
+// This is useful when there are already running containers and we
+// don't have a pause process yet. We can use the paths to the conmon
+// processes to attempt joining their namespaces.
+// If needNewNamespace is set, the file is read from a temporary user
+// namespace, this is useful for containers that are running with a
+// different uidmap and the unprivileged user has no way to read the
+// file owned by the root in the container.
+func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []string) (bool, int, error) {
return false, -1, errors.New("this function is not supported on this os")
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 9979e773c..e4501aaac 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -319,6 +319,9 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
if logPath != "" {
options = append(options, libpod.WithLogPath(logPath))
}
+
+ options = append(options, libpod.WithLogDriver(c.LogDriver))
+
if c.IPAddress != "" {
ip := net.ParseIP(c.IPAddress)
if ip == nil {
diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go
index a843fe7ff..7233d169c 100644
--- a/test/e2e/attach_test.go
+++ b/test/e2e/attach_test.go
@@ -26,7 +26,7 @@ var _ = Describe("Podman attach", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index c2f5a592c..95ec21433 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -28,7 +28,7 @@ var _ = Describe("Podman checkpoint", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
// Check if the runtime implements checkpointing. Currently only
// runc's checkpoint/restore implementation is supported.
cmd := exec.Command(podmanTest.OCIRuntime, "checkpoint", "-h")
@@ -221,7 +221,6 @@ var _ = Describe("Podman checkpoint", func() {
})
It("podman checkpoint container with established tcp connections", func() {
- podmanTest.RestoreArtifact(redis)
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", redis})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go
index bf20ac999..50577fdfb 100644
--- a/test/e2e/commit_test.go
+++ b/test/e2e/commit_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman commit", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 3c7675b35..0a388dc42 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -100,12 +100,23 @@ var _ = SynchronizedBeforeSuite(func() []byte {
}
}
+ // make cache dir
+ if err := os.MkdirAll(ImageCacheDir, 0777); err != nil {
+ fmt.Printf("%q\n", err)
+ os.Exit(1)
+ }
+
for _, image := range CACHE_IMAGES {
if err := podman.CreateArtifact(image); err != nil {
fmt.Printf("%q\n", err)
os.Exit(1)
}
}
+
+ // If running localized tests, the cache dir is created and populated. if the
+ // tests are remote, this is a no-op
+ populateCache(podman)
+
host := GetHostDistributionInfo()
if host.Distribution == "rhel" && strings.HasPrefix(host.Version, "7") {
f, err := os.OpenFile("/proc/sys/user/max_user_namespaces", os.O_WRONLY, 0644)
@@ -136,53 +147,29 @@ func (p *PodmanTestIntegration) Setup() {
p.ArtifactPath = ARTIFACT_DIR
}
-// var _ = BeforeSuite(func() {
-// cwd, _ := os.Getwd()
-// INTEGRATION_ROOT = filepath.Join(cwd, "../../")
-// podman := PodmanTestCreate("/tmp")
-// podman.ArtifactPath = ARTIFACT_DIR
-// if _, err := os.Stat(ARTIFACT_DIR); os.IsNotExist(err) {
-// if err = os.Mkdir(ARTIFACT_DIR, 0777); err != nil {
-// fmt.Printf("%q\n", err)
-// os.Exit(1)
-// }
-// }
-// })
-// for _, image := range CACHE_IMAGES {
-// if err := podman.CreateArtifact(image); err != nil {
-// fmt.Printf("%q\n", err)
-// os.Exit(1)
-// }
-// }
-// host := GetHostDistributionInfo()
-// if host.Distribution == "rhel" && strings.HasPrefix(host.Version, "7") {
-// f, err := os.OpenFile("/proc/sys/user/max_user_namespaces", os.O_WRONLY, 0644)
-// if err != nil {
-// fmt.Println("Unable to enable userspace on RHEL 7")
-// os.Exit(1)
-// }
-// _, err = f.WriteString("15000")
-// if err != nil {
-// fmt.Println("Unable to enable userspace on RHEL 7")
-// os.Exit(1)
-// }
-// f.Close()
-// }
-// path, err := ioutil.TempDir("", "libpodlock")
-// if err != nil {
-// fmt.Println(err)
-// os.Exit(1)
-// }
-// LockTmpDir = path
-// })
-
-var _ = AfterSuite(func() {
- sort.Sort(testResultsSortedLength{testResults})
- fmt.Println("integration timing results")
- for _, result := range testResults {
- fmt.Printf("%s\t\t%f\n", result.name, result.length)
- }
-})
+var _ = SynchronizedAfterSuite(func() {},
+ func() {
+ sort.Sort(testResultsSortedLength{testResults})
+ fmt.Println("integration timing results")
+ for _, result := range testResults {
+ fmt.Printf("%s\t\t%f\n", result.name, result.length)
+ }
+
+ // previous crio-run
+ tempdir, err := CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest := PodmanTestCreate(tempdir)
+
+ if err := os.RemoveAll(podmanTest.CrioRoot); err != nil {
+ fmt.Printf("%q\n", err)
+ }
+
+ // for localized tests, this removes the image cache dir and for remote tests
+ // this is a no-op
+ removeCache()
+ })
// PodmanTestCreate creates a PodmanTestIntegration instance for the tests
func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
@@ -244,12 +231,18 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
os.Setenv("DISABLE_HC_SYSTEMD", "true")
CNIConfigDir := "/etc/cni/net.d"
+ storageFs := STORAGE_FS
+ if rootless.IsRootless() {
+ storageFs = ROOTLESS_STORAGE_FS
+ }
p := &PodmanTestIntegration{
PodmanTest: PodmanTest{
- PodmanBinary: podmanBinary,
- ArtifactPath: ARTIFACT_DIR,
- TempDir: tempDir,
- RemoteTest: remote,
+ PodmanBinary: podmanBinary,
+ ArtifactPath: ARTIFACT_DIR,
+ TempDir: tempDir,
+ RemoteTest: remote,
+ ImageCacheFS: storageFs,
+ ImageCacheDir: ImageCacheDir,
},
ConmonBinary: conmonBinary,
CrioRoot: filepath.Join(tempDir, "crio"),
@@ -304,10 +297,10 @@ func (p *PodmanTestIntegration) CreateArtifact(image string) error {
dest := strings.Split(image, "/")
destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
if _, err := os.Stat(destName); os.IsNotExist(err) {
- pull := p.Podman([]string{"pull", image})
+ pull := p.PodmanNoCache([]string{"pull", image})
pull.Wait(90)
- save := p.Podman([]string{"save", "-o", destName, image})
+ save := p.PodmanNoCache([]string{"save", "-o", destName, image})
save.Wait(90)
fmt.Printf("\n")
} else {
@@ -390,7 +383,7 @@ func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers
dockerfilePath := filepath.Join(p.TempDir, "Dockerfile")
err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755)
Expect(err).To(BeNil())
- session := p.Podman([]string{"build", "--layers=" + layers, "-t", imageName, "--file", dockerfilePath, p.TempDir})
+ session := p.PodmanNoCache([]string{"build", "--layers=" + layers, "-t", imageName, "--file", dockerfilePath, p.TempDir})
session.Wait(120)
Expect(session.ExitCode()).To(Equal(0))
}
@@ -465,7 +458,7 @@ func (p *PodmanTestIntegration) PullImages(images []string) error {
// PullImage pulls a single image
// TODO should the timeout be configurable?
func (p *PodmanTestIntegration) PullImage(image string) error {
- session := p.Podman([]string{"pull", image})
+ session := p.PodmanNoCache([]string{"pull", image})
session.Wait(60)
Expect(session.ExitCode()).To(Equal(0))
return nil
@@ -508,3 +501,9 @@ func (p *PodmanTestIntegration) RunTopContainerInPod(name, pod string) *PodmanSe
podmanArgs = append(podmanArgs, "-d", ALPINE, "top")
return p.Podman(podmanArgs)
}
+
+func (p *PodmanTestIntegration) ImageExistsInMainStore(idOrName string) bool {
+ results := p.PodmanNoCache([]string{"image", "exists", idOrName})
+ results.WaitWithDefaultTimeout()
+ return Expect(results.ExitCode()).To(Equal(0))
+}
diff --git a/test/e2e/config.go b/test/e2e/config.go
index 3fdb9e116..5e0000e09 100644
--- a/test/e2e/config.go
+++ b/test/e2e/config.go
@@ -7,4 +7,5 @@ var (
infra = "k8s.gcr.io/pause:3.1"
BB = "docker.io/library/busybox:latest"
healthcheck = "docker.io/libpod/alpine_healthcheck:latest"
+ ImageCacheDir = "/tmp/podman/imagecachedir"
)
diff --git a/test/e2e/config_amd64.go b/test/e2e/config_amd64.go
index d02de7a6e..01aa8445a 100644
--- a/test/e2e/config_amd64.go
+++ b/test/e2e/config_amd64.go
@@ -1,7 +1,9 @@
package integration
var (
+ STORAGE_FS = "vfs"
STORAGE_OPTIONS = "--storage-driver vfs"
+ ROOTLESS_STORAGE_FS = "vfs"
ROOTLESS_STORAGE_OPTIONS = "--storage-driver vfs"
CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, registry, infra, labels, healthcheck}
nginx = "quay.io/libpod/alpine_nginx:latest"
diff --git a/test/e2e/config_ppc64le.go b/test/e2e/config_ppc64le.go
index d1737fa6f..569a34efb 100644
--- a/test/e2e/config_ppc64le.go
+++ b/test/e2e/config_ppc64le.go
@@ -1,7 +1,9 @@
package integration
var (
+ STORAGE_FS = "overlay"
STORAGE_OPTIONS = "--storage-driver overlay"
+ ROOTLESS_STORAGE_FS = "vfs"
ROOTLESS_STORAGE_OPTIONS = "--storage-driver vfs"
CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, infra, labels}
nginx = "quay.io/libpod/alpine_nginx-ppc64le:latest"
diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go
index f8df5d3d0..983d61b58 100644
--- a/test/e2e/cp_test.go
+++ b/test/e2e/cp_test.go
@@ -28,7 +28,7 @@ var _ = Describe("Podman cp", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -42,14 +42,15 @@ var _ = Describe("Podman cp", func() {
srcPath := filepath.Join(podmanTest.RunRoot, "cp_test.txt")
dstPath := filepath.Join(podmanTest.RunRoot, "cp_from_container")
fromHostToContainer := []byte("copy from host to container")
- err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644)
- Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"create", ALPINE, "cat", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
name := session.OutputToString()
+ err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644)
+ Expect(err).To(BeNil())
+
session = podmanTest.Podman([]string{"cp", srcPath, name + ":foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -63,16 +64,17 @@ var _ = Describe("Podman cp", func() {
srcPath := filepath.Join(podmanTest.RunRoot, "cp_test.txt")
dstDir := filepath.Join(podmanTest.RunRoot, "receive")
fromHostToContainer := []byte("copy from host to container directory")
- err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644)
- Expect(err).To(BeNil())
- err = os.Mkdir(dstDir, 0755)
- Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foodir/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
name := session.OutputToString()
+ err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644)
+ Expect(err).To(BeNil())
+ err = os.Mkdir(dstDir, 0755)
+ Expect(err).To(BeNil())
+
session = podmanTest.Podman([]string{"cp", srcPath, name + ":foodir/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -87,14 +89,15 @@ var _ = Describe("Podman cp", func() {
It("podman cp dir to dir", func() {
testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir")
- err := os.Mkdir(testDirPath, 0755)
- Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"create", ALPINE, "ls", "/foodir"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
name := session.OutputToString()
+ err := os.Mkdir(testDirPath, 0755)
+ Expect(err).To(BeNil())
+
session = podmanTest.Podman([]string{"cp", testDirPath, name + ":/foodir"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -105,6 +108,11 @@ var _ = Describe("Podman cp", func() {
})
It("podman cp stdin/stdout", func() {
+ session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ name := session.OutputToString()
+
testDirPath := filepath.Join(podmanTest.RunRoot, "TestDir")
err := os.Mkdir(testDirPath, 0755)
Expect(err).To(BeNil())
@@ -112,11 +120,6 @@ var _ = Describe("Podman cp", func() {
_, err = cmd.Output()
Expect(err).To(BeNil())
- session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foo"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
- name := session.OutputToString()
-
data, err := ioutil.ReadFile("foo.tar.gz")
reader := strings.NewReader(string(data))
cmd.Stdin = reader
@@ -133,6 +136,10 @@ var _ = Describe("Podman cp", func() {
})
It("podman cp tar", func() {
+ session := podmanTest.Podman([]string{"create", "--name", "testctr", ALPINE, "ls", "-l", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
path, err := os.Getwd()
Expect(err).To(BeNil())
testDirPath := filepath.Join(path, "TestDir")
@@ -142,10 +149,6 @@ var _ = Describe("Podman cp", func() {
_, err = cmd.Output()
Expect(err).To(BeNil())
- session := podmanTest.Podman([]string{"create", "--name", "testctr", ALPINE, "ls", "-l", "foo"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
-
session = podmanTest.Podman([]string{"cp", "file.tar", "testctr:/foo/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -158,4 +161,27 @@ var _ = Describe("Podman cp", func() {
os.Remove("file.tar")
os.RemoveAll(testDirPath)
})
+
+ It("podman cp symlink", func() {
+ srcPath := filepath.Join(podmanTest.RunRoot, "cp_test.txt")
+ fromHostToContainer := []byte("copy from host to container")
+ err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ name := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"exec", name, "ln", "-s", "/tmp", "/test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"cp", "--pause=false", srcPath, name + ":/test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ _, err = os.Stat("/tmp/cp_test.txt")
+ Expect(err).To(Not(BeNil()))
+ })
})
diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go
index 6c4ca1cb8..11301856b 100644
--- a/test/e2e/create_staticip_test.go
+++ b/test/e2e/create_staticip_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman create with --ip flag", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
// Cleanup the CNI networks used by the tests
os.RemoveAll("/var/lib/cni/networks/podman")
})
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index f3367337e..e2b4a7cf4 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman create", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/diff_test.go b/test/e2e/diff_test.go
index 920b920c0..0f53d9bc8 100644
--- a/test/e2e/diff_test.go
+++ b/test/e2e/diff_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman diff", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go
index 5ac5c9860..c5eedda3c 100644
--- a/test/e2e/events_test.go
+++ b/test/e2e/events_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman events", func() {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 2a10e52b1..f42831ebb 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman exec", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -123,7 +123,6 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec with user only in container", func() {
- podmanTest.RestoreArtifact(fedoraMinimal)
testUser := "test123"
setup := podmanTest.Podman([]string{"run", "--name", "test1", "-d", fedoraMinimal, "sleep", "60"})
setup.WaitWithDefaultTimeout()
diff --git a/test/e2e/exists_test.go b/test/e2e/exists_test.go
index 71c6c1820..1486427c5 100644
--- a/test/e2e/exists_test.go
+++ b/test/e2e/exists_test.go
@@ -48,7 +48,6 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(1))
})
It("podman container exists in local storage by name", func() {
- SkipIfRemote()
setup := podmanTest.RunTopContainer("foobar")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
@@ -58,7 +57,6 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman container exists in local storage by container ID", func() {
- SkipIfRemote()
setup := podmanTest.RunTopContainer("")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
@@ -69,7 +67,6 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman container exists in local storage by short container ID", func() {
- SkipIfRemote()
setup := podmanTest.RunTopContainer("")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
@@ -80,14 +77,12 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman container does not exist in local storage", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"container", "exists", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(1))
})
It("podman pod exists in local storage by name", func() {
- SkipIfRemote()
setup, rc, _ := podmanTest.CreatePod("foobar")
setup.WaitWithDefaultTimeout()
Expect(rc).To(Equal(0))
@@ -97,7 +92,6 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pod exists in local storage by container ID", func() {
- SkipIfRemote()
setup, rc, podID := podmanTest.CreatePod("")
setup.WaitWithDefaultTimeout()
Expect(rc).To(Equal(0))
@@ -107,7 +101,6 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pod exists in local storage by short container ID", func() {
- SkipIfRemote()
setup, rc, podID := podmanTest.CreatePod("")
setup.WaitWithDefaultTimeout()
Expect(rc).To(Equal(0))
@@ -117,6 +110,7 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pod does not exist in local storage", func() {
+ // The exit code for non-existing pod is incorrect (125 vs 1)
SkipIfRemote()
session := podmanTest.Podman([]string{"pod", "exists", "foobar"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/export_test.go b/test/e2e/export_test.go
index 71ddb518a..8406b0e73 100644
--- a/test/e2e/export_test.go
+++ b/test/e2e/export_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman export", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 2f0af7e5f..95d46476d 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman generate kube", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index 940e894bc..5bb040206 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman generate systemd", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index 60be86ebc..be54cf1bd 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -24,7 +24,8 @@ var _ = Describe("Podman healthcheck run", func() {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
- podmanTest.RestoreAllArtifacts()
+ podmanTest.Setup()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -42,7 +43,6 @@ var _ = Describe("Podman healthcheck run", func() {
})
It("podman healthcheck on valid container", func() {
- podmanTest.RestoreArtifact(healthcheck)
session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -63,7 +63,6 @@ var _ = Describe("Podman healthcheck run", func() {
})
It("podman healthcheck on stopped container", func() {
- podmanTest.RestoreArtifact(healthcheck)
session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/history_test.go b/test/e2e/history_test.go
index 9e519dd9c..231e8b856 100644
--- a/test/e2e/history_test.go
+++ b/test/e2e/history_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman history", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go
index 23455163b..07d61e885 100644
--- a/test/e2e/images_test.go
+++ b/test/e2e/images_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman images", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -44,14 +44,15 @@ var _ = Describe("Podman images", func() {
})
It("podman images with no images prints header", func() {
- rmi := podmanTest.Podman([]string{"rmi", "-a"})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", "-a"})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"images"})
+ session := podmanTest.PodmanNoCache([]string{"images"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(1))
+ Expect(session.LineInOutputContains("REPOSITORY")).To(BeTrue())
})
It("podman image List", func() {
@@ -65,15 +66,16 @@ var _ = Describe("Podman images", func() {
It("podman images with multiple tags", func() {
// tag "docker.io/library/alpine:latest" to "foo:{a,b,c}"
- session := podmanTest.Podman([]string{"tag", ALPINE, "foo:a", "foo:b", "foo:c"})
+ podmanTest.RestoreAllArtifacts()
+ session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a", "foo:b", "foo:c"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// tag "foo:c" to "bar:{a,b}"
- session = podmanTest.Podman([]string{"tag", "foo:c", "bar:a", "bar:b"})
+ session = podmanTest.PodmanNoCache([]string{"tag", "foo:c", "bar:a", "bar:b"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// check all previous and the newly tagged images
- session = podmanTest.Podman([]string{"images"})
+ session = podmanTest.PodmanNoCache([]string{"images"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session.LineInOutputContainsTag("docker.io/library/alpine", "latest")
@@ -83,7 +85,7 @@ var _ = Describe("Podman images", func() {
session.LineInOutputContainsTag("foo", "c")
session.LineInOutputContainsTag("bar", "a")
session.LineInOutputContainsTag("bar", "b")
- session = podmanTest.Podman([]string{"images", "-qn"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-qn"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2))
@@ -119,19 +121,20 @@ var _ = Describe("Podman images", func() {
})
It("podman images filter by image name", func() {
- session := podmanTest.Podman([]string{"images", "-q", ALPINE})
+ podmanTest.RestoreAllArtifacts()
+ session := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(1))
- session = podmanTest.Podman([]string{"tag", ALPINE, "foo:a"})
+ session = podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"tag", BB, "foo:b"})
+ session = podmanTest.PodmanNoCache([]string{"tag", BB, "foo:b"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q", "foo"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2))
@@ -141,24 +144,25 @@ var _ = Describe("Podman images", func() {
if podmanTest.RemoteTest {
Skip("Does not work on remote client")
}
- result := podmanTest.Podman([]string{"images", "-q", "-f", "reference=docker.io*"})
+ podmanTest.RestoreAllArtifacts()
+ result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=docker.io*"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(Equal(2))
- retapline := podmanTest.Podman([]string{"images", "-f", "reference=a*pine"})
+ retapline := podmanTest.PodmanNoCache([]string{"images", "-f", "reference=a*pine"})
retapline.WaitWithDefaultTimeout()
Expect(retapline.ExitCode()).To(Equal(0))
Expect(len(retapline.OutputToStringArray())).To(Equal(2))
Expect(retapline.LineInOutputContains("alpine"))
- retapline = podmanTest.Podman([]string{"images", "-f", "reference=alpine"})
+ retapline = podmanTest.PodmanNoCache([]string{"images", "-f", "reference=alpine"})
retapline.WaitWithDefaultTimeout()
Expect(retapline.ExitCode()).To(Equal(0))
Expect(len(retapline.OutputToStringArray())).To(Equal(2))
Expect(retapline.LineInOutputContains("alpine"))
- retnone := podmanTest.Podman([]string{"images", "-q", "-f", "reference=bogus"})
+ retnone := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=bogus"})
retnone.WaitWithDefaultTimeout()
Expect(retnone.ExitCode()).To(Equal(0))
Expect(len(retnone.OutputToStringArray())).To(Equal(0))
@@ -182,14 +186,15 @@ RUN apk update && apk add man
if podmanTest.RemoteTest {
Skip("Does not work on remote client")
}
- rmi := podmanTest.Podman([]string{"rmi", "busybox"})
+ podmanTest.RestoreAllArtifacts()
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", "busybox"})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
dockerfile := `FROM docker.io/library/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
- result := podmanTest.Podman([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"})
+ result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(Equal(0))
@@ -199,14 +204,15 @@ RUN apk update && apk add man
if podmanTest.RemoteTest {
Skip("Does not work on remote client")
}
- rmi := podmanTest.Podman([]string{"image", "rm", "busybox"})
+ podmanTest.RestoreAllArtifacts()
+ rmi := podmanTest.PodmanNoCache([]string{"image", "rm", "busybox"})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
dockerfile := `FROM docker.io/library/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
- result := podmanTest.Podman([]string{"image", "list", "-q", "-f", "after=docker.io/library/alpine:latest"})
+ result := podmanTest.PodmanNoCache([]string{"image", "list", "-q", "-f", "after=docker.io/library/alpine:latest"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(Equal(0))
@@ -282,18 +288,19 @@ RUN apk update && apk add man
if podmanTest.RemoteTest {
Skip("Does not work on remote client")
}
+ podmanTest.RestoreAllArtifacts()
dockerfile := `FROM docker.io/library/alpine:latest
RUN mkdir hello
RUN touch test.txt
ENV foo=bar
`
podmanTest.BuildImage(dockerfile, "test", "true")
- session := podmanTest.Podman([]string{"images"})
+ session := podmanTest.PodmanNoCache([]string{"images"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(4))
- session2 := podmanTest.Podman([]string{"images", "--all"})
+ session2 := podmanTest.PodmanNoCache([]string{"images", "--all"})
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
Expect(len(session2.OutputToStringArray())).To(Equal(6))
diff --git a/test/e2e/import_test.go b/test/e2e/import_test.go
index e819d819c..84a91a783 100644
--- a/test/e2e/import_test.go
+++ b/test/e2e/import_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman import", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -62,14 +62,11 @@ var _ = Describe("Podman import", func() {
export.WaitWithDefaultTimeout()
Expect(export.ExitCode()).To(Equal(0))
- importImage := podmanTest.Podman([]string{"import", outfile})
+ importImage := podmanTest.PodmanNoCache([]string{"import", outfile})
importImage.WaitWithDefaultTimeout()
Expect(importImage.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"images", "-q"})
- results.WaitWithDefaultTimeout()
- Expect(results.ExitCode()).To(Equal(0))
- Expect(len(results.OutputToStringArray())).To(Equal(3))
+ Expect(podmanTest.ImageExistsInMainStore(importImage.OutputToString())).To(BeTrue())
})
It("podman import with message flag", func() {
diff --git a/test/e2e/init_test.go b/test/e2e/init_test.go
index 5865930a5..919fe4abf 100644
--- a/test/e2e/init_test.go
+++ b/test/e2e/init_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman init", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go
index 34328828f..ccd8602c4 100644
--- a/test/e2e/inspect_test.go
+++ b/test/e2e/inspect_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman inspect", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go
index 3286180a4..017fe4a3f 100644
--- a/test/e2e/kill_test.go
+++ b/test/e2e/kill_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman kill", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/libpod_suite_remoteclient_test.go b/test/e2e/libpod_suite_remoteclient_test.go
index b7fd8537d..c8210f7d1 100644
--- a/test/e2e/libpod_suite_remoteclient_test.go
+++ b/test/e2e/libpod_suite_remoteclient_test.go
@@ -30,7 +30,13 @@ func SkipIfRootless() {
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
- podmanSession := p.PodmanBase(args)
+ podmanSession := p.PodmanBase(args, false)
+ return &PodmanSessionIntegration{podmanSession}
+}
+
+// PodmanNoCache calls podman with out adding the imagecache
+func (p *PodmanTestIntegration) PodmanNoCache(args []string) *PodmanSessionIntegration {
+ podmanSession := p.PodmanBase(args, true)
return &PodmanSessionIntegration{podmanSession}
}
@@ -145,6 +151,21 @@ func getVarlinkOptions(p *PodmanTestIntegration, args []string) []string {
return podmanOptions
}
+func (p *PodmanTestIntegration) RestoreArtifactToCache(image string) error {
+ fmt.Printf("Restoring %s...\n", image)
+ dest := strings.Split(image, "/")
+ destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
+ p.CrioRoot = p.ImageCacheDir
+ restore := p.PodmanNoCache([]string{"load", "-q", "-i", destName})
+ restore.WaitWithDefaultTimeout()
+ return nil
+}
+
+// SeedImages restores all the artifacts into the main store for remote tests
+func (p *PodmanTestIntegration) SeedImages() error {
+ return p.RestoreAllArtifacts()
+}
+
// RestoreArtifact puts the cached image into our test store
func (p *PodmanTestIntegration) RestoreArtifact(image string) error {
fmt.Printf("Restoring %s...\n", image)
@@ -169,3 +190,6 @@ func (p *PodmanTestIntegration) DelayForVarlink() {
time.Sleep(1 * time.Second)
}
}
+
+func populateCache(podman *PodmanTestIntegration) {}
+func removeCache() {}
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index 0a85c625d..8d993ee72 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -23,13 +23,19 @@ func SkipIfRootless() {
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
- podmanSession := p.PodmanBase(args)
+ podmanSession := p.PodmanBase(args, false)
+ return &PodmanSessionIntegration{podmanSession}
+}
+
+// PodmanNoCache calls the podman command with no configured imagecache
+func (p *PodmanTestIntegration) PodmanNoCache(args []string) *PodmanSessionIntegration {
+ podmanSession := p.PodmanBase(args, true)
return &PodmanSessionIntegration{podmanSession}
}
// PodmanAsUser is the exec call to podman on the filesystem with the specified uid/gid and environment
func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd string, env []string) *PodmanSessionIntegration {
- podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env)
+ podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env, false)
return &PodmanSessionIntegration{podmanSession}
}
@@ -75,9 +81,40 @@ func (p *PodmanTestIntegration) RestoreArtifact(image string) error {
fmt.Printf("Restoring %s...\n", image)
dest := strings.Split(image, "/")
destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
- restore := p.Podman([]string{"load", "-q", "-i", destName})
+ restore := p.PodmanNoCache([]string{"load", "-q", "-i", destName})
restore.Wait(90)
return nil
}
+
+// RestoreArtifactToCache populates the imagecache from tarballs that were cached earlier
+func (p *PodmanTestIntegration) RestoreArtifactToCache(image string) error {
+ fmt.Printf("Restoring %s...\n", image)
+ dest := strings.Split(image, "/")
+ destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
+
+ p.CrioRoot = p.ImageCacheDir
+ restore := p.PodmanNoCache([]string{"load", "-q", "-i", destName})
+ restore.WaitWithDefaultTimeout()
+ return nil
+}
+
func (p *PodmanTestIntegration) StopVarlink() {}
func (p *PodmanTestIntegration) DelayForVarlink() {}
+
+func populateCache(podman *PodmanTestIntegration) {
+ for _, image := range CACHE_IMAGES {
+ podman.RestoreArtifactToCache(image)
+ }
+}
+
+func removeCache() {
+ // Remove cache dirs
+ if err := os.RemoveAll(ImageCacheDir); err != nil {
+ fmt.Printf("%q\n", err)
+ }
+}
+
+// SeedImages is a no-op for localized testing
+func (p *PodmanTestIntegration) SeedImages() error {
+ return nil
+}
diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go
index 0e193640e..9209e1770 100644
--- a/test/e2e/load_test.go
+++ b/test/e2e/load_test.go
@@ -3,6 +3,7 @@
package integration
import (
+ "fmt"
"os"
"path/filepath"
@@ -38,7 +39,11 @@ var _ = Describe("Podman load", func() {
It("podman load input flag", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE})
+ images := podmanTest.PodmanNoCache([]string{"images"})
+ images.WaitWithDefaultTimeout()
+ fmt.Println(images.OutputToStringArray())
+
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
@@ -46,7 +51,7 @@ var _ = Describe("Podman load", func() {
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
@@ -54,7 +59,7 @@ var _ = Describe("Podman load", func() {
It("podman load compressed tar file", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
@@ -62,11 +67,11 @@ var _ = Describe("Podman load", func() {
Expect(compress.ExitCode()).To(Equal(0))
outfile = outfile + ".gz"
- rmi := podmanTest.Podman([]string{"rmi", ALPINE})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
@@ -74,15 +79,15 @@ var _ = Describe("Podman load", func() {
It("podman load oci-archive image", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
- rmi := podmanTest.Podman([]string{"rmi", ALPINE})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
@@ -90,15 +95,15 @@ var _ = Describe("Podman load", func() {
It("podman load oci-archive with signature", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
- rmi := podmanTest.Podman([]string{"rmi", ALPINE})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "--signature-policy", "/etc/containers/policy.json", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "--signature-policy", "/etc/containers/policy.json", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
@@ -106,15 +111,15 @@ var _ = Describe("Podman load", func() {
It("podman load with quiet flag", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
- rmi := podmanTest.Podman([]string{"rmi", ALPINE})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-q", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "-q", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
@@ -122,7 +127,7 @@ var _ = Describe("Podman load", func() {
It("podman load directory", func() {
outdir := filepath.Join(podmanTest.TempDir, "alpine")
- save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
@@ -136,7 +141,7 @@ var _ = Describe("Podman load", func() {
})
It("podman load bogus file", func() {
- save := podmanTest.Podman([]string{"load", "-i", "foobar.tar"})
+ save := podmanTest.PodmanNoCache([]string{"load", "-i", "foobar.tar"})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).ToNot(Equal(0))
})
@@ -148,75 +153,75 @@ var _ = Describe("Podman load", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
alpVersion := "docker.io/library/alpine:3.2"
- pull := podmanTest.Podman([]string{"pull", alpVersion})
+ pull := podmanTest.PodmanNoCache([]string{"pull", alpVersion})
pull.WaitWithDefaultTimeout()
Expect(pull.ExitCode()).To(Equal(0))
- save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE, alpVersion})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINE, alpVersion})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
- rmi := podmanTest.Podman([]string{"rmi", ALPINE, alpVersion})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE, alpVersion})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-i", outfile})
+ result := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", ALPINE})
+ inspect := podmanTest.PodmanNoCache([]string{"inspect", ALPINE})
inspect.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
- inspect = podmanTest.Podman([]string{"inspect", alpVersion})
+ inspect = podmanTest.PodmanNoCache([]string{"inspect", alpVersion})
inspect.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
It("podman load localhost registry from scratch", func() {
outfile := filepath.Join(podmanTest.TempDir, "load_test.tar.gz")
- setup := podmanTest.Podman([]string{"tag", ALPINE, "hello:world"})
+ setup := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", "hello:world"})
+ setup = podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-archive", "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"rmi", "hello:world"})
+ setup = podmanTest.PodmanNoCache([]string{"rmi", "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- load := podmanTest.Podman([]string{"load", "-i", outfile})
+ load := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
load.WaitWithDefaultTimeout()
Expect(load.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"images", "hello:world"})
+ result := podmanTest.PodmanNoCache([]string{"images", "hello:world"})
result.WaitWithDefaultTimeout()
Expect(result.LineInOutputContains("docker")).To(Not(BeTrue()))
Expect(result.LineInOutputContains("localhost")).To(BeTrue())
})
It("podman load localhost registry from scratch and :latest", func() {
+ podmanTest.RestoreArtifact(fedoraMinimal)
outfile := filepath.Join(podmanTest.TempDir, "load_test.tar.gz")
- podmanTest.RestoreArtifact("fedora-minimal:latest")
- setup := podmanTest.Podman([]string{"tag", "fedora-minimal", "hello"})
+ setup := podmanTest.PodmanNoCache([]string{"tag", "fedora-minimal", "hello"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", "hello"})
+ setup = podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-archive", "hello"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"rmi", "hello"})
+ setup = podmanTest.PodmanNoCache([]string{"rmi", "hello"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- load := podmanTest.Podman([]string{"load", "-i", outfile})
+ load := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
load.WaitWithDefaultTimeout()
Expect(load.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"images", "hello:latest"})
+ result := podmanTest.PodmanNoCache([]string{"images", "hello:latest"})
result.WaitWithDefaultTimeout()
Expect(result.LineInOutputContains("docker")).To(Not(BeTrue()))
Expect(result.LineInOutputContains("localhost")).To(BeTrue())
@@ -225,23 +230,23 @@ var _ = Describe("Podman load", func() {
It("podman load localhost registry from dir", func() {
outfile := filepath.Join(podmanTest.TempDir, "load")
- setup := podmanTest.Podman([]string{"tag", BB, "hello:world"})
+ setup := podmanTest.PodmanNoCache([]string{"tag", BB, "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-dir", "hello:world"})
+ setup = podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-dir", "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- setup = podmanTest.Podman([]string{"rmi", "hello:world"})
+ setup = podmanTest.PodmanNoCache([]string{"rmi", "hello:world"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- load := podmanTest.Podman([]string{"load", "-i", outfile})
+ load := podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
load.WaitWithDefaultTimeout()
Expect(load.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"images", "load:latest"})
+ result := podmanTest.PodmanNoCache([]string{"images", "load:latest"})
result.WaitWithDefaultTimeout()
Expect(result.LineInOutputContains("docker")).To(Not(BeTrue()))
Expect(result.LineInOutputContains("localhost")).To(BeTrue())
@@ -250,17 +255,17 @@ var _ = Describe("Podman load", func() {
It("podman load xz compressed image", func() {
outfile := filepath.Join(podmanTest.TempDir, "bb.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, BB})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, BB})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
session := SystemExec("xz", []string{outfile})
Expect(session.ExitCode()).To(Equal(0))
- rmi := podmanTest.Podman([]string{"rmi", BB})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", BB})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"load", "-i", outfile + ".xz"})
+ result := podmanTest.PodmanNoCache([]string{"load", "-i", outfile + ".xz"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index 2c82182cf..cc50c4d95 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman logs", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -140,4 +140,82 @@ var _ = Describe("Podman logs", func() {
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(BeZero())
})
+
+ It("podman journald logs for container", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(3))
+ })
+
+ It("podman journald logs tail two lines", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", "--tail", "2", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(2))
+ })
+
+ It("podman journald logs tail 99 lines", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", "--tail", "99", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(3))
+ })
+
+ It("podman journald logs tail 2 lines with timestamps", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(2))
+ })
+
+ It("podman journald logs latest with since time", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(3))
+ })
+
+ It("podman journald logs latest with since duration", func() {
+ Skip("need to verify images have correct packages for journald")
+ logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+ logc.WaitWithDefaultTimeout()
+ Expect(logc.ExitCode()).To(Equal(0))
+ cid := logc.OutputToString()
+
+ results := podmanTest.Podman([]string{"logs", "--since", "10m", cid})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(len(results.OutputToStringArray())).To(Equal(3))
+ })
})
diff --git a/test/e2e/mount_test.go b/test/e2e/mount_test.go
index b361e0057..61abdf6fc 100644
--- a/test/e2e/mount_test.go
+++ b/test/e2e/mount_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman mount", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/namespace_test.go b/test/e2e/namespace_test.go
index 28d050be3..88b48cb06 100644
--- a/test/e2e/namespace_test.go
+++ b/test/e2e/namespace_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman namespaces", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go
index c47189a0e..01fb6d91b 100644
--- a/test/e2e/pause_test.go
+++ b/test/e2e/pause_test.go
@@ -27,7 +27,7 @@ var _ = Describe("Podman pause", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -249,7 +249,6 @@ var _ = Describe("Podman pause", func() {
})
It("Pause a bunch of running containers", func() {
- podmanTest.RestoreArtifact(nginx)
for i := 0; i < 3; i++ {
name := fmt.Sprintf("test%d", i)
run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx})
@@ -277,7 +276,6 @@ var _ = Describe("Podman pause", func() {
})
It("Unpause a bunch of running containers", func() {
- podmanTest.RestoreArtifact(nginx)
for i := 0; i < 3; i++ {
name := fmt.Sprintf("test%d", i)
run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx})
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 84966f77b..2efa36141 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod create", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 82f35999c..c8763de9f 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -25,8 +25,7 @@ var _ = Describe("Podman pod create", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
- podmanTest.RestoreArtifact(infra)
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -113,12 +112,10 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- podmanTest.RestoreArtifact(nginx)
session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- podmanTest.RestoreArtifact(fedoraMinimal)
session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "localhost:80"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -138,7 +135,6 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- podmanTest.RestoreArtifact(fedoraMinimal)
session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "/bin/sh", "-c", "'touch /dev/shm/hi'"})
session.WaitWithDefaultTimeout()
if session.ExitCode() != 0 {
@@ -216,7 +212,6 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- podmanTest.RestoreArtifact(nginx)
session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go
index d1a023153..488dd1685 100644
--- a/test/e2e/pod_inspect_test.go
+++ b/test/e2e/pod_inspect_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod inspect", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_kill_test.go b/test/e2e/pod_kill_test.go
index 23a8ea97e..7cf67bbfc 100644
--- a/test/e2e/pod_kill_test.go
+++ b/test/e2e/pod_kill_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman pod kill", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_pause_test.go b/test/e2e/pod_pause_test.go
index ab828853b..619ee6f12 100644
--- a/test/e2e/pod_pause_test.go
+++ b/test/e2e/pod_pause_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman pod pause", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_pod_namespaces.go b/test/e2e/pod_pod_namespaces.go
index 9d6321c0e..83c877f5a 100644
--- a/test/e2e/pod_pod_namespaces.go
+++ b/test/e2e/pod_pod_namespaces.go
@@ -25,8 +25,7 @@ var _ = Describe("Podman pod create", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
- podmanTest.RestoreArtifact(infra)
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_prune_test.go b/test/e2e/pod_prune_test.go
index 8a4ba2399..da0d425cb 100644
--- a/test/e2e/pod_prune_test.go
+++ b/test/e2e/pod_prune_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod prune", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_ps_test.go b/test/e2e/pod_ps_test.go
index 8513c6c2e..6d5873caa 100644
--- a/test/e2e/pod_ps_test.go
+++ b/test/e2e/pod_ps_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman ps", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_restart_test.go b/test/e2e/pod_restart_test.go
index 7b19ecc94..691fe5f0c 100644
--- a/test/e2e/pod_restart_test.go
+++ b/test/e2e/pod_restart_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod restart", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go
index 7417a1298..0d3f47f30 100644
--- a/test/e2e/pod_rm_test.go
+++ b/test/e2e/pod_rm_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman pod rm", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go
index 967fbc2da..2722cb5b3 100644
--- a/test/e2e/pod_start_test.go
+++ b/test/e2e/pod_start_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod start", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go
index 6018b4494..01176f97c 100644
--- a/test/e2e/pod_stats_test.go
+++ b/test/e2e/pod_stats_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman pod stats", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go
index 9fd9e3ef4..361a63a7f 100644
--- a/test/e2e/pod_stop_test.go
+++ b/test/e2e/pod_stop_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman pod stop", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go
index 420e4aca9..c313b0675 100644
--- a/test/e2e/pod_top_test.go
+++ b/test/e2e/pod_top_test.go
@@ -26,7 +26,7 @@ var _ = Describe("Podman top", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/port_test.go b/test/e2e/port_test.go
index 7cf3e16bf..e45118361 100644
--- a/test/e2e/port_test.go
+++ b/test/e2e/port_test.go
@@ -26,7 +26,7 @@ var _ = Describe("Podman port", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -49,7 +49,6 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l nginx", func() {
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"run", "-dt", "-P", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -62,7 +61,6 @@ var _ = Describe("Podman port", func() {
})
It("podman container port -l nginx", func() {
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"container", "run", "-dt", "-P", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -75,7 +73,6 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l port nginx", func() {
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"run", "-dt", "-P", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -88,7 +85,6 @@ var _ = Describe("Podman port", func() {
})
It("podman port -a nginx", func() {
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"run", "-dt", "-P", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 377c9f5e1..df0525a79 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -28,7 +28,7 @@ var _ = Describe("Podman prune", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -77,11 +77,12 @@ var _ = Describe("Podman prune", func() {
})
It("podman image prune unused images", func() {
- prune := podmanTest.Podman([]string{"image", "prune", "-a"})
+ podmanTest.RestoreAllArtifacts()
+ prune := podmanTest.PodmanNoCache([]string{"image", "prune", "-a"})
prune.WaitWithDefaultTimeout()
Expect(prune.ExitCode()).To(Equal(0))
- images := podmanTest.Podman([]string{"images", "-aq"})
+ images := podmanTest.PodmanNoCache([]string{"images", "-aq"})
images.WaitWithDefaultTimeout()
// all images are unused, so they all should be deleted!
Expect(len(images.OutputToStringArray())).To(Equal(0))
@@ -89,12 +90,13 @@ var _ = Describe("Podman prune", func() {
It("podman system image prune unused images", func() {
SkipIfRemote()
+ podmanTest.RestoreAllArtifacts()
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
- prune := podmanTest.Podman([]string{"system", "prune", "-a", "--force"})
+ prune := podmanTest.PodmanNoCache([]string{"system", "prune", "-a", "--force"})
prune.WaitWithDefaultTimeout()
Expect(prune.ExitCode()).To(Equal(0))
- images := podmanTest.Podman([]string{"images", "-aq"})
+ images := podmanTest.PodmanNoCache([]string{"images", "-aq"})
images.WaitWithDefaultTimeout()
// all images are unused, so they all should be deleted!
Expect(len(images.OutputToStringArray())).To(Equal(0))
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index 7edb350f3..b0a28501a 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -27,7 +27,7 @@ var _ = Describe("Podman ps", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index 4e4e80d56..d6e7b44d1 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -28,7 +28,6 @@ var _ = Describe("Podman pull", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
})
AfterEach(func() {
@@ -39,132 +38,135 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from docker a not existing image", func() {
- session := podmanTest.Podman([]string{"pull", "ibetthisdoesntexistthere:foo"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "ibetthisdoesntexistthere:foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman pull from docker with tag", func() {
- session := podmanTest.Podman([]string{"pull", "busybox:glibc"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "busybox:glibc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "busybox:glibc"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "busybox:glibc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from docker without tag", func() {
- session := podmanTest.Podman([]string{"pull", "busybox"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "busybox"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "busybox"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "busybox"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from alternate registry with tag", func() {
- session := podmanTest.Podman([]string{"pull", nginx})
+ session := podmanTest.PodmanNoCache([]string{"pull", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", nginx})
+ session = podmanTest.PodmanNoCache([]string{"rmi", nginx})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from alternate registry without tag", func() {
- session := podmanTest.Podman([]string{"pull", "quay.io/libpod/alpine_nginx"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "quay.io/libpod/alpine_nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "quay.io/libpod/alpine_nginx"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "quay.io/libpod/alpine_nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull by digest", func() {
- session := podmanTest.Podman([]string{"pull", "alpine@sha256:1072e499f3f655a032e88542330cf75b02e7bdf673278f701d7ba61629ee3ebe"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "alpine@sha256:1072e499f3f655a032e88542330cf75b02e7bdf673278f701d7ba61629ee3ebe"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine:none"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine:none"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull bogus image", func() {
- session := podmanTest.Podman([]string{"pull", "umohnani/get-started"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "umohnani/get-started"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman pull from docker-archive", func() {
+ podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
- session := podmanTest.Podman([]string{"save", "-o", tarfn, "alpine"})
+ session := podmanTest.PodmanNoCache([]string{"save", "-o", tarfn, "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:%s", tarfn)})
+ session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:%s", tarfn)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from oci-archive", func() {
+ podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "oci-alp.tar")
- session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", tarfn, "alpine"})
+ session := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-archive", "-o", tarfn, "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"pull", fmt.Sprintf("oci-archive:%s", tarfn)})
+ session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("oci-archive:%s", tarfn)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from local directory", func() {
+ podmanTest.RestoreArtifact(ALPINE)
dirpath := filepath.Join(podmanTest.TempDir, "alpine")
os.MkdirAll(dirpath, os.ModePerm)
imgPath := fmt.Sprintf("dir:%s", dirpath)
- session := podmanTest.Podman([]string{"push", "alpine", imgPath})
+ session := podmanTest.PodmanNoCache([]string{"push", "alpine", imgPath})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"pull", imgPath})
+ session = podmanTest.PodmanNoCache([]string{"pull", imgPath})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "alpine"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull check quiet", func() {
podmanTest.RestoreArtifact(ALPINE)
- setup := podmanTest.Podman([]string{"images", ALPINE, "-q", "--no-trunc"})
+ setup := podmanTest.PodmanNoCache([]string{"images", ALPINE, "-q", "--no-trunc"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
shortImageId := strings.Split(setup.OutputToString(), ":")[1]
- rmi := podmanTest.Podman([]string{"rmi", ALPINE})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
- pull := podmanTest.Podman([]string{"pull", "-q", ALPINE})
+ pull := podmanTest.PodmanNoCache([]string{"pull", "-q", ALPINE})
pull.WaitWithDefaultTimeout()
Expect(pull.ExitCode()).To(Equal(0))
@@ -172,17 +174,17 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull check all tags", func() {
- session := podmanTest.Podman([]string{"pull", "--all-tags", "alpine"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "--all-tags", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.LineInOuputStartsWith("Pulled Images:")).To(BeTrue())
- session = podmanTest.Podman([]string{"images"})
+ session = podmanTest.PodmanNoCache([]string{"images"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 4))
- rmi := podmanTest.Podman([]string{"rmi", "-a", "-f"})
+ rmi := podmanTest.PodmanNoCache([]string{"rmi", "-a", "-f"})
rmi.WaitWithDefaultTimeout()
Expect(rmi.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go
index 009067482..de2416868 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -38,22 +38,18 @@ var _ = Describe("Podman push", func() {
})
It("podman push to containers/storage", func() {
- session := podmanTest.Podman([]string{"push", ALPINE, "containers-storage:busybox:test"})
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE, "containers-storage:busybox:test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", ALPINE})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
-
- session = podmanTest.Podman([]string{"rmi", "busybox:test"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman push to dir", func() {
bbdir := filepath.Join(podmanTest.TempDir, "busybox")
- session := podmanTest.Podman([]string{"push", "--remove-signatures", ALPINE,
+ session := podmanTest.PodmanNoCache([]string{"push", "--remove-signatures", ALPINE,
fmt.Sprintf("dir:%s", bbdir)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -65,8 +61,7 @@ var _ = Describe("Podman push", func() {
}
lock := GetPortLock("5000")
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
- session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
+ session := podmanTest.PodmanNoCache([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -74,7 +69,7 @@ var _ = Describe("Podman push", func() {
Skip("Can not start docker registry.")
}
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
})
@@ -106,8 +101,7 @@ var _ = Describe("Podman push", func() {
}
lock := GetPortLock("5000")
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
- session := podmanTest.Podman([]string{"run", "--entrypoint", "htpasswd", registry, "-Bbn", "podmantest", "test"})
+ session := podmanTest.PodmanNoCache([]string{"run", "--entrypoint", "htpasswd", registry, "-Bbn", "podmantest", "test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -117,7 +111,7 @@ var _ = Describe("Podman push", func() {
f.WriteString(session.OutputToString())
f.Sync()
- session = podmanTest.Podman([]string{"run", "-d", "-p", "5000:5000", "--name", "registry", "-v",
+ session = podmanTest.PodmanNoCache([]string{"run", "-d", "-p", "5000:5000", "--name", "registry", "-v",
strings.Join([]string{authPath, "/auth"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd",
"-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
@@ -129,36 +123,36 @@ var _ = Describe("Podman push", func() {
Skip("Can not start docker registry.")
}
- session = podmanTest.Podman([]string{"logs", "registry"})
+ session = podmanTest.PodmanNoCache([]string{"logs", "registry"})
session.WaitWithDefaultTimeout()
- push := podmanTest.Podman([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5000/tlstest"})
+ push := podmanTest.PodmanNoCache([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5000/tlstest"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Not(Equal(0)))
- push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--tls-verify=false", ALPINE, "localhost:5000/tlstest"})
+ push = podmanTest.PodmanNoCache([]string{"push", "--creds=podmantest:test", "--tls-verify=false", ALPINE, "localhost:5000/tlstest"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), "/etc/containers/certs.d/localhost:5000/ca.crt"})
Expect(setup.ExitCode()).To(Equal(0))
- push = podmanTest.Podman([]string{"push", "--creds=podmantest:wrongpasswd", ALPINE, "localhost:5000/credstest"})
+ push = podmanTest.PodmanNoCache([]string{"push", "--creds=podmantest:wrongpasswd", ALPINE, "localhost:5000/credstest"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Not(Equal(0)))
- push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--cert-dir=fakedir", ALPINE, "localhost:5000/certdirtest"})
+ push = podmanTest.PodmanNoCache([]string{"push", "--creds=podmantest:test", "--cert-dir=fakedir", ALPINE, "localhost:5000/certdirtest"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Not(Equal(0)))
- push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5000/defaultflags"})
+ push = podmanTest.PodmanNoCache([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5000/defaultflags"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
})
It("podman push to docker-archive", func() {
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
- session := podmanTest.Podman([]string{"push", ALPINE,
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE,
fmt.Sprintf("docker-archive:%s:latest", tarfn)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -177,7 +171,7 @@ var _ = Describe("Podman push", func() {
Skip("Docker is not available")
}
- session := podmanTest.Podman([]string{"push", ALPINE, "docker-daemon:alpine:podmantest"})
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE, "docker-daemon:alpine:podmantest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -191,7 +185,7 @@ var _ = Describe("Podman push", func() {
It("podman push to oci-archive", func() {
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
- session := podmanTest.Podman([]string{"push", ALPINE,
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE,
fmt.Sprintf("oci-archive:%s:latest", tarfn)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -208,7 +202,7 @@ var _ = Describe("Podman push", func() {
setup := SystemExec("ostree", []string{strings.Join([]string{"--repo=", ostreePath}, ""), "init"})
Expect(setup.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"push", ALPINE, strings.Join([]string{"ostree:alp@", ostreePath}, "")})
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE, strings.Join([]string{"ostree:alp@", ostreePath}, "")})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -216,7 +210,7 @@ var _ = Describe("Podman push", func() {
It("podman push to docker-archive no reference", func() {
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
- session := podmanTest.Podman([]string{"push", ALPINE,
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE,
fmt.Sprintf("docker-archive:%s", tarfn)})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -224,7 +218,7 @@ var _ = Describe("Podman push", func() {
It("podman push to oci-archive no reference", func() {
ociarc := filepath.Join(podmanTest.TempDir, "alp-oci")
- session := podmanTest.Podman([]string{"push", ALPINE,
+ session := podmanTest.PodmanNoCache([]string{"push", ALPINE,
fmt.Sprintf("oci-archive:%s", ociarc)})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go
index 7a9a466d8..2b515f53b 100644
--- a/test/e2e/restart_test.go
+++ b/test/e2e/restart_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman restart", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go
index 29150d67c..2dbabbf6a 100644
--- a/test/e2e/rm_test.go
+++ b/test/e2e/rm_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman rm", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go
index e034f24cf..1687bf764 100644
--- a/test/e2e/rmi_test.go
+++ b/test/e2e/rmi_test.go
@@ -41,14 +41,14 @@ var _ = Describe("Podman rmi", func() {
})
It("podman rmi with fq name", func() {
- session := podmanTest.Podman([]string{"rmi", ALPINE})
+ session := podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman rmi with short name", func() {
- session := podmanTest.Podman([]string{"rmi", "alpine"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -56,9 +56,9 @@ var _ = Describe("Podman rmi", func() {
It("podman rmi all images", func() {
podmanTest.PullImages([]string{nginx})
- session := podmanTest.Podman([]string{"rmi", "-a"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-a"})
session.WaitWithDefaultTimeout()
- images := podmanTest.Podman([]string{"images"})
+ images := podmanTest.PodmanNoCache([]string{"images"})
images.WaitWithDefaultTimeout()
fmt.Println(images.OutputToStringArray())
Expect(session.ExitCode()).To(Equal(0))
@@ -67,22 +67,22 @@ var _ = Describe("Podman rmi", func() {
It("podman rmi all images forcibly with short options", func() {
podmanTest.PullImages([]string{nginx})
- session := podmanTest.Podman([]string{"rmi", "-fa"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman rmi tagged image", func() {
- setup := podmanTest.Podman([]string{"images", "-q", ALPINE})
+ setup := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"tag", "alpine", "foo:bar", "foo"})
+ session := podmanTest.PodmanNoCache([]string{"tag", "alpine", "foo:bar", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"images", "-q", "foo"})
+ result := podmanTest.PodmanNoCache([]string{"images", "-q", "foo"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
@@ -90,95 +90,95 @@ var _ = Describe("Podman rmi", func() {
})
It("podman rmi image with tags by ID cannot be done without force", func() {
- setup := podmanTest.Podman([]string{"images", "-q", ALPINE})
+ setup := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
alpineId := setup.OutputToString()
- session := podmanTest.Podman([]string{"tag", "alpine", "foo:bar", "foo"})
+ session := podmanTest.PodmanNoCache([]string{"tag", "alpine", "foo:bar", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// Trying without --force should fail
- result := podmanTest.Podman([]string{"rmi", alpineId})
+ result := podmanTest.PodmanNoCache([]string{"rmi", alpineId})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).ToNot(Equal(0))
// With --force it should work
- resultForce := podmanTest.Podman([]string{"rmi", "-f", alpineId})
+ resultForce := podmanTest.PodmanNoCache([]string{"rmi", "-f", alpineId})
resultForce.WaitWithDefaultTimeout()
Expect(resultForce.ExitCode()).To(Equal(0))
})
It("podman rmi image that is a parent of another image", func() {
SkipIfRemote()
- session := podmanTest.Podman([]string{"rmi", "-fa"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"run", "--name", "c_test", ALPINE, "true"})
+ session = podmanTest.PodmanNoCache([]string{"run", "--name", "c_test", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"commit", "-q", "c_test", "test"})
+ session = podmanTest.PodmanNoCache([]string{"commit", "-q", "c_test", "test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rm", "c_test"})
+ session = podmanTest.PodmanNoCache([]string{"rm", "c_test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", ALPINE})
+ session = podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(1))
- session = podmanTest.Podman([]string{"images", "-q", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2))
untaggedImg := session.OutputToStringArray()[1]
- session = podmanTest.Podman([]string{"rmi", "-f", untaggedImg})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "-f", untaggedImg})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman rmi image that is created from another named imaged", func() {
SkipIfRemote()
- session := podmanTest.Podman([]string{"rmi", "-fa"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"})
+ session = podmanTest.PodmanNoCache([]string{"create", "--name", "c_test1", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"})
+ session = podmanTest.PodmanNoCache([]string{"commit", "-q", "c_test1", "test1"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"})
+ session = podmanTest.PodmanNoCache([]string{"create", "--name", "c_test2", "test1", "true"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"})
+ session = podmanTest.PodmanNoCache([]string{"commit", "-q", "c_test2", "test2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rm", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"rm", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "test2"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "test2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2))
@@ -186,7 +186,7 @@ var _ = Describe("Podman rmi", func() {
It("podman rmi with cached images", func() {
SkipIfRemote()
- session := podmanTest.Podman([]string{"rmi", "-fa"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -205,51 +205,51 @@ var _ = Describe("Podman rmi", func() {
`
podmanTest.BuildImage(dockerfile, "test2", "true")
- session = podmanTest.Podman([]string{"images", "-q", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
numOfImages := len(session.OutputToStringArray())
- session = podmanTest.Podman([]string{"rmi", "test2"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "test2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(numOfImages - len(session.OutputToStringArray())).To(Equal(2))
- session = podmanTest.Podman([]string{"rmi", "test"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(1))
podmanTest.BuildImage(dockerfile, "test3", "true")
- session = podmanTest.Podman([]string{"rmi", ALPINE})
+ session = podmanTest.PodmanNoCache([]string{"rmi", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "test3"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "test3"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"images", "-q", "-a"})
+ session = podmanTest.PodmanNoCache([]string{"images", "-q", "-a"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToString())).To(Equal(0))
})
It("podman rmi -a with no images should be exit 0", func() {
- session := podmanTest.Podman([]string{"rmi", "-fa"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session2 := podmanTest.Podman([]string{"rmi", "-fa"})
+ session2 := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
})
@@ -265,12 +265,12 @@ RUN find $LOCAL
`
podmanTest.BuildImage(dockerfile, "test", "true")
- session := podmanTest.Podman([]string{"rmi", "-a"})
+ session := podmanTest.PodmanNoCache([]string{"rmi", "-a"})
session.WaitWithDefaultTimeout()
fmt.Println(session.OutputToString())
Expect(session.ExitCode()).To(Equal(0))
- images := podmanTest.Podman([]string{"images", "-aq"})
+ images := podmanTest.PodmanNoCache([]string{"images", "-aq"})
images.WaitWithDefaultTimeout()
Expect(images.ExitCode()).To(Equal(0))
Expect(len(images.OutputToStringArray())).To(Equal(0))
@@ -279,7 +279,7 @@ RUN find $LOCAL
// Don't rerun all tests; just assume that if we get that diagnostic,
// we're getting rmi
It("podman image rm is the same as rmi", func() {
- session := podmanTest.Podman([]string{"image", "rm"})
+ session := podmanTest.PodmanNoCache([]string{"image", "rm"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
Expect(session.LineInOutputContains("image name or ID must be specified"))
diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go
index 0d04c5f03..1fb9f6871 100644
--- a/test/e2e/run_cgroup_parent_test.go
+++ b/test/e2e/run_cgroup_parent_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreArtifact(fedoraMinimal)
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_cleanup_test.go b/test/e2e/run_cleanup_test.go
index b20e37794..73647b6bb 100644
--- a/test/e2e/run_cleanup_test.go
+++ b/test/e2e/run_cleanup_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run exit", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.RestoreArtifact(ALPINE)
})
AfterEach(func() {
diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go
index 42a66865c..87f89b1dd 100644
--- a/test/e2e/run_cpu_test.go
+++ b/test/e2e/run_cpu_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run cpu", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go
index fac09b78d..2e537a9f9 100644
--- a/test/e2e/run_device_test.go
+++ b/test/e2e/run_device_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run device", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_dns_test.go b/test/e2e/run_dns_test.go
index 0f4dd6742..f1196ff38 100644
--- a/test/e2e/run_dns_test.go
+++ b/test/e2e/run_dns_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run dns", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go
index ee9fd1263..b1344a371 100644
--- a/test/e2e/run_entrypoint_test.go
+++ b/test/e2e/run_entrypoint_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run entrypoint", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreArtifact(ALPINE)
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_exit_test.go b/test/e2e/run_exit_test.go
index da4cf7ee7..861d6b3b7 100644
--- a/test/e2e/run_exit_test.go
+++ b/test/e2e/run_exit_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run exit", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go
index 05d0b7a18..8fe90c8d8 100644
--- a/test/e2e/run_memory_test.go
+++ b/test/e2e/run_memory_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run memory", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 93919925c..1497a651b 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run networking", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -78,7 +78,6 @@ var _ = Describe("Podman run networking", func() {
})
It("podman run network expose ports in image metadata", func() {
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"create", "-dt", "-P", nginx})
session.Wait(90)
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_ns_test.go b/test/e2e/run_ns_test.go
index 51f921bce..6ba0d1aba 100644
--- a/test/e2e/run_ns_test.go
+++ b/test/e2e/run_ns_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run ns", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreArtifact(fedoraMinimal)
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go
index becbc5bfa..bd6a0e036 100644
--- a/test/e2e/run_passwd_test.go
+++ b/test/e2e/run_passwd_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run passwd", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go
index 16011b2fd..f2c424483 100644
--- a/test/e2e/run_privileged_test.go
+++ b/test/e2e/run_privileged_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman privileged container tests", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_restart_test.go b/test/e2e/run_restart_test.go
index 9976b45e8..8bbdf2056 100644
--- a/test/e2e/run_restart_test.go
+++ b/test/e2e/run_restart_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman run restart containers", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_selinux_test.go b/test/e2e/run_selinux_test.go
index 4d2bad49c..a2228411e 100644
--- a/test/e2e/run_selinux_test.go
+++ b/test/e2e/run_selinux_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
if !selinux.GetEnabled() {
Skip("SELinux not enabled")
}
diff --git a/test/e2e/run_signal_test.go b/test/e2e/run_signal_test.go
index e482adb84..3a5ed483c 100644
--- a/test/e2e/run_signal_test.go
+++ b/test/e2e/run_signal_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman run with --sig-proxy", func() {
}
podmanTest = PodmanTestCreate(tmpdir)
podmanTest.Setup()
- podmanTest.RestoreArtifact(fedoraMinimal)
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go
index 318a7a62d..9753cfc9c 100644
--- a/test/e2e/run_staticip_test.go
+++ b/test/e2e/run_staticip_test.go
@@ -25,7 +25,7 @@ var _ = Describe("Podman run with --ip flag", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
// Cleanup the CNI networks used by the tests
os.RemoveAll("/var/lib/cni/networks/podman")
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index f908fe154..31720ea04 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -32,7 +32,7 @@ var _ = Describe("Podman run", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -51,7 +51,6 @@ var _ = Describe("Podman run", func() {
It("podman run a container based on a complex local image name", func() {
SkipIfRootless()
imageName := strings.TrimPrefix(nginx, "quay.io/")
- podmanTest.RestoreArtifact(nginx)
session := podmanTest.Podman([]string{"run", imageName, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
@@ -59,7 +58,6 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container based on on a short name with localhost", func() {
- podmanTest.RestoreArtifact(nginx)
tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"})
tag.WaitWithDefaultTimeout()
@@ -73,7 +71,6 @@ var _ = Describe("Podman run", func() {
})
It("podman container run a container based on on a short name with localhost", func() {
- podmanTest.RestoreArtifact(nginx)
tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"})
tag.WaitWithDefaultTimeout()
@@ -229,7 +226,6 @@ var _ = Describe("Podman run", func() {
It("podman run limits test", func() {
SkipIfRootless()
- podmanTest.RestoreArtifact(fedoraMinimal)
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -349,11 +345,12 @@ var _ = Describe("Podman run", func() {
})
It("podman run tagged image", func() {
- tag := podmanTest.Podman([]string{"tag", "busybox", "bb"})
+ podmanTest.RestoreArtifact(BB)
+ tag := podmanTest.PodmanNoCache([]string{"tag", "busybox", "bb"})
tag.WaitWithDefaultTimeout()
Expect(tag.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"})
+ session := podmanTest.PodmanNoCache([]string{"run", "--rm", "bb", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
@@ -536,15 +533,10 @@ var _ = Describe("Podman run", func() {
})
It("podman run with built-in volume image", func() {
- podmanTest.RestoreArtifact(redis)
session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", redis})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
-
dockerfile := `FROM busybox
RUN mkdir -p /myvol/data && chown -R mail.0 /myvol
VOLUME ["/myvol/data"]
@@ -555,10 +547,6 @@ USER mail`
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("mail root"))
-
- session = podmanTest.Podman([]string{"rmi", "test"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
})
It("podman run --volumes-from flag", func() {
@@ -571,7 +559,6 @@ USER mail`
err = ioutil.WriteFile(volFile, []byte(data), 0755)
Expect(err).To(BeNil())
- podmanTest.RestoreArtifact(redis)
session := podmanTest.Podman([]string{"create", "--volume", vol + ":/myvol", redis, "sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -587,7 +574,6 @@ USER mail`
})
It("podman run --volumes-from flag with built-in volumes", func() {
- podmanTest.RestoreArtifact(redis)
session := podmanTest.Podman([]string{"create", redis, "sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -641,7 +627,6 @@ USER mail`
})
It("podman run findmnt nothing shared", func() {
- podmanTest.RestoreArtifact(fedoraMinimal)
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
@@ -657,7 +642,6 @@ USER mail`
})
It("podman run findmnt shared", func() {
- podmanTest.RestoreArtifact(fedoraMinimal)
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
@@ -765,10 +749,9 @@ USER mail`
})
It("podman run with restart-policy always restarts containers", func() {
- podmanTest.RestoreArtifact(fedoraMinimal)
testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
- err := os.Mkdir(testDir, 0755)
+ err := os.MkdirAll(testDir, 0755)
Expect(err).To(BeNil())
aliveFile := filepath.Join(testDir, "running")
diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go
index ce6971cd1..be3f7df49 100644
--- a/test/e2e/run_userns_test.go
+++ b/test/e2e/run_userns_test.go
@@ -31,7 +31,7 @@ var _ = Describe("Podman UserNS support", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index d031ca143..d89c80909 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -26,7 +26,7 @@ var _ = Describe("Podman run with volumes", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go
index f52a2b8fc..5ef68603e 100644
--- a/test/e2e/runlabel_test.go
+++ b/test/e2e/runlabel_test.go
@@ -37,7 +37,7 @@ var _ = Describe("podman container runlabel", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go
index ffb5182d6..be1ede962 100644
--- a/test/e2e/save_test.go
+++ b/test/e2e/save_test.go
@@ -37,7 +37,7 @@ var _ = Describe("Podman save", func() {
It("podman save output flag", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -45,7 +45,7 @@ var _ = Describe("Podman save", func() {
It("podman save oci flag", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -54,7 +54,7 @@ var _ = Describe("Podman save", func() {
Skip("Pipe redirection in ginkgo probably wont work")
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", ALPINE, ">", outfile})
+ save := podmanTest.PodmanNoCache([]string{"save", ALPINE, ">", outfile})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -62,7 +62,7 @@ var _ = Describe("Podman save", func() {
It("podman save quiet flag", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-q", "-o", outfile, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "-q", "-o", outfile, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -70,7 +70,7 @@ var _ = Describe("Podman save", func() {
It("podman save bogus image", func() {
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- save := podmanTest.Podman([]string{"save", "-o", outfile, "FOOBAR"})
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, "FOOBAR"})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Not(Equal(0)))
})
@@ -81,7 +81,7 @@ var _ = Describe("Podman save", func() {
}
outdir := filepath.Join(podmanTest.TempDir, "save")
- save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -92,7 +92,7 @@ var _ = Describe("Podman save", func() {
}
outdir := filepath.Join(podmanTest.TempDir, "save")
- save := podmanTest.Podman([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -103,7 +103,7 @@ var _ = Describe("Podman save", func() {
}
outdir := filepath.Join(podmanTest.TempDir, "save")
- save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Equal(0))
})
@@ -111,7 +111,7 @@ var _ = Describe("Podman save", func() {
It("podman save bad filename", func() {
outdir := filepath.Join(podmanTest.TempDir, "save:colon")
- save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
+ save := podmanTest.PodmanNoCache([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
save.WaitWithDefaultTimeout()
Expect(save.ExitCode()).To(Not(Equal(0)))
})
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index 72b083de8..3b1da859c 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -75,8 +75,8 @@ registries = ['{{.Host}}:{{.Port}}']`
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
+ podmanTest.SeedImages()
- podmanTest.RestoreAllArtifacts()
})
AfterEach(func() {
@@ -168,7 +168,6 @@ registries = ['{{.Host}}:{{.Port}}']`
lock := GetPortLock(registryEndpoints[0].Port)
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
fakereg := podmanTest.Podman([]string{"run", "-d", "--name", "registry",
"-p", fmt.Sprintf("%s:5000", registryEndpoints[0].Port),
registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
@@ -196,7 +195,6 @@ registries = ['{{.Host}}:{{.Port}}']`
}
lock := GetPortLock(registryEndpoints[3].Port)
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
registry := podmanTest.Podman([]string{"run", "-d", "--name", "registry3",
"-p", fmt.Sprintf("%s:5000", registryEndpoints[3].Port), registry,
"/entrypoint.sh", "/etc/docker/registry/config.yml"})
@@ -207,11 +205,12 @@ registries = ['{{.Host}}:{{.Port}}']`
Skip("Can not start docker registry.")
}
+ podmanTest.RestoreArtifact(ALPINE)
image := fmt.Sprintf("%s/my-alpine", registryEndpoints[3].Address())
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
- search := podmanTest.Podman([]string{"search", image, "--tls-verify=false"})
+ search := podmanTest.PodmanNoCache([]string{"search", image, "--tls-verify=false"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
@@ -225,7 +224,6 @@ registries = ['{{.Host}}:{{.Port}}']`
lock := GetPortLock(registryEndpoints[4].Port)
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[4].Port),
"--name", "registry4", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
registry.WaitWithDefaultTimeout()
@@ -235,8 +233,9 @@ registries = ['{{.Host}}:{{.Port}}']`
Skip("Can not start docker registry.")
}
+ podmanTest.RestoreArtifact(ALPINE)
image := fmt.Sprintf("%s/my-alpine", registryEndpoints[4].Address())
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
@@ -246,7 +245,7 @@ registries = ['{{.Host}}:{{.Port}}']`
podmanTest.setRegistriesConfigEnv(buffer.Bytes())
ioutil.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644)
- search := podmanTest.Podman([]string{"search", image})
+ search := podmanTest.PodmanNoCache([]string{"search", image})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
@@ -264,7 +263,6 @@ registries = ['{{.Host}}:{{.Port}}']`
}
lock := GetPortLock(registryEndpoints[5].Port)
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[5].Port),
"--name", "registry5", registry})
registry.WaitWithDefaultTimeout()
@@ -274,8 +272,9 @@ registries = ['{{.Host}}:{{.Port}}']`
Skip("Can not start docker registry.")
}
+ podmanTest.RestoreArtifact(ALPINE)
image := fmt.Sprintf("%s/my-alpine", registryEndpoints[5].Address())
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
@@ -284,7 +283,7 @@ registries = ['{{.Host}}:{{.Port}}']`
podmanTest.setRegistriesConfigEnv(buffer.Bytes())
ioutil.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644)
- search := podmanTest.Podman([]string{"search", image, "--tls-verify=true"})
+ search := podmanTest.PodmanNoCache([]string{"search", image, "--tls-verify=true"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
@@ -302,7 +301,6 @@ registries = ['{{.Host}}:{{.Port}}']`
}
lock := GetPortLock(registryEndpoints[6].Port)
defer lock.Unlock()
- podmanTest.RestoreArtifact(registry)
registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[6].Port),
"--name", "registry6", registry})
registry.WaitWithDefaultTimeout()
@@ -312,8 +310,9 @@ registries = ['{{.Host}}:{{.Port}}']`
Skip("Can not start docker registry.")
}
+ podmanTest.RestoreArtifact(ALPINE)
image := fmt.Sprintf("%s/my-alpine", registryEndpoints[6].Address())
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
@@ -322,7 +321,7 @@ registries = ['{{.Host}}:{{.Port}}']`
podmanTest.setRegistriesConfigEnv(buffer.Bytes())
ioutil.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644)
- search := podmanTest.Podman([]string{"search", image})
+ search := podmanTest.PodmanNoCache([]string{"search", image})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
@@ -343,7 +342,6 @@ registries = ['{{.Host}}:{{.Port}}']`
lock8 := GetPortLock("6000")
defer lock8.Unlock()
- podmanTest.RestoreArtifact(registry)
registryLocal := podmanTest.Podman([]string{"run", "-d", "--net=host", "-p", fmt.Sprintf("%s:5000", registryEndpoints[7].Port),
"--name", "registry7", registry})
registryLocal.WaitWithDefaultTimeout()
@@ -361,7 +359,8 @@ registries = ['{{.Host}}:{{.Port}}']`
Skip("Can not start docker registry.")
}
- push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:6000/my-alpine"})
+ podmanTest.RestoreArtifact(ALPINE)
+ push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:6000/my-alpine"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
@@ -371,7 +370,7 @@ registries = ['{{.Host}}:{{.Port}}']`
podmanTest.setRegistriesConfigEnv(buffer.Bytes())
ioutil.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644)
- search := podmanTest.Podman([]string{"search", "my-alpine"})
+ search := podmanTest.PodmanNoCache([]string{"search", "my-alpine"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index c92da9777..fc1203ed1 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman start", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go
index 05f24539f..45511edb8 100644
--- a/test/e2e/stats_test.go
+++ b/test/e2e/stats_test.go
@@ -26,7 +26,7 @@ var _ = Describe("Podman stats", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go
index e201204df..77ab6dbb0 100644
--- a/test/e2e/stop_test.go
+++ b/test/e2e/stop_test.go
@@ -23,7 +23,7 @@ var _ = Describe("Podman stop", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go
index 92787f17c..bbbdf30b0 100644
--- a/test/e2e/system_df_test.go
+++ b/test/e2e/system_df_test.go
@@ -25,7 +25,8 @@ var _ = Describe("podman system df", func() {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
- podmanTest.RestoreAllArtifacts()
+ podmanTest.Setup()
+ podmanTest.SeedImages()
})
AfterEach(func() {
@@ -55,7 +56,7 @@ var _ = Describe("podman system df", func() {
images := strings.Fields(session.OutputToStringArray()[1])
containers := strings.Fields(session.OutputToStringArray()[2])
volumes := strings.Fields(session.OutputToStringArray()[3])
- Expect(images[1]).To(Equal("2"))
+ Expect(images[1]).To(Equal("9"))
Expect(containers[1]).To(Equal("2"))
Expect(volumes[2]).To(Equal("1"))
})
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 52efc9fca..91604867d 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -27,7 +27,7 @@ var _ = Describe("Podman systemd", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
systemd_unit_file = `[Unit]
Description=redis container
[Service]
diff --git a/test/e2e/tag_test.go b/test/e2e/tag_test.go
index 26d6dfa75..2b513015b 100644
--- a/test/e2e/tag_test.go
+++ b/test/e2e/tag_test.go
@@ -33,11 +33,11 @@ var _ = Describe("Podman tag", func() {
})
It("podman tag shortname:latest", func() {
- session := podmanTest.Podman([]string{"tag", ALPINE, "foobar:latest"})
+ session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foobar:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"inspect", "foobar:latest"})
+ results := podmanTest.PodmanNoCache([]string{"inspect", "foobar:latest"})
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
@@ -46,11 +46,11 @@ var _ = Describe("Podman tag", func() {
})
It("podman tag shortname", func() {
- session := podmanTest.Podman([]string{"tag", ALPINE, "foobar"})
+ session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foobar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"inspect", "foobar:latest"})
+ results := podmanTest.PodmanNoCache([]string{"inspect", "foobar:latest"})
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
@@ -59,11 +59,11 @@ var _ = Describe("Podman tag", func() {
})
It("podman tag shortname:tag", func() {
- session := podmanTest.Podman([]string{"tag", ALPINE, "foobar:new"})
+ session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foobar:new"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"inspect", "foobar:new"})
+ results := podmanTest.PodmanNoCache([]string{"inspect", "foobar:new"})
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
@@ -72,15 +72,15 @@ var _ = Describe("Podman tag", func() {
})
It("podman tag shortname image no tag", func() {
- session := podmanTest.Podman([]string{"tag", ALPINE, "foobar"})
+ session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foobar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"tag", "foobar", "barfoo"})
+ results := podmanTest.PodmanNoCache([]string{"tag", "foobar", "barfoo"})
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
- verify := podmanTest.Podman([]string{"inspect", "barfoo"})
+ verify := podmanTest.PodmanNoCache([]string{"inspect", "barfoo"})
verify.WaitWithDefaultTimeout()
Expect(verify.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/top_test.go b/test/e2e/top_test.go
index 4c2cdb7b5..b62d242f1 100644
--- a/test/e2e/top_test.go
+++ b/test/e2e/top_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman top", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/tree_test.go b/test/e2e/tree_test.go
index 9740adada..2db7aeb5e 100644
--- a/test/e2e/tree_test.go
+++ b/test/e2e/tree_test.go
@@ -22,7 +22,8 @@ var _ = Describe("Podman image tree", func() {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
- podmanTest.RestoreAllArtifacts()
+ podmanTest.Setup()
+ podmanTest.RestoreArtifact(BB)
})
AfterEach(func() {
@@ -36,7 +37,7 @@ var _ = Describe("Podman image tree", func() {
if podmanTest.RemoteTest {
Skip("Does not work on remote client")
}
- session := podmanTest.Podman([]string{"pull", "docker.io/library/busybox:latest"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "docker.io/library/busybox:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -47,17 +48,17 @@ ENV foo=bar
`
podmanTest.BuildImage(dockerfile, "test:latest", "true")
- session = podmanTest.Podman([]string{"image", "tree", "test:latest"})
+ session = podmanTest.PodmanNoCache([]string{"image", "tree", "test:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"image", "tree", "--whatrequires", "docker.io/library/busybox:latest"})
+ session = podmanTest.PodmanNoCache([]string{"image", "tree", "--whatrequires", "docker.io/library/busybox:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "test:latest"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "test:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"rmi", "docker.io/library/busybox:latest"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "docker.io/library/busybox:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go
index 493c4a7d5..8c97e6b28 100644
--- a/test/e2e/trust_test.go
+++ b/test/e2e/trust_test.go
@@ -27,7 +27,7 @@ var _ = Describe("Podman trust", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/unshare_test.go b/test/e2e/unshare_test.go
index 1e3f06a62..5f342ffc3 100644
--- a/test/e2e/unshare_test.go
+++ b/test/e2e/unshare_test.go
@@ -32,7 +32,7 @@ var _ = Describe("Podman unshare", func() {
podmanTest.CgroupManager = "cgroupfs"
podmanTest.StorageOptions = ROOTLESS_STORAGE_OPTIONS
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go
index 35ee21e49..2c8b3068c 100644
--- a/test/e2e/version_test.go
+++ b/test/e2e/version_test.go
@@ -27,6 +27,7 @@ var _ = Describe("Podman version", func() {
podmanTest.Cleanup()
f := CurrentGinkgoTestDescription()
processTestResult(f)
+ podmanTest.SeedImages()
})
diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go
index dccecd457..041a9e6f0 100644
--- a/test/e2e/volume_create_test.go
+++ b/test/e2e/volume_create_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman volume create", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/volume_inspect_test.go b/test/e2e/volume_inspect_test.go
index e7f20ce7b..0683c6bbf 100644
--- a/test/e2e/volume_inspect_test.go
+++ b/test/e2e/volume_inspect_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman volume inspect", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/volume_ls_test.go b/test/e2e/volume_ls_test.go
index 1f0177def..da2d7ae77 100644
--- a/test/e2e/volume_ls_test.go
+++ b/test/e2e/volume_ls_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman volume ls", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/volume_prune_test.go b/test/e2e/volume_prune_test.go
index 55a95c8c9..ba249278b 100644
--- a/test/e2e/volume_prune_test.go
+++ b/test/e2e/volume_prune_test.go
@@ -24,7 +24,7 @@ var _ = Describe("Podman volume prune", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/volume_rm_test.go b/test/e2e/volume_rm_test.go
index 39628d56f..5dcf51ccd 100644
--- a/test/e2e/volume_rm_test.go
+++ b/test/e2e/volume_rm_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman volume rm", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/e2e/wait_test.go b/test/e2e/wait_test.go
index 28a4c1e40..c03116b01 100644
--- a/test/e2e/wait_test.go
+++ b/test/e2e/wait_test.go
@@ -22,7 +22,7 @@ var _ = Describe("Podman wait", func() {
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
- podmanTest.RestoreAllArtifacts()
+ podmanTest.SeedImages()
})
AfterEach(func() {
diff --git a/test/utils/podmantest_test.go b/test/utils/podmantest_test.go
index 28f294a94..cb31d5548 100644
--- a/test/utils/podmantest_test.go
+++ b/test/utils/podmantest_test.go
@@ -23,7 +23,7 @@ var _ = Describe("PodmanTest test", func() {
FakeOutputs["check"] = []string{"check"}
os.Setenv("HOOK_OPTION", "hook_option")
env := os.Environ()
- session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, "", env)
+ session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, "", env, true)
os.Unsetenv("HOOK_OPTION")
session.WaitWithDefaultTimeout()
Expect(session.Command.Process).ShouldNot(BeNil())
diff --git a/test/utils/utils.go b/test/utils/utils.go
index beadab549..98031385d 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -42,6 +42,8 @@ type PodmanTest struct {
VarlinkSession *os.Process
VarlinkEndpoint string
VarlinkCommand *exec.Cmd
+ ImageCacheDir string
+ ImageCacheFS string
}
// PodmanSession wraps the gexec.session so we can extend it
@@ -63,7 +65,7 @@ func (p *PodmanTest) MakeOptions(args []string) []string {
// PodmanAsUserBase exec podman as user. uid and gid is set for credentials useage. env is used
// to record the env for debugging
-func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string, env []string) *PodmanSession {
+func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string, env []string, nocache bool) *PodmanSession {
var command *exec.Cmd
podmanOptions := p.MakeOptions(args)
podmanBinary := p.PodmanBinary
@@ -71,6 +73,10 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
podmanBinary = p.RemotePodmanBinary
env = append(env, fmt.Sprintf("PODMAN_VARLINK_ADDRESS=%s", p.VarlinkEndpoint))
}
+ if !nocache && !p.RemoteTest {
+ cacheOptions := []string{"--storage-opt", fmt.Sprintf("%s.imagestore=%s", p.ImageCacheFS, p.ImageCacheDir)}
+ podmanOptions = append(cacheOptions, podmanOptions...)
+ }
if env == nil {
fmt.Printf("Running: %s %s\n", podmanBinary, strings.Join(podmanOptions, " "))
@@ -99,8 +105,8 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
}
// PodmanBase exec podman with default env.
-func (p *PodmanTest) PodmanBase(args []string) *PodmanSession {
- return p.PodmanAsUserBase(args, 0, 0, "", nil)
+func (p *PodmanTest) PodmanBase(args []string, nocache bool) *PodmanSession {
+ return p.PodmanAsUserBase(args, 0, 0, "", nil, nocache)
}
// WaitForContainer waits on a started container
@@ -118,7 +124,7 @@ func (p *PodmanTest) WaitForContainer() bool {
// containers are currently running.
func (p *PodmanTest) NumberOfContainersRunning() int {
var containers []string
- ps := p.PodmanBase([]string{"ps", "-q"})
+ ps := p.PodmanBase([]string{"ps", "-q"}, true)
ps.WaitWithDefaultTimeout()
Expect(ps.ExitCode()).To(Equal(0))
for _, i := range ps.OutputToStringArray() {
@@ -133,7 +139,7 @@ func (p *PodmanTest) NumberOfContainersRunning() int {
// containers are currently defined.
func (p *PodmanTest) NumberOfContainers() int {
var containers []string
- ps := p.PodmanBase([]string{"ps", "-aq"})
+ ps := p.PodmanBase([]string{"ps", "-aq"}, true)
ps.WaitWithDefaultTimeout()
Expect(ps.ExitCode()).To(Equal(0))
for _, i := range ps.OutputToStringArray() {
@@ -148,7 +154,7 @@ func (p *PodmanTest) NumberOfContainers() int {
// pods are currently defined.
func (p *PodmanTest) NumberOfPods() int {
var pods []string
- ps := p.PodmanBase([]string{"pod", "ps", "-q"})
+ ps := p.PodmanBase([]string{"pod", "ps", "-q"}, true)
ps.WaitWithDefaultTimeout()
Expect(ps.ExitCode()).To(Equal(0))
for _, i := range ps.OutputToStringArray() {
@@ -164,7 +170,7 @@ func (p *PodmanTest) NumberOfPods() int {
func (p *PodmanTest) GetContainerStatus() string {
var podmanArgs = []string{"ps"}
podmanArgs = append(podmanArgs, "--all", "--format={{.Status}}")
- session := p.PodmanBase(podmanArgs)
+ session := p.PodmanBase(podmanArgs, true)
session.WaitWithDefaultTimeout()
return session.OutputToString()
}
@@ -172,7 +178,7 @@ func (p *PodmanTest) GetContainerStatus() string {
// WaitContainerReady waits process or service inside container start, and ready to be used.
func (p *PodmanTest) WaitContainerReady(id string, expStr string, timeout int, step int) bool {
startTime := time.Now()
- s := p.PodmanBase([]string{"logs", id})
+ s := p.PodmanBase([]string{"logs", id}, true)
s.WaitWithDefaultTimeout()
for {
@@ -185,7 +191,7 @@ func (p *PodmanTest) WaitContainerReady(id string, expStr string, timeout int, s
return true
}
time.Sleep(time.Duration(step) * time.Second)
- s = p.PodmanBase([]string{"logs", id})
+ s = p.PodmanBase([]string{"logs", id}, true)
s.WaitWithDefaultTimeout()
}
}
diff --git a/transfer.md b/transfer.md
index 79b6d3461..7cfd5a85d 100644
--- a/transfer.md
+++ b/transfer.md
@@ -91,10 +91,11 @@ Those Docker commands currently do not have equivalents in `podman`:
| Missing command | Description|
| :--- | :--- |
+| `docker container update` | podman does not support altering running containers. We recommend recreating containers with the correct arguments.|
+| `docker container rename` | podman does not support `container rename` - or the `rename` shorthand. We recommend using `podman rm` and `podman create` to create a container with a specific name.|
| `docker network` ||
| `docker node` ||
| `docker plugin` | podman does not support plugins. We recommend you use alternative OCI Runtimes or OCI Runtime Hooks to alter behavior of podman.|
-| `docker rename` | podman does not support rename, you need to use `podman rm` and `podman create` to rename a container.|
| `docker secret` ||
| `docker service` ||
| `docker stack` ||
diff --git a/vendor.conf b/vendor.conf
index 5c41d6908..65bfcd77a 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -21,7 +21,7 @@ github.com/mattn/go-isatty v0.0.4
github.com/VividCortex/ewma v1.1.1
github.com/containers/storage v1.12.7
github.com/containers/psgo v1.3.0
-github.com/coreos/go-systemd v14
+github.com/coreos/go-systemd v17
github.com/coreos/pkg v4
github.com/cri-o/ocicni 0c180f981b27ef6036fa5be29bcb4dd666e406eb
github.com/cyphar/filepath-securejoin v0.2.1
diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/NOTICE
new file mode 100644
index 000000000..23a0ada2f
--- /dev/null
+++ b/vendor/github.com/coreos/go-systemd/NOTICE
@@ -0,0 +1,5 @@
+CoreOS Project
+Copyright 2018 CoreOS, Inc
+
+This product includes software developed at CoreOS, Inc.
+(http://www.coreos.com/).
diff --git a/vendor/github.com/coreos/go-systemd/README.md b/vendor/github.com/coreos/go-systemd/README.md
index cb87a1124..cad04a803 100644
--- a/vendor/github.com/coreos/go-systemd/README.md
+++ b/vendor/github.com/coreos/go-systemd/README.md
@@ -6,9 +6,11 @@
Go bindings to systemd. The project has several packages:
- `activation` - for writing and using socket activation from Go
+- `daemon` - for notifying systemd of service status changes
- `dbus` - for starting/stopping/inspecting running services and units
- `journal` - for writing to systemd's logging service, journald
- `sdjournal` - for reading from journald by wrapping its C API
+- `login1` - for integration with the systemd logind API
- `machine1` - for registering machines/containers with systemd
- `unit` - for (de)serialization and comparison of unit files
@@ -18,10 +20,9 @@ An example HTTP server using socket activation can be quickly set up by followin
https://github.com/coreos/go-systemd/tree/master/examples/activation/httpserver
-## Journal
+## systemd Service Notification
-Using the pure-Go `journal` package you can submit journal entries directly to systemd's journal, taking advantage of features like indexed key/value pairs for each log entry.
-The `sdjournal` package provides read access to the journal by wrapping around journald's native C API; consequently it requires cgo and the journal headers to be available.
+The `daemon` package is an implementation of the [sd_notify protocol](https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description). It can be used to inform systemd of service start-up completion, watchdog events, and other status changes.
## D-Bus
@@ -45,6 +46,20 @@ Create `/etc/dbus-1/system-local.conf` that looks like this:
</busconfig>
```
+## Journal
+
+### Writing to the Journal
+
+Using the pure-Go `journal` package you can submit journal entries directly to systemd's journal, taking advantage of features like indexed key/value pairs for each log entry.
+
+### Reading from the Journal
+
+The `sdjournal` package provides read access to the journal by wrapping around journald's native C API; consequently it requires cgo and the journal headers to be available.
+
+## logind
+
+The `login1` package provides functions to integrate with the [systemd logind API](http://www.freedesktop.org/wiki/Software/systemd/logind/).
+
## machined
The `machine1` package allows interaction with the [systemd machined D-Bus API](http://www.freedesktop.org/wiki/Software/systemd/machined/).
diff --git a/vendor/github.com/coreos/go-systemd/activation/files.go b/vendor/github.com/coreos/go-systemd/activation/files.go
index c8e85fcd5..29dd18def 100644
--- a/vendor/github.com/coreos/go-systemd/activation/files.go
+++ b/vendor/github.com/coreos/go-systemd/activation/files.go
@@ -18,18 +18,26 @@ package activation
import (
"os"
"strconv"
+ "strings"
"syscall"
)
-// based on: https://gist.github.com/alberts/4640792
const (
+ // listenFdsStart corresponds to `SD_LISTEN_FDS_START`.
listenFdsStart = 3
)
+// Files returns a slice containing a `os.File` object for each
+// file descriptor passed to this process via systemd fd-passing protocol.
+//
+// The order of the file descriptors is preserved in the returned slice.
+// `unsetEnv` is typically set to `true` in order to avoid clashes in
+// fd usage and to avoid leaking environment flags to child processes.
func Files(unsetEnv bool) []*os.File {
if unsetEnv {
defer os.Unsetenv("LISTEN_PID")
defer os.Unsetenv("LISTEN_FDS")
+ defer os.Unsetenv("LISTEN_FDNAMES")
}
pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
@@ -42,10 +50,17 @@ func Files(unsetEnv bool) []*os.File {
return nil
}
+ names := strings.Split(os.Getenv("LISTEN_FDNAMES"), ":")
+
files := make([]*os.File, 0, nfds)
for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
syscall.CloseOnExec(fd)
- files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
+ name := "LISTEN_FD_" + strconv.Itoa(fd)
+ offset := fd - listenFdsStart
+ if offset < len(names) && len(names[offset]) > 0 {
+ name = names[offset]
+ }
+ files = append(files, os.NewFile(uintptr(fd), name))
}
return files
diff --git a/vendor/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/coreos/go-systemd/activation/listeners.go
index fd5dfc709..bb5cc2311 100644
--- a/vendor/github.com/coreos/go-systemd/activation/listeners.go
+++ b/vendor/github.com/coreos/go-systemd/activation/listeners.go
@@ -25,13 +25,33 @@ import (
// The order of the file descriptors is preserved in the returned slice.
// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
// corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener}
-func Listeners(unsetEnv bool) ([]net.Listener, error) {
- files := Files(unsetEnv)
+func Listeners() ([]net.Listener, error) {
+ files := Files(true)
listeners := make([]net.Listener, len(files))
for i, f := range files {
if pc, err := net.FileListener(f); err == nil {
listeners[i] = pc
+ f.Close()
+ }
+ }
+ return listeners, nil
+}
+
+// ListenersWithNames maps a listener name to a set of net.Listener instances.
+func ListenersWithNames() (map[string][]net.Listener, error) {
+ files := Files(true)
+ listeners := map[string][]net.Listener{}
+
+ for _, f := range files {
+ if pc, err := net.FileListener(f); err == nil {
+ current, ok := listeners[f.Name()]
+ if !ok {
+ listeners[f.Name()] = []net.Listener{pc}
+ } else {
+ listeners[f.Name()] = append(current, pc)
+ }
+ f.Close()
}
}
return listeners, nil
@@ -40,8 +60,8 @@ func Listeners(unsetEnv bool) ([]net.Listener, error) {
// TLSListeners returns a slice containing a net.listener for each matching TCP socket type
// passed to this process.
// It uses default Listeners func and forces TCP sockets handlers to use TLS based on tlsConfig.
-func TLSListeners(unsetEnv bool, tlsConfig *tls.Config) ([]net.Listener, error) {
- listeners, err := Listeners(unsetEnv)
+func TLSListeners(tlsConfig *tls.Config) ([]net.Listener, error) {
+ listeners, err := Listeners()
if listeners == nil || err != nil {
return nil, err
@@ -58,3 +78,26 @@ func TLSListeners(unsetEnv bool, tlsConfig *tls.Config) ([]net.Listener, error)
return listeners, err
}
+
+// TLSListenersWithNames maps a listener name to a net.Listener with
+// the associated TLS configuration.
+func TLSListenersWithNames(tlsConfig *tls.Config) (map[string][]net.Listener, error) {
+ listeners, err := ListenersWithNames()
+
+ if listeners == nil || err != nil {
+ return nil, err
+ }
+
+ if tlsConfig != nil && err == nil {
+ for _, ll := range listeners {
+ // Activate TLS only for TCP sockets
+ for i, l := range ll {
+ if l.Addr().Network() == "tcp" {
+ ll[i] = tls.NewListener(l, tlsConfig)
+ }
+ }
+ }
+ }
+
+ return listeners, err
+}
diff --git a/vendor/github.com/coreos/go-systemd/activation/packetconns.go b/vendor/github.com/coreos/go-systemd/activation/packetconns.go
index 48b2ca029..a97206785 100644
--- a/vendor/github.com/coreos/go-systemd/activation/packetconns.go
+++ b/vendor/github.com/coreos/go-systemd/activation/packetconns.go
@@ -24,13 +24,14 @@ import (
// The order of the file descriptors is preserved in the returned slice.
// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
// corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn}
-func PacketConns(unsetEnv bool) ([]net.PacketConn, error) {
- files := Files(unsetEnv)
+func PacketConns() ([]net.PacketConn, error) {
+ files := Files(true)
conns := make([]net.PacketConn, len(files))
for i, f := range files {
if pc, err := net.FilePacketConn(f); err == nil {
conns[i] = pc
+ f.Close()
}
}
return conns, nil
diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/dbus/dbus.go
index c1694fb52..1d54810af 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/dbus.go
+++ b/vendor/github.com/coreos/go-systemd/dbus/dbus.go
@@ -16,6 +16,7 @@
package dbus
import (
+ "encoding/hex"
"fmt"
"os"
"strconv"
@@ -60,6 +61,27 @@ func PathBusEscape(path string) string {
return string(n)
}
+// pathBusUnescape is the inverse of PathBusEscape.
+func pathBusUnescape(path string) string {
+ if path == "_" {
+ return ""
+ }
+ n := []byte{}
+ for i := 0; i < len(path); i++ {
+ c := path[i]
+ if c == '_' && i+2 < len(path) {
+ res, err := hex.DecodeString(path[i+1 : i+3])
+ if err == nil {
+ n = append(n, res...)
+ }
+ i += 2
+ } else {
+ n = append(n, c)
+ }
+ }
+ return string(n)
+}
+
// Conn is a connection to systemd's dbus endpoint.
type Conn struct {
// sysconn/sysobj are only used to call dbus methods
@@ -74,13 +96,18 @@ type Conn struct {
jobs map[dbus.ObjectPath]chan<- string
sync.Mutex
}
- subscriber struct {
+ subStateSubscriber struct {
updateCh chan<- *SubStateUpdate
errCh chan<- error
sync.Mutex
ignore map[dbus.ObjectPath]int64
cleanIgnore int64
}
+ propertiesSubscriber struct {
+ updateCh chan<- *PropertiesUpdate
+ errCh chan<- error
+ sync.Mutex
+ }
}
// New establishes a connection to any available bus and authenticates.
@@ -152,7 +179,7 @@ func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) {
sigobj: systemdObject(sigconn),
}
- c.subscriber.ignore = make(map[dbus.ObjectPath]int64)
+ c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64)
c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string)
// Setup the listeners on jobs so that we can get completions
diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/coreos/go-systemd/dbus/methods.go
index ab17f7cc7..0b4207229 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/methods.go
+++ b/vendor/github.com/coreos/go-systemd/dbus/methods.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2015, 2018 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package dbus
import (
"errors"
+ "fmt"
"path"
"strconv"
@@ -148,14 +149,27 @@ func (c *Conn) ResetFailedUnit(name string) error {
return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
}
-// getProperties takes the unit name and returns all of its dbus object properties, for the given dbus interface
-func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]interface{}, error) {
+// SystemState returns the systemd state. Equivalent to `systemctl is-system-running`.
+func (c *Conn) SystemState() (*Property, error) {
+ var err error
+ var prop dbus.Variant
+
+ obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")
+ err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Property{Name: "SystemState", Value: prop}, nil
+}
+
+// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface
+func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) {
var err error
var props map[string]dbus.Variant
- path := unitPath(unit)
if !path.IsValid() {
- return nil, errors.New("invalid unit name: " + unit)
+ return nil, fmt.Errorf("invalid unit name: %v", path)
}
obj := c.sysconn.Object("org.freedesktop.systemd1", path)
@@ -172,9 +186,15 @@ func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]inte
return out, nil
}
-// GetUnitProperties takes the unit name and returns all of its dbus object properties.
+// GetUnitProperties takes the (unescaped) unit name and returns all of its dbus object properties.
func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) {
- return c.getProperties(unit, "org.freedesktop.systemd1.Unit")
+ path := unitPath(unit)
+ return c.getProperties(path, "org.freedesktop.systemd1.Unit")
+}
+
+// GetUnitProperties takes the (escaped) unit path and returns all of its dbus object properties.
+func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) {
+ return c.getProperties(path, "org.freedesktop.systemd1.Unit")
}
func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) {
@@ -208,7 +228,8 @@ func (c *Conn) GetServiceProperty(service string, propertyName string) (*Propert
// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope
// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit
func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) {
- return c.getProperties(unit, "org.freedesktop.systemd1."+unitType)
+ path := unitPath(unit)
+ return c.getProperties(path, "org.freedesktop.systemd1."+unitType)
}
// SetUnitProperties() may be used to modify certain unit properties at runtime.
@@ -292,6 +313,7 @@ func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitSt
// names and returns an UnitStatus array. Comparing to ListUnitsByPatterns
// method, this method returns statuses even for inactive or non-existing
// units. Input array should contain exact unit names, but not patterns.
+// Note: Requires systemd v230 or higher
func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) {
return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store)
}
@@ -563,3 +585,8 @@ func (c *Conn) Reload() error {
func unitPath(name string) dbus.ObjectPath {
return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name))
}
+
+// unitName returns the unescaped base element of the supplied escaped path
+func unitName(dpath dbus.ObjectPath) string {
+ return pathBusUnescape(path.Base(string(dpath)))
+}
diff --git a/vendor/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/coreos/go-systemd/dbus/set.go
index f92e6fbed..17c5d4856 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/set.go
+++ b/vendor/github.com/coreos/go-systemd/dbus/set.go
@@ -36,7 +36,7 @@ func (s *set) Length() int {
}
func (s *set) Values() (values []string) {
- for val, _ := range s.data {
+ for val := range s.data {
values = append(values, val)
}
return
diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/dbus/subscription.go
index 996451445..70e63a6f1 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/subscription.go
+++ b/vendor/github.com/coreos/go-systemd/dbus/subscription.go
@@ -16,6 +16,7 @@ package dbus
import (
"errors"
+ "log"
"time"
"github.com/godbus/dbus"
@@ -36,22 +37,12 @@ func (c *Conn) Subscribe() error {
c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
"type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'")
- err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store()
- if err != nil {
- return err
- }
-
- return nil
+ return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store()
}
// Unsubscribe this connection from systemd dbus events.
func (c *Conn) Unsubscribe() error {
- err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store()
- if err != nil {
- return err
- }
-
- return nil
+ return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store()
}
func (c *Conn) dispatch() {
@@ -70,7 +61,8 @@ func (c *Conn) dispatch() {
c.jobComplete(signal)
}
- if c.subscriber.updateCh == nil {
+ if c.subStateSubscriber.updateCh == nil &&
+ c.propertiesSubscriber.updateCh == nil {
continue
}
@@ -84,6 +76,12 @@ func (c *Conn) dispatch() {
case "org.freedesktop.DBus.Properties.PropertiesChanged":
if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" {
unitPath = signal.Path
+
+ if len(signal.Body) >= 2 {
+ if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok {
+ c.sendPropertiesUpdate(unitPath, changed)
+ }
+ }
}
}
@@ -169,42 +167,80 @@ type SubStateUpdate struct {
// is full, it attempts to write an error to errCh; if errCh is full, the error
// passes silently.
func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) {
- c.subscriber.Lock()
- defer c.subscriber.Unlock()
- c.subscriber.updateCh = updateCh
- c.subscriber.errCh = errCh
+ if c == nil {
+ msg := "nil receiver"
+ select {
+ case errCh <- errors.New(msg):
+ default:
+ log.Printf("full error channel while reporting: %s\n", msg)
+ }
+ return
+ }
+
+ c.subStateSubscriber.Lock()
+ defer c.subStateSubscriber.Unlock()
+ c.subStateSubscriber.updateCh = updateCh
+ c.subStateSubscriber.errCh = errCh
}
-func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) {
- c.subscriber.Lock()
- defer c.subscriber.Unlock()
+func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) {
+ c.subStateSubscriber.Lock()
+ defer c.subStateSubscriber.Unlock()
+
+ if c.subStateSubscriber.updateCh == nil {
+ return
+ }
- if c.shouldIgnore(path) {
+ isIgnored := c.shouldIgnore(unitPath)
+ defer c.cleanIgnore()
+ if isIgnored {
return
}
- info, err := c.GetUnitProperties(string(path))
+ info, err := c.GetUnitPathProperties(unitPath)
if err != nil {
select {
- case c.subscriber.errCh <- err:
+ case c.subStateSubscriber.errCh <- err:
default:
+ log.Printf("full error channel while reporting: %s\n", err)
}
+ return
}
+ defer c.updateIgnore(unitPath, info)
- name := info["Id"].(string)
- substate := info["SubState"].(string)
+ name, ok := info["Id"].(string)
+ if !ok {
+ msg := "failed to cast info.Id"
+ select {
+ case c.subStateSubscriber.errCh <- errors.New(msg):
+ default:
+ log.Printf("full error channel while reporting: %s\n", err)
+ }
+ return
+ }
+ substate, ok := info["SubState"].(string)
+ if !ok {
+ msg := "failed to cast info.SubState"
+ select {
+ case c.subStateSubscriber.errCh <- errors.New(msg):
+ default:
+ log.Printf("full error channel while reporting: %s\n", msg)
+ }
+ return
+ }
update := &SubStateUpdate{name, substate}
select {
- case c.subscriber.updateCh <- update:
+ case c.subStateSubscriber.updateCh <- update:
default:
+ msg := "update channel is full"
select {
- case c.subscriber.errCh <- errors.New("update channel full!"):
+ case c.subStateSubscriber.errCh <- errors.New(msg):
default:
+ log.Printf("full error channel while reporting: %s\n", msg)
}
+ return
}
-
- c.updateIgnore(path, info)
}
// The ignore functions work around a wart in the systemd dbus interface.
@@ -222,29 +258,76 @@ func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) {
// the properties).
func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool {
- t, ok := c.subscriber.ignore[path]
+ t, ok := c.subStateSubscriber.ignore[path]
return ok && t >= time.Now().UnixNano()
}
func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) {
- c.cleanIgnore()
+ loadState, ok := info["LoadState"].(string)
+ if !ok {
+ return
+ }
// unit is unloaded - it will trigger bad systemd dbus behavior
- if info["LoadState"].(string) == "not-found" {
- c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval
+ if loadState == "not-found" {
+ c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval
}
}
// without this, ignore would grow unboundedly over time
func (c *Conn) cleanIgnore() {
now := time.Now().UnixNano()
- if c.subscriber.cleanIgnore < now {
- c.subscriber.cleanIgnore = now + cleanIgnoreInterval
+ if c.subStateSubscriber.cleanIgnore < now {
+ c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval
- for p, t := range c.subscriber.ignore {
+ for p, t := range c.subStateSubscriber.ignore {
if t < now {
- delete(c.subscriber.ignore, p)
+ delete(c.subStateSubscriber.ignore, p)
}
}
}
}
+
+// PropertiesUpdate holds a map of a unit's changed properties
+type PropertiesUpdate struct {
+ UnitName string
+ Changed map[string]dbus.Variant
+}
+
+// SetPropertiesSubscriber writes to updateCh when any unit's properties
+// change. Every property change reported by systemd will be sent; that is, no
+// transitions will be "missed" (as they might be with SetSubStateSubscriber).
+// However, state changes will only be written to the channel with non-blocking
+// writes. If updateCh is full, it attempts to write an error to errCh; if
+// errCh is full, the error passes silently.
+func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) {
+ c.propertiesSubscriber.Lock()
+ defer c.propertiesSubscriber.Unlock()
+ c.propertiesSubscriber.updateCh = updateCh
+ c.propertiesSubscriber.errCh = errCh
+}
+
+// we don't need to worry about shouldIgnore() here because
+// sendPropertiesUpdate doesn't call GetProperties()
+func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) {
+ c.propertiesSubscriber.Lock()
+ defer c.propertiesSubscriber.Unlock()
+
+ if c.propertiesSubscriber.updateCh == nil {
+ return
+ }
+
+ update := &PropertiesUpdate{unitName(unitPath), changedProps}
+
+ select {
+ case c.propertiesSubscriber.updateCh <- update:
+ default:
+ msg := "update channel is full"
+ select {
+ case c.propertiesSubscriber.errCh <- errors.New(msg):
+ default:
+ log.Printf("full error channel while reporting: %s\n", msg)
+ }
+ return
+ }
+}
diff --git a/vendor/github.com/coreos/go-systemd/journal/journal.go b/vendor/github.com/coreos/go-systemd/journal/journal.go
index 7f434990d..ef85a3ba2 100644
--- a/vendor/github.com/coreos/go-systemd/journal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/journal/journal.go
@@ -103,7 +103,10 @@ func Send(message string, priority Priority, vars map[string]string) error {
if !ok {
return journalError("can't send file through non-Unix connection")
}
- unixConn.WriteMsgUnix([]byte{}, rights, nil)
+ _, _, err = unixConn.WriteMsgUnix([]byte{}, rights, nil)
+ if err != nil {
+ return journalError(err.Error())
+ }
} else if err != nil {
return journalError(err.Error())
}
@@ -165,7 +168,7 @@ func tempFd() (*os.File, error) {
if err != nil {
return nil, err
}
- syscall.Unlink(file.Name())
+ err = syscall.Unlink(file.Name())
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go b/vendor/github.com/coreos/go-systemd/sdjournal/journal.go
index b00d606c1..9f3d92342 100644
--- a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/sdjournal/journal.go
@@ -47,6 +47,15 @@ package sdjournal
// return sd_journal_open_directory(ret, path, flags);
// }
//
+// int
+// my_sd_journal_open_files(void *f, sd_journal **ret, const char **paths, int flags)
+// {
+// int (*sd_journal_open_files)(sd_journal **, const char **, int);
+//
+// sd_journal_open_files = f;
+// return sd_journal_open_files(ret, paths, flags);
+// }
+//
// void
// my_sd_journal_close(void *f, sd_journal *j)
// {
@@ -282,9 +291,19 @@ package sdjournal
// sd_journal_restart_unique(j);
// }
//
+// int
+// my_sd_journal_get_catalog(void *f, sd_journal *j, char **ret)
+// {
+// int(*sd_journal_get_catalog)(sd_journal *, char **);
+//
+// sd_journal_get_catalog = f;
+// return sd_journal_get_catalog(j, ret);
+// }
+//
import "C"
import (
"bytes"
+ "errors"
"fmt"
"strings"
"sync"
@@ -352,6 +371,12 @@ const (
IndefiniteWait time.Duration = 1<<63 - 1
)
+var (
+ // ErrNoTestCursor gets returned when using TestCursor function and cursor
+ // parameter is not the same as the current cursor position.
+ ErrNoTestCursor = errors.New("Cursor parameter is not the same as current position")
+)
+
// Journal is a Go wrapper of an sd_journal structure.
type Journal struct {
cjournal *C.sd_journal
@@ -396,8 +421,7 @@ func NewJournal() (j *Journal, err error) {
}
// NewJournalFromDir returns a new Journal instance pointing to a journal residing
-// in a given directory. The supplied path may be relative or absolute; if
-// relative, it will be converted to an absolute path before being opened.
+// in a given directory.
func NewJournalFromDir(path string) (j *Journal, err error) {
j = &Journal{}
@@ -417,6 +441,32 @@ func NewJournalFromDir(path string) (j *Journal, err error) {
return j, nil
}
+// NewJournalFromFiles returns a new Journal instance pointing to a journals residing
+// in a given files.
+func NewJournalFromFiles(paths ...string) (j *Journal, err error) {
+ j = &Journal{}
+
+ sd_journal_open_files, err := getFunction("sd_journal_open_files")
+ if err != nil {
+ return nil, err
+ }
+
+ // by making the slice 1 elem too long, we guarantee it'll be null-terminated
+ cPaths := make([]*C.char, len(paths)+1)
+ for idx, path := range paths {
+ p := C.CString(path)
+ cPaths[idx] = p
+ defer C.free(unsafe.Pointer(p))
+ }
+
+ r := C.my_sd_journal_open_files(sd_journal_open_files, &j.cjournal, &cPaths[0], 0)
+ if r < 0 {
+ return nil, fmt.Errorf("failed to open journals in paths %q: %d", paths, syscall.Errno(-r))
+ }
+
+ return j, nil
+}
+
// Close closes a journal opened with NewJournal.
func (j *Journal) Close() error {
sd_journal_close, err := getFunction("sd_journal_close")
@@ -598,7 +648,8 @@ func (j *Journal) getData(field string) (unsafe.Pointer, C.int, error) {
}
// GetData gets the data object associated with a specific field from the
-// current journal entry.
+// the journal entry referenced by the last completed Next/Previous function
+// call. To call GetData, you must have first called one of these functions.
func (j *Journal) GetData(field string) (string, error) {
d, l, err := j.getData(field)
if err != nil {
@@ -609,7 +660,9 @@ func (j *Journal) GetData(field string) (string, error) {
}
// GetDataValue gets the data object associated with a specific field from the
-// current journal entry, returning only the value of the object.
+// journal entry referenced by the last completed Next/Previous function call,
+// returning only the value of the object. To call GetDataValue, you must first
+// have called one of the Next/Previous functions.
func (j *Journal) GetDataValue(field string) (string, error) {
val, err := j.GetData(field)
if err != nil {
@@ -620,7 +673,8 @@ func (j *Journal) GetDataValue(field string) (string, error) {
}
// GetDataBytes gets the data object associated with a specific field from the
-// current journal entry.
+// journal entry referenced by the last completed Next/Previous function call.
+// To call GetDataBytes, you must first have called one of these functions.
func (j *Journal) GetDataBytes(field string) ([]byte, error) {
d, l, err := j.getData(field)
if err != nil {
@@ -631,7 +685,9 @@ func (j *Journal) GetDataBytes(field string) ([]byte, error) {
}
// GetDataValueBytes gets the data object associated with a specific field from the
-// current journal entry, returning only the value of the object.
+// journal entry referenced by the last completed Next/Previous function call,
+// returning only the value of the object. To call GetDataValueBytes, you must first
+// have called one of the Next/Previous functions.
func (j *Journal) GetDataValueBytes(field string) ([]byte, error) {
val, err := j.GetDataBytes(field)
if err != nil {
@@ -641,9 +697,10 @@ func (j *Journal) GetDataValueBytes(field string) ([]byte, error) {
return bytes.SplitN(val, []byte("="), 2)[1], nil
}
-// GetEntry returns a full representation of a journal entry with
-// all key-value pairs of data as well as address fields (cursor, realtime
-// timestamp and monotonic timestamp)
+// GetEntry returns a full representation of the journal entry referenced by the
+// last completed Next/Previous function call, with all key-value pairs of data
+// as well as address fields (cursor, realtime timestamp and monotonic timestamp).
+// To call GetEntry, you must first have called one of the Next/Previous functions.
func (j *Journal) GetEntry() (*JournalEntry, error) {
sd_journal_get_realtime_usec, err := getFunction("sd_journal_get_realtime_usec")
if err != nil {
@@ -731,7 +788,7 @@ func (j *Journal) GetEntry() (*JournalEntry, error) {
return entry, nil
}
-// SetDataThresold sets the data field size threshold for data returned by
+// SetDataThreshold sets the data field size threshold for data returned by
// GetData. To retrieve the complete data fields this threshold should be
// turned off by setting it to 0, so that the library always returns the
// complete data objects.
@@ -752,8 +809,10 @@ func (j *Journal) SetDataThreshold(threshold uint64) error {
return nil
}
-// GetRealtimeUsec gets the realtime (wallclock) timestamp of the current
-// journal entry.
+// GetRealtimeUsec gets the realtime (wallclock) timestamp of the journal
+// entry referenced by the last completed Next/Previous function call. To
+// call GetRealtimeUsec, you must first have called one of the Next/Previous
+// functions.
func (j *Journal) GetRealtimeUsec() (uint64, error) {
var usec C.uint64_t
@@ -773,7 +832,10 @@ func (j *Journal) GetRealtimeUsec() (uint64, error) {
return uint64(usec), nil
}
-// GetMonotonicUsec gets the monotonic timestamp of the current journal entry.
+// GetMonotonicUsec gets the monotonic timestamp of the journal entry
+// referenced by the last completed Next/Previous function call. To call
+// GetMonotonicUsec, you must first have called one of the Next/Previous
+// functions.
func (j *Journal) GetMonotonicUsec() (uint64, error) {
var usec C.uint64_t
var boot_id C.sd_id128_t
@@ -794,7 +856,9 @@ func (j *Journal) GetMonotonicUsec() (uint64, error) {
return uint64(usec), nil
}
-// GetCursor gets the cursor of the current journal entry.
+// GetCursor gets the cursor of the last journal entry reeferenced by the
+// last completed Next/Previous function call. To call GetCursor, you must
+// first have called one of the Next/Previous functions.
func (j *Journal) GetCursor() (string, error) {
sd_journal_get_cursor, err := getFunction("sd_journal_get_cursor")
if err != nil {
@@ -836,13 +900,16 @@ func (j *Journal) TestCursor(cursor string) error {
if r < 0 {
return fmt.Errorf("failed to test to cursor %q: %d", cursor, syscall.Errno(-r))
+ } else if r == 0 {
+ return ErrNoTestCursor
}
return nil
}
// SeekHead seeks to the beginning of the journal, i.e. the oldest available
-// entry.
+// entry. This call must be followed by a call to Next before any call to
+// Get* will return data about the first element.
func (j *Journal) SeekHead() error {
sd_journal_seek_head, err := getFunction("sd_journal_seek_head")
if err != nil {
@@ -861,7 +928,8 @@ func (j *Journal) SeekHead() error {
}
// SeekTail may be used to seek to the end of the journal, i.e. the most recent
-// available entry.
+// available entry. This call must be followed by a call to Next before any
+// call to Get* will return data about the last element.
func (j *Journal) SeekTail() error {
sd_journal_seek_tail, err := getFunction("sd_journal_seek_tail")
if err != nil {
@@ -880,7 +948,8 @@ func (j *Journal) SeekTail() error {
}
// SeekRealtimeUsec seeks to the entry with the specified realtime (wallclock)
-// timestamp, i.e. CLOCK_REALTIME.
+// timestamp, i.e. CLOCK_REALTIME. This call must be followed by a call to
+// Next/Previous before any call to Get* will return data about the sought entry.
func (j *Journal) SeekRealtimeUsec(usec uint64) error {
sd_journal_seek_realtime_usec, err := getFunction("sd_journal_seek_realtime_usec")
if err != nil {
@@ -898,7 +967,9 @@ func (j *Journal) SeekRealtimeUsec(usec uint64) error {
return nil
}
-// SeekCursor seeks to a concrete journal cursor.
+// SeekCursor seeks to a concrete journal cursor. This call must be
+// followed by a call to Next/Previous before any call to Get* will return
+// data about the sought entry.
func (j *Journal) SeekCursor(cursor string) error {
sd_journal_seek_cursor, err := getFunction("sd_journal_seek_cursor")
if err != nil {
@@ -937,7 +1008,7 @@ func (j *Journal) Wait(timeout time.Duration) int {
// equivalent hex value.
to = 0xffffffffffffffff
} else {
- to = uint64(time.Now().Add(timeout).Unix() / 1000)
+ to = uint64(timeout / time.Microsecond)
}
j.mu.Lock()
r := C.my_sd_journal_wait(sd_journal_wait, j.cjournal, C.uint64_t(to))
@@ -1022,3 +1093,28 @@ func (j *Journal) GetUniqueValues(field string) ([]string, error) {
return result, nil
}
+
+// GetCatalog retrieves a message catalog entry for the journal entry referenced
+// by the last completed Next/Previous function call. To call GetCatalog, you
+// must first have called one of these functions.
+func (j *Journal) GetCatalog() (string, error) {
+ sd_journal_get_catalog, err := getFunction("sd_journal_get_catalog")
+ if err != nil {
+ return "", err
+ }
+
+ var c *C.char
+
+ j.mu.Lock()
+ r := C.my_sd_journal_get_catalog(sd_journal_get_catalog, j.cjournal, &c)
+ j.mu.Unlock()
+ defer C.free(unsafe.Pointer(c))
+
+ if r < 0 {
+ return "", fmt.Errorf("failed to retrieve catalog entry for current journal entry: %d", syscall.Errno(-r))
+ }
+
+ catalog := C.GoString(c)
+
+ return catalog, nil
+}
diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/read.go b/vendor/github.com/coreos/go-systemd/sdjournal/read.go
index b581f03b4..51a060fb5 100644
--- a/vendor/github.com/coreos/go-systemd/sdjournal/read.go
+++ b/vendor/github.com/coreos/go-systemd/sdjournal/read.go
@@ -21,10 +21,13 @@ import (
"io"
"log"
"strings"
+ "sync"
"time"
)
var (
+ // ErrExpired gets returned when the Follow function runs into the
+ // specified timeout.
ErrExpired = errors.New("Timeout expired")
)
@@ -44,6 +47,11 @@ type JournalReaderConfig struct {
// If not empty, the journal instance will point to a journal residing
// in this directory. The supplied path may be relative or absolute.
Path string
+
+ // If not nil, Formatter will be used to translate the resulting entries
+ // into strings. If not set, the default format (timestamp and message field)
+ // will be used. If Formatter returns an error, Read will stop and return the error.
+ Formatter func(entry *JournalEntry) (string, error)
}
// JournalReader is an io.ReadCloser which provides a simple interface for iterating through the
@@ -51,12 +59,20 @@ type JournalReaderConfig struct {
type JournalReader struct {
journal *Journal
msgReader *strings.Reader
+ formatter func(entry *JournalEntry) (string, error)
}
// NewJournalReader creates a new JournalReader with configuration options that are similar to the
// systemd journalctl tool's iteration and filtering features.
func NewJournalReader(config JournalReaderConfig) (*JournalReader, error) {
- r := &JournalReader{}
+ // use simpleMessageFormatter as default formatter.
+ if config.Formatter == nil {
+ config.Formatter = simpleMessageFormatter
+ }
+
+ r := &JournalReader{
+ formatter: config.Formatter,
+ }
// Open the journal
var err error
@@ -71,7 +87,9 @@ func NewJournalReader(config JournalReaderConfig) (*JournalReader, error) {
// Add any supplied matches
for _, m := range config.Matches {
- r.journal.AddMatch(m.String())
+ if err = r.journal.AddMatch(m.String()); err != nil {
+ return nil, err
+ }
}
// Set the start position based on options
@@ -118,14 +136,10 @@ func NewJournalReader(config JournalReaderConfig) (*JournalReader, error) {
// don't fit in the read buffer. Callers should keep calling until 0 and/or an
// error is returned.
func (r *JournalReader) Read(b []byte) (int, error) {
- var err error
-
if r.msgReader == nil {
- var c uint64
-
// Advance the journal cursor. It has to be called at least one time
// before reading
- c, err = r.journal.Next()
+ c, err := r.journal.Next()
// An unexpected error
if err != nil {
@@ -137,10 +151,13 @@ func (r *JournalReader) Read(b []byte) (int, error) {
return 0, io.EOF
}
- // Build a message
- var msg string
- msg, err = r.buildMessage()
+ entry, err := r.journal.GetEntry()
+ if err != nil {
+ return 0, err
+ }
+ // Build a message
+ msg, err := r.formatter(entry)
if err != nil {
return 0, err
}
@@ -148,8 +165,7 @@ func (r *JournalReader) Read(b []byte) (int, error) {
}
// Copy and return the message
- var sz int
- sz, err = r.msgReader.Read(b)
+ sz, err := r.msgReader.Read(b)
if err == io.EOF {
// The current entry has been fully read. Don't propagate this
// EOF, so the next entry can be read at the next Read()
@@ -180,80 +196,76 @@ func (r *JournalReader) Rewind() error {
// Follow synchronously follows the JournalReader, writing each new journal entry to writer. The
// follow will continue until a single time.Time is received on the until channel.
-func (r *JournalReader) Follow(until <-chan time.Time, writer io.Writer) (err error) {
+func (r *JournalReader) Follow(until <-chan time.Time, writer io.Writer) error {
// Process journal entries and events. Entries are flushed until the tail or
// timeout is reached, and then we wait for new events or the timeout.
var msg = make([]byte, 64*1<<(10))
+ var waitCh = make(chan int, 1)
+ var waitGroup sync.WaitGroup
+ defer waitGroup.Wait()
+
process:
for {
c, err := r.Read(msg)
if err != nil && err != io.EOF {
- break process
+ return err
}
select {
case <-until:
return ErrExpired
default:
- if c > 0 {
- if _, err = writer.Write(msg[:c]); err != nil {
- break process
- }
- continue process
+ }
+ if c > 0 {
+ if _, err = writer.Write(msg[:c]); err != nil {
+ return err
}
+ continue process
}
// We're at the tail, so wait for new events or time out.
// Holds journal events to process. Tightly bounded for now unless there's a
// reason to unblock the journal watch routine more quickly.
- events := make(chan int, 1)
- pollDone := make(chan bool, 1)
- go func() {
- for {
- select {
- case <-pollDone:
- return
+ for {
+ waitGroup.Add(1)
+ go func() {
+ status := r.journal.Wait(100 * time.Millisecond)
+ waitCh <- status
+ waitGroup.Done()
+ }()
+
+ select {
+ case <-until:
+ return ErrExpired
+ case e := <-waitCh:
+ switch e {
+ case SD_JOURNAL_NOP:
+ // the journal did not change since the last invocation
+ case SD_JOURNAL_APPEND, SD_JOURNAL_INVALIDATE:
+ continue process
default:
- events <- r.journal.Wait(time.Duration(1) * time.Second)
- }
- }
- }()
+ if e < 0 {
+ return fmt.Errorf("received error event: %d", e)
+ }
- select {
- case <-until:
- pollDone <- true
- return ErrExpired
- case e := <-events:
- pollDone <- true
- switch e {
- case SD_JOURNAL_NOP, SD_JOURNAL_APPEND, SD_JOURNAL_INVALIDATE:
- // TODO: need to account for any of these?
- default:
- log.Printf("Received unknown event: %d\n", e)
+ log.Printf("received unknown event: %d\n", e)
+ }
}
- continue process
}
}
-
- return
}
-// buildMessage returns a string representing the current journal entry in a simple format which
+// simpleMessageFormatter is the default formatter.
+// It returns a string representing the current journal entry in a simple format which
// includes the entry timestamp and MESSAGE field.
-func (r *JournalReader) buildMessage() (string, error) {
- var msg string
- var usec uint64
- var err error
-
- if msg, err = r.journal.GetData("MESSAGE"); err != nil {
- return "", err
- }
-
- if usec, err = r.journal.GetRealtimeUsec(); err != nil {
- return "", err
+func simpleMessageFormatter(entry *JournalEntry) (string, error) {
+ msg, ok := entry.Fields["MESSAGE"]
+ if !ok {
+ return "", fmt.Errorf("no MESSAGE field present in journal entry")
}
+ usec := entry.RealtimeTimestamp
timestamp := time.Unix(0, int64(usec)*int64(time.Microsecond))
return fmt.Sprintf("%s %s\n", timestamp, msg), nil