summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/spec/spec.go34
-rw-r--r--pkg/varlinkapi/containers.go17
-rw-r--r--pkg/varlinkapi/images.go8
-rw-r--r--pkg/varlinkapi/transfers.go75
4 files changed, 123 insertions, 11 deletions
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 46105af4a..76b8963ff 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/storage/pkg/mount"
"github.com/docker/docker/daemon/caps"
"github.com/docker/go-units"
+ "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
@@ -45,6 +46,18 @@ func supercedeUserMounts(mounts []spec.Mount, configMount []spec.Mount) []spec.M
return configMount
}
+func getAvailableGids() (int64, error) {
+ idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
+ if err != nil {
+ return 0, err
+ }
+ count := int64(0)
+ for _, r := range idMap {
+ count += r.Count
+ }
+ return count, nil
+}
+
// CreateConfigToOCISpec parses information needed to create a container into an OCI runtime spec
func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
cgroupPerm := "ro"
@@ -91,14 +104,21 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.AddMount(sysMnt)
}
if isRootless {
- g.RemoveMount("/dev/pts")
- devPts := spec.Mount{
- Destination: "/dev/pts",
- Type: "devpts",
- Source: "devpts",
- Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
+ nGids, err := getAvailableGids()
+ if err != nil {
+ return nil, err
+ }
+ if nGids < 5 {
+ // If we have no GID mappings, the gid=5 default option would fail, so drop it.
+ g.RemoveMount("/dev/pts")
+ devPts := spec.Mount{
+ Destination: "/dev/pts",
+ Type: "devpts",
+ Source: "devpts",
+ Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
+ }
+ g.AddMount(devPts)
}
- g.AddMount(devPts)
}
if inUserNS && config.IpcMode.IsHost() {
g.RemoveMount("/dev/mqueue")
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index a01e3cc2b..737e2dd96 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
+ "io/ioutil"
"os"
"syscall"
"time"
@@ -194,15 +195,25 @@ func (i *LibpodAPI) ListContainerChanges(call iopodman.VarlinkCall, name string)
}
// ExportContainer ...
-func (i *LibpodAPI) ExportContainer(call iopodman.VarlinkCall, name, path string) error {
+func (i *LibpodAPI) ExportContainer(call iopodman.VarlinkCall, name, outPath string) error {
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyContainerNotFound(name)
}
- if err := ctr.Export(path); err != nil {
+ outputFile, err := ioutil.TempFile("", "varlink_recv")
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ defer outputFile.Close()
+ if outPath == "" {
+ outPath = outputFile.Name()
+ }
+ if err := ctr.Export(outPath); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- return call.ReplyExportContainer(path)
+ return call.ReplyExportContainer(outPath)
+
}
// GetContainerStats ...
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 0ab645802..5e0889645 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -500,7 +500,7 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch
}
// ImportImage imports an image from a tarball to the image store
-func (i *LibpodAPI) ImportImage(call iopodman.VarlinkCall, source, reference, message string, changes []string) error {
+func (i *LibpodAPI) ImportImage(call iopodman.VarlinkCall, source, reference, message string, changes []string, delete bool) error {
configChanges, err := util.GetImageConfig(changes)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
@@ -516,6 +516,12 @@ func (i *LibpodAPI) ImportImage(call iopodman.VarlinkCall, source, reference, me
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
+ if delete {
+ if err := os.Remove(source); err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ }
+
return call.ReplyImportImage(newImage.ID())
}
diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go
new file mode 100644
index 000000000..0cb7e5e2e
--- /dev/null
+++ b/pkg/varlinkapi/transfers.go
@@ -0,0 +1,75 @@
+package varlinkapi
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+
+ "github.com/containers/libpod/cmd/podman/varlink"
+)
+
+// SendFile allows a client to send a file to the varlink server
+func (i *LibpodAPI) SendFile(call iopodman.VarlinkCall, ftype string, length int64) error {
+ if !call.WantsUpgrade() {
+ return call.ReplyErrorOccurred("client must use upgraded connection to send files")
+ }
+
+ outputFile, err := ioutil.TempFile("", "varlink_send")
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ defer outputFile.Close()
+
+ if err = call.ReplySendFile(outputFile.Name()); err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ writer := bufio.NewWriter(outputFile)
+ defer writer.Flush()
+
+ reader := call.Call.Reader
+ if _, err := io.CopyN(writer, reader, length); err != nil {
+ return err
+ }
+
+ // Send an ACK to the client
+ call.Call.Writer.WriteString(fmt.Sprintf("%s:", outputFile.Name()))
+ call.Call.Writer.Flush()
+ return nil
+
+}
+
+// ReceiveFile allows the varlink server to send a file to a client
+func (i *LibpodAPI) ReceiveFile(call iopodman.VarlinkCall, filepath string, delete bool) error {
+ if !call.WantsUpgrade() {
+ return call.ReplyErrorOccurred("client must use upgraded connection to send files")
+ }
+ fs, err := os.Open(filepath)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ fileInfo, err := fs.Stat()
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ // Send the file length down to client
+ // Varlink connection upraded
+ if err = call.ReplyReceiveFile(fileInfo.Size()); err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ reader := bufio.NewReader(fs)
+ _, err = reader.WriteTo(call.Writer)
+ if err != nil {
+ return err
+ }
+ if delete {
+ if err := os.Remove(filepath); err != nil {
+ return err
+ }
+ }
+ return call.Writer.Flush()
+}