summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md8
-rw-r--r--cmd/podman/run.go1
-rw-r--r--cmd/podman/varlink/io.podman.varlink4
-rw-r--r--libpod/oci_conmon_linux.go6
-rw-r--r--libpod/runtime.go31
-rw-r--r--libpod/volume_inspect.go3
-rw-r--r--pkg/adapter/containers_remote.go9
-rw-r--r--pkg/adapter/runtime_remote.go37
-rw-r--r--pkg/util/utils.go2
-rw-r--r--pkg/varlinkapi/attach.go1
-rw-r--r--pkg/varlinkapi/virtwriter/virtwriter.go24
-rw-r--r--pkg/varlinkapi/volumes.go19
-rw-r--r--test/e2e/volume_inspect_test.go13
13 files changed, 128 insertions, 30 deletions
diff --git a/API.md b/API.md
index a2a093bec..1cbdacb12 100755
--- a/API.md
+++ b/API.md
@@ -107,6 +107,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func InspectPod(name: string) string](#InspectPod)
+[func InspectVolume(name: string) string](#InspectVolume)
+
[func KillContainer(name: string, signal: int) string](#KillContainer)
[func KillPod(name: string, signal: int) string](#KillPod)
@@ -804,6 +806,12 @@ method InspectPod(name: [string](https://godoc.org/builtin#string)) [string](htt
InspectPod takes the name or ID of an image and returns a string representation of data associated with the
pod. You must serialize the string into JSON to use it further. A [PodNotFound](#PodNotFound) error will
be returned if the pod cannot be found.
+### <a name="InspectVolume"></a>func InspectVolume
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method InspectVolume(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
+InspectVolume inspects a single volume. Returns inspect JSON in the form of a
+string.
### <a name="KillContainer"></a>func KillContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 4836c99dc..7aa4cb3c4 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -45,7 +45,6 @@ func runCmd(c *cliconfig.RunValues) error {
span, _ := opentracing.StartSpanFromContext(Ctx, "runCmd")
defer span.Finish()
}
-
if err := createInit(&c.PodmanCommand); err != nil {
return err
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 13e8394fb..dca366bc5 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -1268,6 +1268,10 @@ method VolumeRemove(options: VolumeRemoveOpts) -> (successes: []string, failures
# GetVolumes gets slice of the volumes on a remote host
method GetVolumes(args: []string, all: bool) -> (volumes: []Volume)
+# InspectVolume inspects a single volume. Returns inspect JSON in the form of a
+# string.
+method InspectVolume(name: string) -> (volume: string)
+
# VolumesPrune removes unused volumes on the host
method VolumesPrune() -> (prunedNames: []string, prunedErrors: []string)
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 658a2fe4e..448e05bdf 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -602,7 +602,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
if err != nil {
return -1, nil, errors.Wrapf(err, "cannot start container %s", c.ID())
}
- if err := r.moveConmonToCgroupAndSignal(c, execCmd, parentStartPipe, sessionID); err != nil {
+ if err := r.moveConmonToCgroupAndSignal(c, execCmd, parentStartPipe); err != nil {
return -1, nil, err
}
@@ -986,7 +986,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
if err != nil {
return err
}
- if err := r.moveConmonToCgroupAndSignal(ctr, cmd, parentStartPipe, ctr.ID()); err != nil {
+ if err := r.moveConmonToCgroupAndSignal(ctr, cmd, parentStartPipe); err != nil {
return err
}
/* Wait for initial setup and fork, and reap child */
@@ -1213,7 +1213,7 @@ func startCommandGivenSelinux(cmd *exec.Cmd) error {
// moveConmonToCgroupAndSignal gets a container's cgroupParent and moves the conmon process to that cgroup
// it then signals for conmon to start by sending nonse data down the start fd
-func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec.Cmd, startFd *os.File, uuid string) error {
+func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec.Cmd, startFd *os.File) error {
mustCreateCgroup := true
// If cgroup creation is disabled - just signal.
if ctr.config.NoCgroups {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 107e8e3d0..8f145a809 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -509,6 +509,17 @@ func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options ..
return nil, err
}
+ // storage.conf
+ storageConfFile, err := storage.DefaultConfigFile(rootless.IsRootless())
+ if err != nil {
+ return nil, err
+ }
+
+ createStorageConfFile := false
+ if _, err := os.Stat(storageConfFile); os.IsNotExist(err) {
+ createStorageConfFile = true
+ }
+
defRunConf, err := defaultRuntimeConfig()
if err != nil {
return nil, err
@@ -683,27 +694,21 @@ func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options ..
}
if rootless.IsRootless() && configPath == "" {
- configPath, err := getRootlessConfigPath()
- if err != nil {
- return nil, err
- }
-
- // storage.conf
- storageConfFile, err := storage.DefaultConfigFile(rootless.IsRootless())
- if err != nil {
- return nil, err
- }
- if _, err := os.Stat(storageConfFile); os.IsNotExist(err) {
+ if createStorageConfFile {
if err := util.WriteStorageConfigFile(&runtime.config.StorageConfig, storageConfFile); err != nil {
return nil, errors.Wrapf(err, "cannot write config file %s", storageConfFile)
}
}
+ configPath, err := getRootlessConfigPath()
+ if err != nil {
+ return nil, err
+ }
if configPath != "" {
- if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil {
+ if err := os.MkdirAll(filepath.Dir(configPath), 0711); err != nil {
return nil, err
}
- file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+ file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil && !os.IsExist(err) {
return nil, errors.Wrapf(err, "cannot open file %s", configPath)
}
diff --git a/libpod/volume_inspect.go b/libpod/volume_inspect.go
index 87ed9d340..c333b8961 100644
--- a/libpod/volume_inspect.go
+++ b/libpod/volume_inspect.go
@@ -62,6 +62,9 @@ func (v *Volume) Inspect() (*InspectVolumeData, error) {
}
data.Scope = v.Scope()
data.Options = make(map[string]string)
+ for k, v := range v.config.Options {
+ data.Options[k] = v
+ }
data.UID = v.config.UID
data.GID = v.config.GID
data.ContainerSpecific = v.config.IsCtrSpecific
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index f7cb28b0c..f4e83a975 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -1092,6 +1092,7 @@ func configureVarlinkAttachStdio(reader *bufio.Reader, writer *bufio.Writer, std
// These are the special writers that encode input from the client.
varlinkStdinWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.ToStdin)
varlinkResizeWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.TerminalResize)
+ varlinkHangupWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.HangUpFromClient)
go func() {
// Read from the wire and direct to stdout or stderr
@@ -1117,7 +1118,6 @@ func configureVarlinkAttachStdio(reader *bufio.Reader, writer *bufio.Writer, std
}
}
}()
-
if stdin != nil {
// Takes stdinput and sends it over the wire after being encoded
go func() {
@@ -1126,7 +1126,12 @@ func configureVarlinkAttachStdio(reader *bufio.Reader, writer *bufio.Writer, std
sendGenericError(ecChan)
errChan <- err
}
-
+ _, err := varlinkHangupWriter.Write([]byte("EOF"))
+ if err != nil {
+ logrus.Errorf("unable to notify server to hangup: %q", err)
+ }
+ err = varlinkStdinWriter.Close()
+ errChan <- err
}()
}
return errChan
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 3b808a2ee..870e86896 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -659,12 +659,39 @@ func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestM
}
// InspectVolumes returns a slice of volumes based on an arg list or --all
-func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) {
- reply, err := iopodman.GetVolumes().Call(r.Conn, c.InputArgs, c.All)
- if err != nil {
- return nil, err
+func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*libpod.InspectVolumeData, error) {
+ var (
+ inspectData []*libpod.InspectVolumeData
+ volumes []string
+ )
+
+ if c.All {
+ allVolumes, err := r.Volumes(ctx)
+ if err != nil {
+ return nil, err
+ }
+ for _, vol := range allVolumes {
+ volumes = append(volumes, vol.Name())
+ }
+ } else {
+ for _, arg := range c.InputArgs {
+ volumes = append(volumes, arg)
+ }
}
- return varlinkVolumeToVolume(r, reply), nil
+
+ for _, vol := range volumes {
+ jsonString, err := iopodman.InspectVolume().Call(r.Conn, vol)
+ if err != nil {
+ return nil, err
+ }
+ inspectJSON := new(libpod.InspectVolumeData)
+ if err := json.Unmarshal([]byte(jsonString), inspectJSON); err != nil {
+ return nil, errors.Wrapf(err, "error unmarshalling inspect JSON for volume %s", vol)
+ }
+ inspectData = append(inspectData, inspectJSON)
+ }
+
+ return inspectData, nil
}
// Volumes returns a slice of adapter.volumes based on information about libpod
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 0190b106d..d9a84e4e5 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -318,7 +318,7 @@ func WriteStorageConfigFile(storageOpts *storage.StoreOptions, storageConf strin
if err := os.MkdirAll(filepath.Dir(storageConf), 0755); err != nil {
return err
}
- storageFile, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+ storageFile, err := os.OpenFile(storageConf, os.O_RDWR|os.O_TRUNC, 0600)
if err != nil {
return errors.Wrapf(err, "cannot open %s", storageConf)
}
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index f8557ae0c..37adbbf55 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -70,7 +70,6 @@ func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys st
}
reader, writer, _, pw, streams := setupStreams(call)
-
go func() {
if err := virtwriter.Reader(reader, nil, nil, pw, resize, nil); err != nil {
errChan <- err
diff --git a/pkg/varlinkapi/virtwriter/virtwriter.go b/pkg/varlinkapi/virtwriter/virtwriter.go
index 27ecd1f52..dd171943f 100644
--- a/pkg/varlinkapi/virtwriter/virtwriter.go
+++ b/pkg/varlinkapi/virtwriter/virtwriter.go
@@ -5,6 +5,7 @@ import (
"encoding/binary"
"encoding/json"
"io"
+ "time"
"github.com/pkg/errors"
"k8s.io/client-go/tools/remotecommand"
@@ -26,8 +27,14 @@ const (
TerminalResize SocketDest = iota
// Quit and detach
Quit SocketDest = iota
+ // Quit from the client
+ HangUpFromClient SocketDest = iota
)
+// ClientHangup signifies that the client wants to drop its
+// connection from the server
+var ClientHangup = errors.New("client hangup")
+
// IntToSocketDest returns a socketdest based on integer input
func IntToSocketDest(i int) SocketDest {
switch i {
@@ -41,6 +48,8 @@ func IntToSocketDest(i int) SocketDest {
return TerminalResize
case Quit.Int():
return Quit
+ case HangUpFromClient.Int():
+ return HangUpFromClient
default:
return ToStderr
}
@@ -65,7 +74,7 @@ func NewVirtWriteCloser(w *bufio.Writer, dest SocketDest) VirtWriteCloser {
// Close is a required method for a writecloser
func (v VirtWriteCloser) Close() error {
- return nil
+ return v.writer.Flush()
}
// Write prepends a header to the input message. The header is
@@ -96,7 +105,6 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote
if r == nil {
return errors.Errorf("Reader must not be nil")
}
-
for {
n, err := io.ReadFull(r, headerBytes)
if err != nil {
@@ -107,7 +115,6 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote
}
messageSize = int64(binary.BigEndian.Uint32(headerBytes[4:8]))
-
switch IntToSocketDest(int(headerBytes[0])) {
case ToStdout:
if output != nil {
@@ -161,7 +168,16 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote
execEcChan <- int(ecInt)
}
return nil
-
+ case HangUpFromClient:
+ // This sleep allows the pipes to flush themselves before tearing everything down.
+ // It makes me sick to do it but after a full day I cannot put my finger on the race
+ // that occurs when closing things up. It would require a significant rewrite of code
+ // to make the pipes close down properly. Given that we are currently discussing a
+ // rewrite of all things remote, this hardly seems worth resolving.
+ //
+ // reproducer: echo hello | (podman-remote run -i alpine cat)
+ time.Sleep(1 * time.Second)
+ return ClientHangup
default:
// Something really went wrong
return errors.New("unknown multiplex destination")
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index b41eb5086..0ba76902e 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -3,6 +3,8 @@
package varlinkapi
import (
+ "encoding/json"
+
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
@@ -80,6 +82,23 @@ func (i *LibpodAPI) GetVolumes(call iopodman.VarlinkCall, args []string, all boo
return call.ReplyGetVolumes(volumes)
}
+// InspectVolume inspects a single volume, returning its JSON as a string.
+func (i *LibpodAPI) InspectVolume(call iopodman.VarlinkCall, name string) error {
+ vol, err := i.Runtime.LookupVolume(name)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ inspectOut, err := vol.Inspect()
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ inspectJSON, err := json.Marshal(inspectOut)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyInspectVolume(string(inspectJSON))
+}
+
// VolumesPrune removes unused images via a varlink call
func (i *LibpodAPI) VolumesPrune(call iopodman.VarlinkCall) error {
var errs []string
diff --git a/test/e2e/volume_inspect_test.go b/test/e2e/volume_inspect_test.go
index 0683c6bbf..5015e0535 100644
--- a/test/e2e/volume_inspect_test.go
+++ b/test/e2e/volume_inspect_test.go
@@ -2,6 +2,7 @@ package integration
import (
"os"
+ "strings"
. "github.com/containers/libpod/test/utils"
. "github.com/onsi/ginkgo"
@@ -74,4 +75,16 @@ var _ = Describe("Podman volume inspect", func() {
Expect(session.OutputToStringArray()[0]).To(Equal(volName1))
Expect(session.OutputToStringArray()[1]).To(Equal(volName2))
})
+
+ It("inspect volume finds options", func() {
+ volName := "testvol"
+ session := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", volName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"volume", "inspect", volName})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(strings.Contains(inspect.OutputToString(), "tmpfs")).To(BeTrue())
+ })
})