summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/create_opts.go28
-rw-r--r--cmd/podman/common/volumes.go36
-rw-r--r--cmd/podman/containers/cp.go54
-rw-r--r--cmd/podman/images/build.go86
-rw-r--r--cmd/podman/root.go19
5 files changed, 130 insertions, 93 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index f945c9c54..a296ef4f1 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -3,6 +3,7 @@ package common
import (
"fmt"
"net"
+ "os"
"path/filepath"
"strconv"
"strings"
@@ -13,6 +14,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/pkg/errors"
)
type ContainerCLIOpts struct {
@@ -395,8 +397,16 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
cliOpts.Ulimit = ulimits
}
}
+ if cc.HostConfig.Resources.NanoCPUs > 0 {
+ if cliOpts.CPUPeriod != 0 || cliOpts.CPUQuota != 0 {
+ return nil, nil, errors.Errorf("NanoCpus conflicts with CpuPeriod and CpuQuota")
+ }
+ cliOpts.CPUPeriod = 100000
+ cliOpts.CPUQuota = cc.HostConfig.Resources.NanoCPUs / 10000
+ }
// volumes
+ volSources := make(map[string]bool)
volDestinations := make(map[string]bool)
for _, vol := range cc.HostConfig.Binds {
cliOpts.Volume = append(cliOpts.Volume, vol)
@@ -407,6 +417,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
case 1:
volDestinations[vol] = true
default:
+ volSources[splitVol[0]] = true
volDestinations[splitVol[1]] = true
}
}
@@ -421,6 +432,23 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
}
cliOpts.Volume = append(cliOpts.Volume, vol)
}
+ // Make mount points for compat volumes
+ for vol := range volSources {
+ // This might be a named volume.
+ // Assume it is if it's not an absolute path.
+ if !filepath.IsAbs(vol) {
+ continue
+ }
+ // If volume already exists, there is nothing to do
+ if _, err := os.Stat(vol); err == nil {
+ continue
+ }
+ if err := os.MkdirAll(vol, 0755); err != nil {
+ if !os.IsExist(err) {
+ return nil, nil, errors.Wrapf(err, "error making volume mountpoint for volume %s", vol)
+ }
+ }
+ }
if len(cc.HostConfig.BlkioWeightDevice) > 0 {
devices := make([]string, 0, len(cc.HostConfig.BlkioWeightDevice))
for _, d := range cc.HostConfig.BlkioWeightDevice {
diff --git a/cmd/podman/common/volumes.go b/cmd/podman/common/volumes.go
index 19a49a6f2..aff323936 100644
--- a/cmd/podman/common/volumes.go
+++ b/cmd/podman/common/volumes.go
@@ -6,23 +6,13 @@ import (
"strings"
"github.com/containers/common/pkg/parse"
+ "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
-const (
- // TypeBind is the type for mounting host dir
- TypeBind = "bind"
- // TypeVolume is the type for named volumes
- TypeVolume = "volume"
- // TypeTmpfs is the type for mounting tmpfs
- TypeTmpfs = "tmpfs"
- // TypeDevpts is the type for creating a devpts
- TypeDevpts = "devpts"
-)
-
var (
errDuplicateDest = errors.Errorf("duplicate mount destination")
optionArgError = errors.Errorf("must provide an argument for option")
@@ -90,7 +80,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
}
unifiedMounts[dest] = spec.Mount{
Destination: dest,
- Type: TypeTmpfs,
+ Type: define.TypeTmpfs,
Source: "tmpfs",
Options: options,
}
@@ -131,7 +121,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
// Final step: maps to arrays
finalMounts := make([]spec.Mount, 0, len(unifiedMounts))
for _, mount := range unifiedMounts {
- if mount.Type == TypeBind {
+ if mount.Type == define.TypeBind {
absSrc, err := filepath.Abs(mount.Source)
if err != nil {
return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source)
@@ -194,7 +184,7 @@ func getMounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.N
return nil, nil, nil, err
}
switch mountType {
- case TypeBind:
+ case define.TypeBind:
mount, err := getBindMount(tokens)
if err != nil {
return nil, nil, nil, err
@@ -203,7 +193,7 @@ func getMounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.N
return nil, nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
}
finalMounts[mount.Destination] = mount
- case TypeTmpfs:
+ case define.TypeTmpfs:
mount, err := getTmpfsMount(tokens)
if err != nil {
return nil, nil, nil, err
@@ -212,7 +202,7 @@ func getMounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.N
return nil, nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
}
finalMounts[mount.Destination] = mount
- case TypeDevpts:
+ case define.TypeDevpts:
mount, err := getDevptsMount(tokens)
if err != nil {
return nil, nil, nil, err
@@ -250,7 +240,7 @@ func getMounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.N
// Parse a single bind mount entry from the --mount flag.
func getBindMount(args []string) (spec.Mount, error) {
newMount := spec.Mount{
- Type: TypeBind,
+ Type: define.TypeBind,
}
var setSource, setDest, setRORW, setSuid, setDev, setExec, setRelabel bool
@@ -381,8 +371,8 @@ func getBindMount(args []string) (spec.Mount, error) {
// Parse a single tmpfs mount entry from the --mount flag
func getTmpfsMount(args []string) (spec.Mount, error) {
newMount := spec.Mount{
- Type: TypeTmpfs,
- Source: TypeTmpfs,
+ Type: define.TypeTmpfs,
+ Source: define.TypeTmpfs,
}
var setDest, setRORW, setSuid, setDev, setExec, setTmpcopyup bool
@@ -460,8 +450,8 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
// Parse a single devpts mount entry from the --mount flag
func getDevptsMount(args []string) (spec.Mount, error) {
newMount := spec.Mount{
- Type: TypeDevpts,
- Source: TypeDevpts,
+ Type: define.TypeDevpts,
+ Source: define.TypeDevpts,
}
var setDest bool
@@ -630,9 +620,9 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) {
mount := spec.Mount{
Destination: filepath.Clean(destPath),
- Type: string(TypeTmpfs),
+ Type: string(define.TypeTmpfs),
Options: options,
- Source: string(TypeTmpfs),
+ Source: string(define.TypeTmpfs),
}
m[destPath] = mount
}
diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go
index 7887e9539..27aacc6e5 100644
--- a/cmd/podman/containers/cp.go
+++ b/cmd/podman/containers/cp.go
@@ -160,6 +160,25 @@ func copyFromContainer(container string, containerPath string, hostPath string)
}
}
+ // If we copy a directory via the "." notation and the host path does
+ // not exist, we need to make sure that the destination on the host
+ // gets created; otherwise the contents of the source directory will be
+ // written to the destination's parent directory.
+ //
+ // While we could cut it short on the host and do create the directory
+ // ourselves, we would run into problems trying to that the other way
+ // around when copying into a container. Instead, to keep both
+ // implementations symmetrical, we need to massage the code a bit to
+ // let Buildah's copier package create the destination.
+ //
+ // Hence, whenever "." is the source and the destination does not exist,
+ // we copy the source's parent and let the copier package create the
+ // destination via the Rename option.
+ containerTarget := containerInfo.LinkTarget
+ if hostInfoErr != nil && containerInfo.IsDir && strings.HasSuffix(containerTarget, ".") {
+ containerTarget = filepath.Dir(containerTarget)
+ }
+
reader, writer := io.Pipe()
hostCopy := func() error {
defer reader.Close()
@@ -189,13 +208,14 @@ func copyFromContainer(container string, containerPath string, hostPath string)
}
putOptions := buildahCopiah.PutOptions{
- ChownDirs: &idPair,
- ChownFiles: &idPair,
+ ChownDirs: &idPair,
+ ChownFiles: &idPair,
+ IgnoreDevices: true,
}
- if !containerInfo.IsDir && (!hostInfo.IsDir || hostInfoErr != nil) {
+ if (!containerInfo.IsDir && !hostInfo.IsDir) || hostInfoErr != nil {
// If we're having a file-to-file copy, make sure to
// rename accordingly.
- putOptions.Rename = map[string]string{filepath.Base(containerInfo.LinkTarget): hostBaseName}
+ putOptions.Rename = map[string]string{filepath.Base(containerTarget): hostBaseName}
}
dir := hostInfo.LinkTarget
if !hostInfo.IsDir {
@@ -209,7 +229,7 @@ func copyFromContainer(container string, containerPath string, hostPath string)
containerCopy := func() error {
defer writer.Close()
- copyFunc, err := registry.ContainerEngine().ContainerCopyToArchive(registry.GetContext(), container, containerInfo.LinkTarget, writer)
+ copyFunc, err := registry.ContainerEngine().ContainerCopyToArchive(registry.GetContext(), container, containerTarget, writer)
if err != nil {
return err
}
@@ -277,6 +297,19 @@ func copyToContainer(container string, containerPath string, hostPath string) er
containerBaseName = filepath.Base(containerInfo.LinkTarget)
}
+ // If we copy a directory via the "." notation and the container path
+ // does not exist, we need to make sure that the destination on the
+ // container gets created; otherwise the contents of the source
+ // directory will be written to the destination's parent directory.
+ //
+ // Hence, whenever "." is the source and the destination does not
+ // exist, we copy the source's parent and let the copier package create
+ // the destination via the Rename option.
+ hostTarget := hostInfo.LinkTarget
+ if containerInfoErr != nil && hostInfo.IsDir && strings.HasSuffix(hostTarget, ".") {
+ hostTarget = filepath.Dir(hostTarget)
+ }
+
var stdinFile string
if isStdin {
if !containerInfo.IsDir {
@@ -317,15 +350,16 @@ func copyToContainer(container string, containerPath string, hostPath string) er
}
getOptions := buildahCopiah.GetOptions{
- // Unless the specified points to ".", we want to copy the base directory.
- KeepDirectoryNames: hostInfo.IsDir && filepath.Base(hostPath) != ".",
+ // Unless the specified path points to ".", we want to
+ // copy the base directory.
+ KeepDirectoryNames: hostInfo.IsDir && filepath.Base(hostTarget) != ".",
}
- if !hostInfo.IsDir && (!containerInfo.IsDir || containerInfoErr != nil) {
+ if (!hostInfo.IsDir && !containerInfo.IsDir) || containerInfoErr != nil {
// If we're having a file-to-file copy, make sure to
// rename accordingly.
- getOptions.Rename = map[string]string{filepath.Base(hostInfo.LinkTarget): containerBaseName}
+ getOptions.Rename = map[string]string{filepath.Base(hostTarget): containerBaseName}
}
- if err := buildahCopiah.Get("/", "", getOptions, []string{hostInfo.LinkTarget}, writer); err != nil {
+ if err := buildahCopiah.Get("/", "", getOptions, []string{hostTarget}, writer); err != nil {
return errors.Wrap(err, "error copying from host")
}
return nil
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index de532ed78..3b34a6bf6 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -2,6 +2,7 @@ package images
import (
"io"
+ "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -19,7 +20,6 @@ import (
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -170,6 +170,7 @@ func buildFlags(cmd *cobra.Command) {
_ = flags.MarkHidden("signature-policy")
_ = flags.MarkHidden("tls-verify")
_ = flags.MarkHidden("compress")
+ _ = flags.MarkHidden("volume")
}
}
@@ -298,6 +299,11 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
}
}
+ commonOpts, err := parse.CommonBuildOptions(c)
+ if err != nil {
+ return nil, err
+ }
+
pullPolicy := imagebuildah.PullIfMissing
if c.Flags().Changed("pull") && flags.Pull {
pullPolicy = imagebuildah.PullAlways
@@ -317,7 +323,12 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
if len(av) > 1 {
args[av[0]] = av[1]
} else {
- delete(args, av[0])
+ // check if the env is set in the local environment and use that value if it is
+ if val, present := os.LookupEnv(av[0]); present {
+ args[av[0]] = val
+ } else {
+ delete(args, av[0])
+ }
}
}
}
@@ -356,22 +367,6 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
reporter = logfile
}
- var memoryLimit, memorySwap int64
- var err error
- if c.Flags().Changed("memory") {
- memoryLimit, err = units.RAMInBytes(flags.Memory)
- if err != nil {
- return nil, err
- }
- }
-
- if c.Flags().Changed("memory-swap") {
- memorySwap, err = units.RAMInBytes(flags.MemorySwap)
- if err != nil {
- return nil, err
- }
- }
-
nsValues, networkPolicy, err := parse.NamespaceOptions(c)
if err != nil {
return nil, err
@@ -449,29 +444,15 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
}
opts := imagebuildah.BuildOptions{
- AddCapabilities: flags.CapAdd,
- AdditionalTags: tags,
- Annotations: flags.Annotation,
- Architecture: arch,
- Args: args,
- BlobDirectory: flags.BlobCache,
- CNIConfigDir: flags.CNIConfigDir,
- CNIPluginPath: flags.CNIPlugInPath,
- CommonBuildOpts: &buildah.CommonBuildOptions{
- AddHost: flags.AddHost,
- CPUPeriod: flags.CPUPeriod,
- CPUQuota: flags.CPUQuota,
- CPUSetCPUs: flags.CPUSetCPUs,
- CPUSetMems: flags.CPUSetMems,
- CPUShares: flags.CPUShares,
- CgroupParent: flags.CgroupParent,
- HTTPProxy: flags.HTTPProxy,
- Memory: memoryLimit,
- MemorySwap: memorySwap,
- ShmSize: flags.ShmSize,
- Ulimit: flags.Ulimit,
- Volumes: flags.Volumes,
- },
+ AddCapabilities: flags.CapAdd,
+ AdditionalTags: tags,
+ Annotations: flags.Annotation,
+ Architecture: arch,
+ Args: args,
+ BlobDirectory: flags.BlobCache,
+ CNIConfigDir: flags.CNIConfigDir,
+ CNIPluginPath: flags.CNIPlugInPath,
+ CommonBuildOpts: commonOpts,
Compression: compression,
ConfigureNetwork: networkPolicy,
ContextDirectory: contextDir,
@@ -512,6 +493,14 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
TransientMounts: flags.Volumes,
}
+ if flags.IgnoreFile != "" {
+ excludes, err := parseDockerignore(flags.IgnoreFile)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to obtain decrypt config")
+ }
+ opts.Excludes = excludes
+ }
+
if c.Flag("timestamp").Changed {
timestamp := time.Unix(flags.Timestamp, 0).UTC()
opts.Timestamp = &timestamp
@@ -534,3 +523,18 @@ func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error)
return decConfig, nil
}
+
+func parseDockerignore(ignoreFile string) ([]string, error) {
+ excludes := []string{}
+ ignore, err := ioutil.ReadFile(ignoreFile)
+ if err != nil {
+ return excludes, err
+ }
+ for _, e := range strings.Split(string(ignore), "\n") {
+ if len(e) == 0 || e[0] == '#' {
+ continue
+ }
+ excludes = append(excludes, e)
+ }
+ return excludes, nil
+}
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 874573bb9..7722e35dd 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -17,9 +17,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/parallel"
"github.com/containers/podman/v3/pkg/rootless"
- "github.com/containers/podman/v3/pkg/tracing"
"github.com/containers/podman/v3/version"
- "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -103,7 +101,6 @@ func Execute() {
}
func persistentPreRunE(cmd *cobra.Command, args []string) error {
- // TODO: Remove trace statement in podman V2.1
logrus.Debugf("Called %s.PersistentPreRunE(%s)", cmd.Name(), strings.Join(os.Args, " "))
// Help, completion and commands with subcommands are special cases, no need for more setup
@@ -194,16 +191,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
}
}
- if cmd.Flag("trace").Changed {
- tracer, closer := tracing.Init("podman")
- opentracing.SetGlobalTracer(tracer)
- cfg.SpanCloser = closer
-
- cfg.Span = tracer.StartSpan("before-context")
- cfg.SpanCtx = opentracing.ContextWithSpan(registry.Context(), cfg.Span)
- opentracing.StartSpanFromContext(cfg.SpanCtx, cmd.Name())
- }
-
if cfg.MaxWorks <= 0 {
return errors.Errorf("maximum workers must be set to a positive number (got %d)", cfg.MaxWorks)
}
@@ -226,22 +213,16 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
}
func persistentPostRunE(cmd *cobra.Command, args []string) error {
- // TODO: Remove trace statement in podman V2.1
logrus.Debugf("Called %s.PersistentPostRunE(%s)", cmd.Name(), strings.Join(os.Args, " "))
if !requireCleanup {
return nil
}
- cfg := registry.PodmanConfig()
if !registry.IsRemote() {
if cmd.Flag("cpu-profile").Changed {
pprof.StopCPUProfile()
}
- if cmd.Flag("trace").Changed {
- cfg.Span.Finish()
- cfg.SpanCloser.Close()
- }
}
registry.ImageEngine().Shutdown(registry.Context())