Merge pull request #27 from mrunalp/dev/nsenter_flags
Add option parsing to nsenter and enable specifying commands with arguments
This commit is contained in:
commit
2c29550226
|
@ -21,14 +21,8 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Move this to the container JSON.
|
||||
processLabel, err := label.GetPidCon(nspid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Enter the namespace and then finish setup
|
||||
finalArgs := []string{os.Args[0], "nsenter", strconv.Itoa(nspid), processLabel, string(containerJson)}
|
||||
finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(nspid), "--containerjson", string(containerJson), "--"}
|
||||
finalArgs = append(finalArgs, args...)
|
||||
if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil {
|
||||
return err
|
||||
|
@ -37,7 +31,7 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error {
|
|||
}
|
||||
|
||||
// NsEnter is run after entering the namespace.
|
||||
func NsEnter(container *libcontainer.Container, processLabel string, nspid int, args []string) error {
|
||||
func NsEnter(container *libcontainer.Container, nspid int, args []string) error {
|
||||
// clear the current processes env and replace it with the environment
|
||||
// defined on the container
|
||||
if err := LoadContainerEnvironment(container); err != nil {
|
||||
|
@ -46,9 +40,13 @@ func NsEnter(container *libcontainer.Container, processLabel string, nspid int,
|
|||
if err := FinalizeNamespace(container); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := label.SetProcessLabel(processLabel); err != nil {
|
||||
return err
|
||||
|
||||
if process_label, ok := container.Context["process_label"]; ok {
|
||||
if err := label.SetProcessLabel(process_label); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := system.Execv(args[0], args[0:], container.Env); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package namespaces
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static const kBufSize = 256;
|
||||
|
||||
|
@ -64,6 +65,10 @@ int setns(int fd, int nstype) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
void print_usage() {
|
||||
fprintf(stderr, "<binary> nsenter --nspid <pid> --containerjson <container_json> -- cmd1 arg1 arg2...\n");
|
||||
}
|
||||
|
||||
void nsenter() {
|
||||
int argc;
|
||||
char **argv;
|
||||
|
@ -79,11 +84,40 @@ void nsenter() {
|
|||
fprintf(stderr, "nsenter: Incorrect usage, not enough arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
pid_t init_pid = strtol(argv[2], NULL, 10);
|
||||
if (errno != 0 || init_pid <= 0) {
|
||||
fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", argv[2], strerror(errno));
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{ "nspid", required_argument, NULL, 'n' },
|
||||
{ "containerjson", required_argument, NULL, 'c' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
int c;
|
||||
pid_t init_pid = -1;
|
||||
char *init_pid_str = NULL;
|
||||
char *container_json = NULL;
|
||||
while ((c = getopt_long_only(argc, argv, "n:s:c:", longopts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
init_pid_str = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
container_json = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (container_json == NULL || init_pid_str == NULL) {
|
||||
print_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_pid = strtol(init_pid_str, NULL, 10);
|
||||
if (errno != 0 || init_pid <= 0) {
|
||||
fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", init_pid_str, strerror(errno));
|
||||
print_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
argc -= 3;
|
||||
argv += 3;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/libcontainer/namespaces"
|
||||
|
@ -12,29 +11,30 @@ var nsenterCommand = cli.Command{
|
|||
Name: "nsenter",
|
||||
Usage: "init process for entering an existing namespace",
|
||||
Action: nsenterAction,
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{Name: "nspid"},
|
||||
cli.StringFlag{Name: "containerjson"},
|
||||
},
|
||||
}
|
||||
|
||||
func nsenterAction(context *cli.Context) {
|
||||
args := context.Args()
|
||||
if len(args) < 4 {
|
||||
log.Fatalf("incorrect usage: <pid> <process label> <container JSON> <cmd>...")
|
||||
|
||||
if len(args) == 0 {
|
||||
args = []string{"/bin/bash"}
|
||||
}
|
||||
|
||||
container, err := loadContainerFromJson(args.Get(2))
|
||||
container, err := loadContainerFromJson(context.String("containerjson"))
|
||||
if err != nil {
|
||||
log.Fatalf("unable to load container: %s", err)
|
||||
}
|
||||
|
||||
nspid, err := strconv.Atoi(args.Get(0))
|
||||
if err != nil {
|
||||
log.Fatalf("unable to read pid: %s from %q", err, args.Get(0))
|
||||
}
|
||||
|
||||
nspid := context.Int("nspid")
|
||||
if nspid <= 0 {
|
||||
log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid)
|
||||
}
|
||||
|
||||
if err := namespaces.NsEnter(container, args.Get(1), nspid, args[3:]); err != nil {
|
||||
if err := namespaces.NsEnter(container, nspid, args); err != nil {
|
||||
log.Fatalf("failed to nsenter: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue