summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/main.go1
-rw-r--r--cmd/podman/pod_inspect.go9
-rw-r--r--cmd/podman/pod_top.go26
-rw-r--r--cmd/podman/tree.go2
-rwxr-xr-xcontrib/cirrus/notice_master_failure.sh3
-rwxr-xr-xcontrib/cirrus/setup_environment.sh2
-rw-r--r--docs/podman-image.1.md2
-rw-r--r--docs/podman-ps.1.md9
-rw-r--r--libpod/container_log.go7
-rw-r--r--libpod/runtime.go37
-rw-r--r--pkg/util/utils.go53
-rw-r--r--test/e2e/logs_test.go10
-rw-r--r--test/e2e/rootless_test.go15
13 files changed, 129 insertions, 47 deletions
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index b130f3232..ef300ef75 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -76,6 +76,7 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
_podKillCommand: true,
_podStatsCommand: true,
_podStopCommand: true,
+ _podTopCommand: true,
_restartCommand: true,
_rmCommand: true,
_runCommand: true,
diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go
index 79ffe2e6f..851f39aa0 100644
--- a/cmd/podman/pod_inspect.go
+++ b/cmd/podman/pod_inspect.go
@@ -14,7 +14,7 @@ var (
podInspectCommand cliconfig.PodInspectValues
podInspectDescription = `Display the configuration for a pod by name or id
- By default, this will render all results in a JSON array. If the container and image have the same name, this command returns the container JSON.`
+ By default, this will render all results in a JSON array.`
_podInspectCommand = &cobra.Command{
Use: "inspect [flags] POD",
@@ -34,7 +34,7 @@ func init() {
podInspectCommand.SetHelpTemplate(HelpTemplate())
podInspectCommand.SetUsageTemplate(UsageTemplate())
flags := podInspectCommand.Flags()
- flags.BoolVarP(&podInspectCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ flags.BoolVarP(&podInspectCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of")
markFlagHiddenForRemoteClient("latest", flags)
}
@@ -44,6 +44,11 @@ func podInspectCmd(c *cliconfig.PodInspectValues) error {
pod *adapter.Pod
)
args := c.InputArgs
+
+ if len(args) < 1 && !c.Latest {
+ return errors.Errorf("you must provide the name or id of a pod")
+ }
+
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go
index c9a6d8822..f65d66df6 100644
--- a/cmd/podman/pod_top.go
+++ b/cmd/podman/pod_top.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -53,6 +54,10 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
)
args := c.InputArgs
+ if os.Geteuid() != 0 {
+ rootless.SetSkipStorageSetup(true)
+ }
+
if c.ListDescriptors {
descriptors, err := libpod.GetContainerPidInformationDescriptors()
if err != nil {
@@ -77,6 +82,27 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
} else {
descriptors = args[1:]
}
+
+ if os.Geteuid() != 0 {
+ var pod *adapter.Pod
+ var err error
+ if c.Latest {
+ pod, err = runtime.GetLatestPod()
+ } else {
+ pod, err = runtime.LookupPod(c.InputArgs[0])
+ }
+ if err != nil {
+ return errors.Wrapf(err, "unable to lookup requested container")
+ }
+ became, ret, err := runtime.JoinOrCreateRootlessPod(pod)
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
+
w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
psOutput, err := runtime.PodTop(c, descriptors)
if err != nil {
diff --git a/cmd/podman/tree.go b/cmd/podman/tree.go
index ebda18cdb..c56e35aef 100644
--- a/cmd/podman/tree.go
+++ b/cmd/podman/tree.go
@@ -23,7 +23,7 @@ var (
treeDescription = "Prints layer hierarchy of an image in a tree format"
_treeCommand = &cobra.Command{
- Use: "tree",
+ Use: "tree [flags] IMAGE",
Short: treeDescription,
Long: treeDescription,
RunE: func(cmd *cobra.Command, args []string) error {
diff --git a/contrib/cirrus/notice_master_failure.sh b/contrib/cirrus/notice_master_failure.sh
index e18460a54..4b09331d3 100755
--- a/contrib/cirrus/notice_master_failure.sh
+++ b/contrib/cirrus/notice_master_failure.sh
@@ -12,8 +12,7 @@ NOR="$(echo -n -e '\x0f')"
if [[ "$CIRRUS_BRANCH" =~ "master" ]]
then
BURL="https://cirrus-ci.com/build/$CIRRUS_BUILD_ID"
- echo "Monitoring execution of $CIRRUS_TASK_NAME and notifying on failure"
- MSG="${RED}[Action Recommended]: ${NOR}Post-merge testing ${RED}$CIRRUS_BRANCH failed${NOR} in $CIRRUS_TASK_NAME on $(os_release_id)-$(os_release_ver): $BURL. Please investigate, and re-run if appropriate."
+ ircmsg "${RED}[Action Recommended]: ${NOR}Post-merge testing ${RED}$CIRRUS_BRANCH failed${NOR} in $CIRRUS_TASK_NAME on $(os_release_id)-$(os_release_ver): $BURL. Please investigate, and re-run if appropriate."
fi
# This script assumed to be executed on failure
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index d8d97904b..04c19b3af 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -88,4 +88,6 @@ then
fi
fi
+show_env_vars
+
record_timestamp "env. setup end"
diff --git a/docs/podman-image.1.md b/docs/podman-image.1.md
index 54960045f..333a75b69 100644
--- a/docs/podman-image.1.md
+++ b/docs/podman-image.1.md
@@ -27,8 +27,8 @@ The image command allows you to manage images
| save | [podman-save(1)](podman-save.1.md) | Save an image to docker-archive or oci. |
| sign | [podman-image-sign(1)](podman-image-sign.1.md) | Sign an image. |
| tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. |
+| tree | [podman-image-tree(1)](podman-image-tree.1.md) | Prints layer hierarchy of an image in a tree format. |
| trust | [podman-image-trust(1)](podman-image-trust.1.md)| Manage container image trust policy. |
-| tree | [podman-image-tree(1)](podman-image-tree.1.md) | Prints layer hierarchy of an image in a tree format |
## SEE ALSO
podman
diff --git a/docs/podman-ps.1.md b/docs/podman-ps.1.md
index b8b1c3d62..811fbbc2f 100644
--- a/docs/podman-ps.1.md
+++ b/docs/podman-ps.1.md
@@ -148,6 +148,15 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS
69ed779d8ef9f redis:alpine "redis-server" 25 hours ago Created 6379/tcp k8s_container1_podsandbox1_redhat.test.crio_redhat-test-crio_1
02f65160e14ca redis:alpine "redis-server" 19 hours ago Exited (-1) 19 hours ago 6379/tcp k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0
```
+
+```
+$ podman ps
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+4089df24d4f3 docker.io/library/centos:latest /bin/bash 2 minutes ago Up 2 minutes ago 0.0.0.0:80->8080/tcp, 0.0.0.0:2000-2006->2000-2006/tcp manyports
+92f58933c28c docker.io/library/centos:latest /bin/bash 3 minutes ago Up 3 minutes ago 192.168.99.100:1000-1006->1000-1006/tcp zen_sanderson
+
+```
+
## ps
Print a list of containers
diff --git a/libpod/container_log.go b/libpod/container_log.go
index 7964e4022..e998ad316 100644
--- a/libpod/container_log.go
+++ b/libpod/container_log.go
@@ -3,6 +3,7 @@ package libpod
import (
"fmt"
"io/ioutil"
+ "os"
"strings"
"sync"
"time"
@@ -54,6 +55,10 @@ func (r *Runtime) Log(containers []*Container, options *LogOptions, logChannel c
func (c *Container) ReadLog(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.
+ if os.IsNotExist(errors.Cause(err)) {
+ return nil
+ }
return errors.Wrapf(err, "unable to read log file %s for %s ", c.ID(), c.LogPath())
}
options.WaitGroup.Add(1)
@@ -111,7 +116,7 @@ func getLogFile(path string, options *LogOptions) (*tail.Tail, []*LogLine, error
Whence: whence,
}
- t, err := tail.TailFile(path, tail.Config{Poll: true, Follow: options.Follow, Location: &seek, Logger: tail.DiscardingLogger})
+ t, err := tail.TailFile(path, tail.Config{MustExist: true, Poll: true, Follow: options.Follow, Location: &seek, Logger: tail.DiscardingLogger})
return t, logTail, err
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 9836b7aab..b3b75d791 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -505,24 +505,33 @@ func newRuntimeFromConfig(userConfigPath string, options ...RuntimeOption) (runt
return nil, errors.Wrapf(err, "error configuring runtime")
}
}
- if err := makeRuntime(runtime); err != nil {
- return nil, err
- }
-
- if !foundConfig && rootlessConfigPath != "" {
- os.MkdirAll(filepath.Dir(rootlessConfigPath), 0755)
- file, err := os.OpenFile(rootlessConfigPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
- if err != nil && !os.IsExist(err) {
- return nil, errors.Wrapf(err, "cannot open file %s", rootlessConfigPath)
+ if rootlessConfigPath != "" {
+ // storage.conf
+ storageConfFile := util.StorageConfigFile()
+ if _, err := os.Stat(storageConfFile); os.IsNotExist(err) {
+ if err := util.WriteStorageConfigFile(&runtime.config.StorageConfig, storageConfFile); err != nil {
+ return nil, errors.Wrapf(err, "cannot write config file %s", storageConfFile)
+ }
}
- if err == nil {
- defer file.Close()
- enc := toml.NewEncoder(file)
- if err := enc.Encode(runtime.config); err != nil {
- os.Remove(rootlessConfigPath)
+
+ if !foundConfig {
+ os.MkdirAll(filepath.Dir(rootlessConfigPath), 0755)
+ file, err := os.OpenFile(rootlessConfigPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+ if err != nil && !os.IsExist(err) {
+ return nil, errors.Wrapf(err, "cannot open file %s", rootlessConfigPath)
+ }
+ if err == nil {
+ defer file.Close()
+ enc := toml.NewEncoder(file)
+ if err := enc.Encode(runtime.config); err != nil {
+ os.Remove(rootlessConfigPath)
+ }
}
}
}
+ if err := makeRuntime(runtime); err != nil {
+ return nil, err
+ }
return runtime, nil
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 73dddf2ac..a408ad34b 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -195,7 +195,7 @@ func GetRootlessRuntimeDir() (string, error) {
}
}
if runtimeDir == "" {
- tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("libpod-rundir-%s", uid))
+ tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
os.MkdirAll(tmpDir, 0700)
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
@@ -311,36 +311,37 @@ func GetDefaultStoreOptions() (storage.StoreOptions, error) {
storageOpts = storage.StoreOptions{}
storage.ReloadConfigurationFile(storageConf, &storageOpts)
}
-
- if rootless.IsRootless() {
- if os.IsNotExist(err) {
- os.MkdirAll(filepath.Dir(storageConf), 0755)
- file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
- if err != nil {
- return storageOpts, errors.Wrapf(err, "cannot open %s", storageConf)
- }
-
- tomlConfiguration := getTomlStorage(&storageOpts)
- defer file.Close()
- enc := toml.NewEncoder(file)
- if err := enc.Encode(tomlConfiguration); err != nil {
- os.Remove(storageConf)
- }
- } else if err == nil {
- // If the file did not specify a graphroot or runroot,
- // set sane defaults so we don't try and use root-owned
- // directories
- if storageOpts.RunRoot == "" {
- storageOpts.RunRoot = defaultRootlessRunRoot
- }
- if storageOpts.GraphRoot == "" {
- storageOpts.GraphRoot = defaultRootlessGraphRoot
- }
+ if rootless.IsRootless() && err == nil {
+ // If the file did not specify a graphroot or runroot,
+ // set sane defaults so we don't try and use root-owned
+ // directories
+ if storageOpts.RunRoot == "" {
+ storageOpts.RunRoot = defaultRootlessRunRoot
+ }
+ if storageOpts.GraphRoot == "" {
+ storageOpts.GraphRoot = defaultRootlessGraphRoot
}
}
return storageOpts, nil
}
+// WriteStorageConfigFile writes the configuration to a file
+func WriteStorageConfigFile(storageOpts *storage.StoreOptions, storageConf string) error {
+ os.MkdirAll(filepath.Dir(storageConf), 0755)
+ file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+ if err != nil {
+ return errors.Wrapf(err, "cannot open %s", storageConf)
+ }
+ tomlConfiguration := getTomlStorage(storageOpts)
+ defer file.Close()
+ enc := toml.NewEncoder(file)
+ if err := enc.Encode(tomlConfiguration); err != nil {
+ os.Remove(storageConf)
+ return err
+ }
+ return nil
+}
+
// StorageConfigFile returns the path to the storage config file used
func StorageConfigFile() string {
if rootless.IsRootless() {
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index d383a83b3..d051e3dba 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -132,4 +132,14 @@ var _ = Describe("Podman logs", func() {
Expect(len(output)).To(Equal(6))
Expect(strings.Contains(output[0], cid1[:12]) || strings.Contains(output[0], cid2[:12])).To(BeTrue())
})
+
+ It("podman logs on a created container should result in 0 exit code", func() {
+ session := podmanTest.Podman([]string{"create", "-dt", "--name", "log", ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+
+ results := podmanTest.Podman([]string{"logs", "log"})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(BeZero())
+ })
})
diff --git a/test/e2e/rootless_test.go b/test/e2e/rootless_test.go
index cd771e2ba..57146bca0 100644
--- a/test/e2e/rootless_test.go
+++ b/test/e2e/rootless_test.go
@@ -138,6 +138,21 @@ var _ = Describe("Podman rootless", func() {
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
Expect(cmd.LineInOutputContains("hello")).To(BeTrue())
+
+ args = []string{"pod", "top", podId}
+ cmd = rootlessTest.PodmanAsUser(args, 1000, 1000, "", env)
+ cmd.WaitWithDefaultTimeout()
+ Expect(cmd.ExitCode()).To(Not(Equal(0)))
+
+ args = []string{"run", "--pod", podId, "-d", "--rootfs", mountPath, "sleep", "100"}
+ cmd = rootlessTest.PodmanAsUser(args, 1000, 1000, "", env)
+ cmd.WaitWithDefaultTimeout()
+ Expect(cmd.ExitCode()).To(Equal(0))
+
+ args = []string{"pod", "top", podId}
+ cmd = rootlessTest.PodmanAsUser(args, 1000, 1000, "", env)
+ cmd.WaitWithDefaultTimeout()
+ Expect(cmd.ExitCode()).To(Equal(0))
}
runInRootlessContext(f)
})