summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/containers/logs.go4
-rw-r--r--cmd/podman/generate/kube.go5
-rw-r--r--cmd/podman/machine/init.go3
-rw-r--r--cmd/podman/volumes/import.go97
4 files changed, 106 insertions, 3 deletions
diff --git a/cmd/podman/containers/logs.go b/cmd/podman/containers/logs.go
index 00a8d4b52..1548c6c24 100644
--- a/cmd/podman/containers/logs.go
+++ b/cmd/podman/containers/logs.go
@@ -120,7 +120,7 @@ func logsFlags(cmd *cobra.Command) {
func logs(_ *cobra.Command, args []string) error {
if logsOptions.SinceRaw != "" {
// parse time, error out if something is wrong
- since, err := util.ParseInputTime(logsOptions.SinceRaw)
+ since, err := util.ParseInputTime(logsOptions.SinceRaw, true)
if err != nil {
return errors.Wrapf(err, "error parsing --since %q", logsOptions.SinceRaw)
}
@@ -128,7 +128,7 @@ func logs(_ *cobra.Command, args []string) error {
}
if logsOptions.UntilRaw != "" {
// parse time, error out if something is wrong
- until, err := util.ParseInputTime(logsOptions.UntilRaw)
+ until, err := util.ParseInputTime(logsOptions.UntilRaw, false)
if err != nil {
return errors.Wrapf(err, "error parsing --until %q", logsOptions.UntilRaw)
}
diff --git a/cmd/podman/generate/kube.go b/cmd/podman/generate/kube.go
index b4c9f9146..60b8f0af0 100644
--- a/cmd/podman/generate/kube.go
+++ b/cmd/podman/generate/kube.go
@@ -2,6 +2,7 @@ package pods
import (
"fmt"
+ "io"
"io/ioutil"
"os"
@@ -61,6 +62,10 @@ func kube(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+ if r, ok := report.Reader.(io.ReadCloser); ok {
+ defer r.Close()
+ }
+
if cmd.Flags().Changed("filename") {
if _, err := os.Stat(kubeFile); err == nil {
return errors.Errorf("cannot write to %q; file exists", kubeFile)
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index f4133dbde..ac0d06a07 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -34,6 +34,7 @@ func init() {
Parent: machineCmd,
})
flags := initCmd.Flags()
+ cfg := registry.PodmanConfig()
cpusFlagName := "cpus"
flags.Uint64Var(
@@ -61,7 +62,7 @@ func init() {
_ = initCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
ImagePathFlagName := "image-path"
- flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, "", "Path to qcow image")
+ flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, cfg.Engine.MachineImage, "Path to qcow image")
_ = initCmd.RegisterFlagCompletionFunc(ImagePathFlagName, completion.AutocompleteDefault)
IgnitionPathFlagName := "ignition-path"
diff --git a/cmd/podman/volumes/import.go b/cmd/podman/volumes/import.go
new file mode 100644
index 000000000..441bd0fe4
--- /dev/null
+++ b/cmd/podman/volumes/import.go
@@ -0,0 +1,97 @@
+package volumes
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/inspect"
+ "github.com/containers/podman/v3/cmd/podman/parse"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/utils"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ importDescription = `Imports contents into a podman volume from specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz).`
+ importCommand = &cobra.Command{
+ Annotations: map[string]string{registry.EngineMode: registry.ABIMode},
+ Use: "import VOLUME [SOURCE]",
+ Short: "Import a tarball contents into a podman volume",
+ Long: importDescription,
+ RunE: importVol,
+ Args: cobra.ExactArgs(2),
+ ValidArgsFunction: common.AutocompleteVolumes,
+ Example: `podman volume import my_vol /home/user/import.tar
+ cat ctr.tar | podman import volume my_vol -`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: importCommand,
+ Parent: volumeCmd,
+ })
+}
+
+func importVol(cmd *cobra.Command, args []string) error {
+ var inspectOpts entities.InspectOptions
+ var tarFile *os.File
+ containerEngine := registry.ContainerEngine()
+ ctx := registry.Context()
+ // create a slice of volumes since inspect expects slice as arg
+ volumes := []string{args[0]}
+ tarPath := args[1]
+
+ if tarPath != "-" {
+ err := parse.ValidateFileName(tarPath)
+ if err != nil {
+ return err
+ }
+
+ // open tar file
+ tarFile, err = os.Open(tarPath)
+ if err != nil {
+ return err
+ }
+ } else {
+ tarFile = os.Stdin
+ }
+
+ inspectOpts.Type = inspect.VolumeType
+ volumeData, _, err := containerEngine.VolumeInspect(ctx, volumes, inspectOpts)
+ if err != nil {
+ return err
+ }
+ if len(volumeData) < 1 {
+ return errors.New("no volume data found")
+ }
+ mountPoint := volumeData[0].VolumeConfigResponse.Mountpoint
+ driver := volumeData[0].VolumeConfigResponse.Driver
+ volumeOptions := volumeData[0].VolumeConfigResponse.Options
+ volumeMountStatus, err := containerEngine.VolumeMounted(ctx, args[0])
+ if err != nil {
+ return err
+ }
+ if mountPoint == "" {
+ return errors.New("volume is not mounted anywhere on host")
+ }
+ // Check if volume is using external plugin and export only if volume is mounted
+ if driver != "" && driver != "local" {
+ if !volumeMountStatus.Value {
+ return fmt.Errorf("volume is using a driver %s and volume is not mounted on %s", driver, mountPoint)
+ }
+ }
+ // Check if volume is using `local` driver and has mount options type other than tmpfs
+ if driver == "local" {
+ if mountOptionType, ok := volumeOptions["type"]; ok {
+ if mountOptionType != "tmpfs" && !volumeMountStatus.Value {
+ return fmt.Errorf("volume is using a driver %s and volume is not mounted on %s", driver, mountPoint)
+ }
+ }
+ }
+ // dont care if volume is mounted or not we are gonna import everything to mountPoint
+ return utils.UntarToFileSystem(mountPoint, tarFile, nil)
+}