mirror of
https://github.com/containers/podman.git
synced 2025-06-21 17:38:12 +08:00
v2 podman unshare command
add unshare command add cp and init to container sub-command allow mount to run as rootless Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -22,20 +23,41 @@ var (
|
|||||||
RunE: cp,
|
RunE: cp,
|
||||||
Example: "podman cp [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH",
|
Example: "podman cp [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containerCpCommand = &cobra.Command{
|
||||||
|
Use: cpCommand.Use,
|
||||||
|
Short: cpCommand.Short,
|
||||||
|
Long: cpCommand.Long,
|
||||||
|
Args: cpCommand.Args,
|
||||||
|
RunE: cpCommand.RunE,
|
||||||
|
Example: "podman container cp [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cpOpts entities.ContainerCpOptions
|
cpOpts entities.ContainerCpOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func cpFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.BoolVar(&cpOpts.Extract, "extract", false, "Extract the tar file into the destination directory.")
|
||||||
|
flags.BoolVar(&cpOpts.Pause, "pause", copyPause(), "Pause the container while copying")
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
Mode: []entities.EngineMode{entities.ABIMode},
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
Command: cpCommand,
|
Command: cpCommand,
|
||||||
})
|
})
|
||||||
flags := cpCommand.Flags()
|
flags := cpCommand.Flags()
|
||||||
flags.BoolVar(&cpOpts.Extract, "extract", false, "Extract the tar file into the destination directory.")
|
cpFlags(flags)
|
||||||
flags.BoolVar(&cpOpts.Pause, "pause", copyPause(), "Pause the container while copying")
|
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: containerCpCommand,
|
||||||
|
Parent: containerCmd,
|
||||||
|
})
|
||||||
|
containerCpFlags := containerCpCommand.Flags()
|
||||||
|
cpFlags(containerCpFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cp(cmd *cobra.Command, args []string) error {
|
func cp(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/containers/libpod/cmd/podman/utils"
|
"github.com/containers/libpod/cmd/podman/utils"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,21 +26,47 @@ var (
|
|||||||
podman init 3c45ef19d893
|
podman init 3c45ef19d893
|
||||||
podman init test1`,
|
podman init test1`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containerInitCommand = &cobra.Command{
|
||||||
|
Use: initCommand.Use,
|
||||||
|
Short: initCommand.Short,
|
||||||
|
Long: initCommand.Long,
|
||||||
|
RunE: initCommand.RunE,
|
||||||
|
Args: initCommand.Args,
|
||||||
|
Example: `podman container init --latest
|
||||||
|
podman container init 3c45ef19d893
|
||||||
|
podman container init test1`,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
initOptions entities.ContainerInitOptions
|
initOptions entities.ContainerInitOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func initFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.BoolVarP(&initOptions.All, "all", "a", false, "Initialize all containers")
|
||||||
|
flags.BoolVarP(&initOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
||||||
|
if registry.IsRemote() {
|
||||||
|
_ = flags.MarkHidden("latest")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
Command: initCommand,
|
Command: initCommand,
|
||||||
})
|
})
|
||||||
flags := initCommand.Flags()
|
flags := initCommand.Flags()
|
||||||
flags.BoolVarP(&initOptions.All, "all", "a", false, "Initialize all containers")
|
initFlags(flags)
|
||||||
flags.BoolVarP(&initOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
|
||||||
_ = flags.MarkHidden("latest")
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Parent: containerCmd,
|
||||||
|
Command: containerInitCommand,
|
||||||
|
})
|
||||||
|
|
||||||
|
containerInitFlags := containerInitCommand.Flags()
|
||||||
|
initFlags(containerInitFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initContainer(cmd *cobra.Command, args []string) error {
|
func initContainer(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -30,9 +30,6 @@ var (
|
|||||||
Args: func(cmd *cobra.Command, args []string) error {
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
|
return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
|
||||||
},
|
},
|
||||||
Annotations: map[string]string{
|
|
||||||
registry.ParentNSRequired: "",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
containerMountCommmand = &cobra.Command{
|
containerMountCommmand = &cobra.Command{
|
||||||
|
50
cmd/podman/system/unshare.go
Normal file
50
cmd/podman/system/unshare.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
unshareDescription = "Runs a command in a modified user namespace."
|
||||||
|
unshareCommand = &cobra.Command{
|
||||||
|
Use: "unshare [flags] [COMMAND [ARG]]",
|
||||||
|
Short: "Run a command in a modified user namespace",
|
||||||
|
Long: unshareDescription,
|
||||||
|
RunE: unshare,
|
||||||
|
Example: `podman unshare id
|
||||||
|
podman unshare cat /proc/self/uid_map,
|
||||||
|
podman unshare podman-script.sh`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: unshareCommand,
|
||||||
|
})
|
||||||
|
flags := unshareCommand.Flags()
|
||||||
|
flags.SetInterspersed(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unshare(cmd *cobra.Command, args []string) error {
|
||||||
|
if isRootless := rootless.IsRootless(); !isRootless {
|
||||||
|
return errors.Errorf("please use unshare with rootless")
|
||||||
|
}
|
||||||
|
// exec the specified command, if there is one
|
||||||
|
if len(args) < 1 {
|
||||||
|
// try to exec the shell, if one's set
|
||||||
|
shell, shellSet := os.LookupEnv("SHELL")
|
||||||
|
if !shellSet {
|
||||||
|
return errors.Errorf("no command specified and no $SHELL specified")
|
||||||
|
}
|
||||||
|
args = []string{shell}
|
||||||
|
}
|
||||||
|
|
||||||
|
return registry.ContainerEngine().Unshare(registry.Context(), args)
|
||||||
|
}
|
@ -71,6 +71,7 @@ type ContainerEngine interface {
|
|||||||
SetupRootless(ctx context.Context, cmd *cobra.Command) error
|
SetupRootless(ctx context.Context, cmd *cobra.Command) error
|
||||||
Shutdown(ctx context.Context)
|
Shutdown(ctx context.Context)
|
||||||
SystemDf(ctx context.Context, options SystemDfOptions) (*SystemDfReport, error)
|
SystemDf(ctx context.Context, options SystemDfOptions) (*SystemDfReport, error)
|
||||||
|
Unshare(ctx context.Context, args []string) error
|
||||||
VarlinkService(ctx context.Context, opts ServiceOptions) error
|
VarlinkService(ctx context.Context, opts ServiceOptions) error
|
||||||
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error)
|
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error)
|
||||||
VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error)
|
VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -391,3 +392,18 @@ func (s SystemEngine) Shutdown(ctx context.Context) {
|
|||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unshareEnv(graphroot, runroot string) []string {
|
||||||
|
return append(os.Environ(), "_CONTAINERS_USERNS_CONFIGURED=done",
|
||||||
|
fmt.Sprintf("CONTAINERS_GRAPHROOT=%s", graphroot),
|
||||||
|
fmt.Sprintf("CONTAINERS_RUNROOT=%s", runroot))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) Unshare(ctx context.Context, args []string) error {
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
cmd.Env = unshareEnv(ic.Libpod.StorageConfig().GraphRoot, ic.Libpod.StorageConfig().RunRoot)
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
@ -30,3 +30,7 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.SystemDfOptions) (*entities.SystemDfReport, error) {
|
func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.SystemDfOptions) (*entities.SystemDfReport, error) {
|
||||||
panic(errors.New("system df is not supported on remote clients"))
|
panic(errors.New("system df is not supported on remote clients"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) Unshare(ctx context.Context, args []string) error {
|
||||||
|
return errors.New("unshare is not supported on remote clients")
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user