summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/spec/createconfig.go59
-rw-r--r--pkg/util/utils.go10
-rw-r--r--pkg/varlinkapi/containers.go6
-rw-r--r--pkg/varlinkapi/containers_create.go7
-rw-r--r--pkg/varlinkapi/images.go181
-rw-r--r--pkg/varlinkapi/transfers.go2
-rw-r--r--pkg/varlinkapi/util.go27
7 files changed, 171 insertions, 121 deletions
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index f6c77d61c..8da44a2f0 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
+ "github.com/containers/storage/pkg/stringid"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-connections/nat"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -134,8 +135,8 @@ type CreateConfig struct {
SeccompProfilePath string //SecurityOpts
SecurityOpts []string
Rootfs string
- LocalVolumes []string //Keeps track of the built-in volumes of container used in the --volumes-from flag
- Syslog bool // Whether to enable syslog on exit commands
+ LocalVolumes []spec.Mount //Keeps track of the built-in volumes of container used in the --volumes-from flag
+ Syslog bool // Whether to enable syslog on exit commands
}
func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
@@ -216,7 +217,7 @@ func (c *CreateConfig) initFSMounts() []spec.Mount {
//GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, error) {
- var m []spec.Mount
+ m := c.LocalVolumes
for _, i := range c.Volumes {
var options []string
spliti := strings.Split(i, ":")
@@ -234,22 +235,31 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
logrus.Debugf("User mount %s:%s options %v", spliti[0], spliti[1], options)
}
- // volumes from image config
- if c.ImageVolumeType != "tmpfs" {
+ if c.ImageVolumeType == "ignore" {
return m, nil
}
+
for vol := range c.BuiltinImgVolumes {
if libpod.MountExists(specMounts, vol) {
continue
}
+
mount := spec.Mount{
Destination: vol,
- Type: string(TypeTmpfs),
- Source: string(TypeTmpfs),
- Options: []string{"rprivate", "rw", "noexec", "nosuid", "nodev", "tmpcopyup"},
+ Type: c.ImageVolumeType,
+ Options: []string{"rprivate", "rw", "nodev"},
+ }
+ if c.ImageVolumeType == "tmpfs" {
+ mount.Source = "tmpfs"
+ mount.Options = append(mount.Options, "tmpcopyup")
+ } else {
+ // This will cause a new local Volume to be created on your system
+ mount.Source = stringid.GenerateNonCryptoID()
+ mount.Options = append(mount.Options, "bind")
}
m = append(m, mount)
}
+
return m, nil
}
@@ -257,6 +267,11 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
// and adds it to c.Volumes of the current container.
func (c *CreateConfig) GetVolumesFrom() error {
var options string
+
+ if rootless.SkipStorageSetup() {
+ return nil
+ }
+
for _, vol := range c.VolumesFrom {
splitVol := strings.SplitN(vol, ":", 2)
if len(splitVol) == 2 {
@@ -266,6 +281,10 @@ func (c *CreateConfig) GetVolumesFrom() error {
if err != nil {
return errors.Wrapf(err, "error looking up container %q", splitVol[0])
}
+ inspect, err := ctr.Inspect(false)
+ if err != nil {
+ return errors.Wrapf(err, "error inspecting %q", splitVol[0])
+ }
var createArtifact CreateConfig
artifact, err := ctr.GetArtifact("create-config")
if err != nil {
@@ -274,9 +293,13 @@ func (c *CreateConfig) GetVolumesFrom() error {
if err := json.Unmarshal(artifact, &createArtifact); err != nil {
return err
}
-
for key := range createArtifact.BuiltinImgVolumes {
- c.LocalVolumes = append(c.LocalVolumes, key)
+ for _, m := range inspect.Mounts {
+ if m.Destination == key {
+ c.LocalVolumes = append(c.LocalVolumes, m)
+ break
+ }
+ }
}
for _, i := range createArtifact.Volumes {
@@ -340,7 +363,13 @@ func (c *CreateConfig) createExitCommand() []string {
if c.Syslog {
command = append(command, "--syslog")
}
- return append(command, []string{"container", "cleanup"}...)
+ command = append(command, []string{"container", "cleanup"}...)
+
+ if c.Rm {
+ command = append(command, "--rm")
+ }
+
+ return command
}
// GetContainerCreateOptions takes a CreateConfig and returns a slice of CtrCreateOptions
@@ -518,11 +547,9 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime, pod *l
if c.CgroupParent != "" {
options = append(options, libpod.WithCgroupParent(c.CgroupParent))
}
- // For a rootless container always cleanup the storage/network as they
- // run in a different namespace thus not reusable when we restart.
- if c.Detach || rootless.IsRootless() {
- options = append(options, libpod.WithExitCommand(c.createExitCommand()))
- }
+
+ // Always use a cleanup process to clean up Podman after termination
+ options = append(options, libpod.WithExitCommand(c.createExitCommand()))
return options, nil
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 52f431881..db8a3d5bb 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -259,8 +259,8 @@ func GetRootlessStorageOpts() (storage.StoreOptions, error) {
return opts, nil
}
-// GetRootlessVolumeInfo returns where all the name volumes will be created in rootless mode
-func GetRootlessVolumeInfo() (string, error) {
+// GetRootlessVolumePath returns where all the name volumes will be created in rootless mode
+func GetRootlessVolumePath() (string, error) {
dataDir, _, err := GetRootlessDirInfo()
if err != nil {
return "", err
@@ -307,15 +307,13 @@ func GetDefaultStoreOptions() (storage.StoreOptions, string, error) {
err error
)
storageOpts := storage.DefaultStoreOptions
- volumePath := "/var/lib/containers/storage"
-
+ volumePath := filepath.Join(storageOpts.GraphRoot, "volumes")
if rootless.IsRootless() {
storageOpts, err = GetRootlessStorageOpts()
if err != nil {
return storageOpts, volumePath, err
}
-
- volumePath, err = GetRootlessVolumeInfo()
+ volumePath, err = GetRootlessVolumePath()
if err != nil {
return storageOpts, volumePath, err
}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 2b2832838..8a52efa61 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -358,13 +358,13 @@ func (i *LibpodAPI) WaitContainer(call iopodman.VarlinkCall, name string) error
}
// RemoveContainer ...
-func (i *LibpodAPI) RemoveContainer(call iopodman.VarlinkCall, name string, force bool) error {
+func (i *LibpodAPI) RemoveContainer(call iopodman.VarlinkCall, name string, force bool, removeVolumes bool) error {
ctx := getContext()
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyContainerNotFound(name)
}
- if err := i.Runtime.RemoveContainer(ctx, ctr, force); err != nil {
+ if err := i.Runtime.RemoveContainer(ctx, ctr, force, removeVolumes); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyRemoveContainer(ctr.ID())
@@ -385,7 +385,7 @@ func (i *LibpodAPI) DeleteStoppedContainers(call iopodman.VarlinkCall) error {
return call.ReplyErrorOccurred(err.Error())
}
if state != libpod.ContainerStateRunning {
- if err := i.Runtime.RemoveContainer(ctx, ctr, false); err != nil {
+ if err := i.Runtime.RemoveContainer(ctx, ctr, false, false); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
deletedContainers = append(deletedContainers, ctr.ID())
diff --git a/pkg/varlinkapi/containers_create.go b/pkg/varlinkapi/containers_create.go
index f1835a189..6b53b22c6 100644
--- a/pkg/varlinkapi/containers_create.go
+++ b/pkg/varlinkapi/containers_create.go
@@ -131,9 +131,14 @@ func varlinkCreateToCreateConfig(ctx context.Context, create iopodman.Create, ru
}
imageID := data.ID
+ var ImageVolumes map[string]struct{}
+ if data != nil && create.Image_volume_type != "ignore" {
+ ImageVolumes = data.Config.Volumes
+ }
+
config := &cc.CreateConfig{
Runtime: runtime,
- BuiltinImgVolumes: data.Config.Volumes,
+ BuiltinImgVolumes: ImageVolumes,
ConmonPidFile: create.Conmon_pidfile,
ImageVolumeType: create.Image_volume_type,
CapAdd: create.Cap_add,
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index ca920dfeb..534419f6f 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
+ "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -24,7 +25,7 @@ import (
sysreg "github.com/containers/libpod/pkg/registries"
"github.com/containers/libpod/pkg/util"
"github.com/containers/libpod/utils"
- "github.com/docker/go-units"
+ "github.com/containers/storage/pkg/archive"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -110,83 +111,46 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error {
// BuildImage ...
func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildInfo) error {
var (
- memoryLimit int64
- memorySwap int64
- namespace []buildah.NamespaceOption
- err error
+ namespace []buildah.NamespaceOption
+ err error
)
systemContext := types.SystemContext{}
- dockerfiles := config.Dockerfile
- contextDir := ""
-
- for i := range dockerfiles {
- if strings.HasPrefix(dockerfiles[i], "http://") ||
- strings.HasPrefix(dockerfiles[i], "https://") ||
- strings.HasPrefix(dockerfiles[i], "git://") ||
- strings.HasPrefix(dockerfiles[i], "github.com/") {
- continue
- }
- absFile, err := filepath.Abs(dockerfiles[i])
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
- }
- contextDir = filepath.Dir(absFile)
- dockerfiles[i], err = filepath.Rel(contextDir, absFile)
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
- }
- break
- }
-
- pullPolicy := imagebuildah.PullNever
- if config.Pull {
- pullPolicy = imagebuildah.PullIfMissing
- }
-
- if config.Pull_always {
- pullPolicy = imagebuildah.PullAlways
- }
- manifestType := "oci" //nolint
- if config.Image_format != "" {
- manifestType = config.Image_format
- }
+ contextDir := config.ContextDir
- if strings.HasPrefix(manifestType, "oci") {
- manifestType = buildah.OCIv1ImageManifest
- } else if strings.HasPrefix(manifestType, "docker") {
- manifestType = buildah.Dockerv2ImageManifest
- } else {
- return call.ReplyErrorOccurred(fmt.Sprintf("unrecognized image type %q", manifestType))
+ newContextDir, err := ioutil.TempDir("", "buildTarball")
+ if err != nil {
+ call.ReplyErrorOccurred("unable to create tempdir")
}
+ logrus.Debugf("created new context dir at %s", newContextDir)
- if config.Memory != "" {
- memoryLimit, err = units.RAMInBytes(config.Memory)
- if err != nil {
- return call.ReplyErrorOccurred(err.Error())
- }
+ reader, err := os.Open(contextDir)
+ if err != nil {
+ logrus.Errorf("failed to open the context dir tar file %s", contextDir)
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to open context dir tar file %s", contextDir))
}
-
- if config.Memory_swap != "" {
- memorySwap, err = units.RAMInBytes(config.Memory_swap)
- if err != nil {
- return call.ReplyErrorOccurred(err.Error())
- }
+ defer reader.Close()
+ if err := archive.Untar(reader, newContextDir, &archive.TarOptions{}); err != nil {
+ logrus.Errorf("fail to untar the context dir tarball (%s) to the context dir (%s)", contextDir, newContextDir)
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to untar context dir %s", contextDir))
}
+ logrus.Debugf("untar of %s successful", contextDir)
+ // All output (stdout, stderr) is captured in output as well
output := bytes.NewBuffer([]byte{})
+
commonOpts := &buildah.CommonBuildOptions{
- AddHost: config.Add_hosts,
- CgroupParent: config.Cgroup_parent,
- CPUPeriod: uint64(config.Cpu_period),
- CPUQuota: config.Cpu_quota,
- CPUSetCPUs: config.Cpuset_cpus,
- CPUSetMems: config.Cpuset_mems,
- Memory: memoryLimit,
- MemorySwap: memorySwap,
- ShmSize: config.Shm_size,
- Ulimit: config.Ulimit,
- Volumes: config.Volume,
+ AddHost: config.BuildOptions.AddHosts,
+ CgroupParent: config.BuildOptions.CgroupParent,
+ CPUPeriod: uint64(config.BuildOptions.CpuPeriod),
+ CPUQuota: config.BuildOptions.CpuQuota,
+ CPUSetCPUs: config.BuildOptions.CpusetCpus,
+ CPUSetMems: config.BuildOptions.CpusetMems,
+ Memory: config.BuildOptions.Memory,
+ MemorySwap: config.BuildOptions.MemorySwap,
+ ShmSize: config.BuildOptions.ShmSize,
+ Ulimit: config.BuildOptions.Ulimit,
+ Volumes: config.BuildOptions.Volume,
}
hostNetwork := buildah.NamespaceOption{
@@ -197,37 +161,68 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
namespace = append(namespace, hostNetwork)
options := imagebuildah.BuildOptions{
- ContextDirectory: contextDir,
- PullPolicy: pullPolicy,
- Compression: imagebuildah.Gzip,
- Quiet: false,
- //SignaturePolicyPath:
- Args: config.Build_args,
- //Output:
- AdditionalTags: config.Tags,
- //Runtime: runtime.
- //RuntimeArgs: ,
- OutputFormat: manifestType,
- SystemContext: &systemContext,
- CommonBuildOpts: commonOpts,
- Squash: config.Squash,
- Labels: config.Label,
- Annotations: config.Annotations,
- ReportWriter: output,
- NamespaceOptions: namespace,
+ CommonBuildOpts: commonOpts,
+ AdditionalTags: config.AdditionalTags,
+ Annotations: config.Annotations,
+ Args: config.BuildArgs,
+ CNIConfigDir: config.CniConfigDir,
+ CNIPluginPath: config.CniPluginDir,
+ Compression: stringCompressionToArchiveType(config.Compression),
+ ContextDirectory: newContextDir,
+ DefaultMountsFilePath: config.DefaultsMountFilePath,
+ Err: output,
+ ForceRmIntermediateCtrs: config.ForceRmIntermediateCtrs,
+ IIDFile: config.Iidfile,
+ Labels: config.Label,
+ Layers: config.Layers,
+ NoCache: config.Nocache,
+ Out: output,
+ Output: config.Output,
+ NamespaceOptions: namespace,
+ OutputFormat: config.OutputFormat,
+ PullPolicy: stringPullPolicyToType(config.PullPolicy),
+ Quiet: config.Quiet,
+ RemoveIntermediateCtrs: config.RemoteIntermediateCtrs,
+ ReportWriter: output,
+ RuntimeArgs: config.RuntimeArgs,
+ SignaturePolicyPath: config.SignaturePolicyPath,
+ Squash: config.Squash,
+ SystemContext: &systemContext,
}
if call.WantsMore() {
call.Continues = true
}
- c := build(i.Runtime, options, config.Dockerfile)
+ var newPathDockerFiles []string
+
+ for _, d := range config.Dockerfiles {
+ if strings.HasPrefix(d, "http://") ||
+ strings.HasPrefix(d, "https://") ||
+ strings.HasPrefix(d, "git://") ||
+ strings.HasPrefix(d, "github.com/") {
+ newPathDockerFiles = append(newPathDockerFiles, d)
+ continue
+ }
+ base := filepath.Base(d)
+ newPathDockerFiles = append(newPathDockerFiles, filepath.Join(newContextDir, base))
+ }
+
+ c := build(i.Runtime, options, newPathDockerFiles)
var log []string
done := false
for {
- line, err := output.ReadString('\n')
+ outputLine, err := output.ReadString('\n')
if err == nil {
- log = append(log, line)
+ log = append(log, outputLine)
+ if call.WantsMore() {
+ // we want to reply with what we have
+ br := iopodman.MoreResponse{
+ Logs: log,
+ }
+ call.ReplyBuildImage(br)
+ log = []string{}
+ }
continue
} else if err == io.EOF {
select {
@@ -237,15 +232,10 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
}
done = true
default:
- if !call.WantsMore() {
+ if call.WantsMore() {
time.Sleep(1 * time.Second)
break
}
- br := iopodman.MoreResponse{
- Logs: log,
- }
- call.ReplyBuildImage(br)
- log = []string{}
}
} else {
return call.ReplyErrorOccurred(err.Error())
@@ -255,7 +245,8 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
}
}
call.Continues = false
- newImage, err := i.Runtime.ImageRuntime().NewFromLocal(config.Tags[0])
+
+ newImage, err := i.Runtime.ImageRuntime().NewFromLocal(config.Output)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go
index 0cb7e5e2e..9a97bc810 100644
--- a/pkg/varlinkapi/transfers.go
+++ b/pkg/varlinkapi/transfers.go
@@ -8,6 +8,7 @@ import (
"os"
"github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/sirupsen/logrus"
)
// SendFile allows a client to send a file to the varlink server
@@ -34,6 +35,7 @@ func (i *LibpodAPI) SendFile(call iopodman.VarlinkCall, ftype string, length int
return err
}
+ logrus.Debugf("successfully received %s", outputFile.Name())
// Send an ACK to the client
call.Call.Writer.WriteString(fmt.Sprintf("%s:", outputFile.Name()))
call.Call.Writer.Flush()
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index 7f6f95d3b..7e487c03a 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -3,11 +3,14 @@ package varlinkapi
import (
"context"
"strconv"
+ "strings"
"time"
+ "github.com/containers/buildah"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ "github.com/containers/storage/pkg/archive"
)
// getContext returns a non-nil, empty context
@@ -133,3 +136,27 @@ func handlePodCall(call iopodman.VarlinkCall, pod *libpod.Pod, ctrErrs map[strin
return nil
}
+
+func stringCompressionToArchiveType(s string) archive.Compression {
+ switch strings.ToUpper(s) {
+ case "BZIP2":
+ return archive.Bzip2
+ case "GZIP":
+ return archive.Gzip
+ case "XZ":
+ return archive.Xz
+ }
+ return archive.Uncompressed
+}
+
+func stringPullPolicyToType(s string) buildah.PullPolicy {
+ switch strings.ToUpper(s) {
+ case "PULLIFMISSING":
+ return buildah.PullIfMissing
+ case "PULLALWAYS":
+ return buildah.PullAlways
+ case "PULLNEVER":
+ return buildah.PullNever
+ }
+ return buildah.PullIfMissing
+}