github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/daemon/execdriver/lxc/init.go (about)

     1  package lxc
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"log"
     8  	"os"
     9  	"os/exec"
    10  	"runtime"
    11  	"strings"
    12  	"syscall"
    13  
    14  	"github.com/docker/docker/pkg/reexec"
    15  )
    16  
    17  // Args provided to the init function for a driver
    18  type InitArgs struct {
    19  	User       string
    20  	Gateway    string
    21  	Ip         string
    22  	WorkDir    string
    23  	Privileged bool
    24  	Env        []string
    25  	Args       []string
    26  	Mtu        int
    27  	Console    string
    28  	Pipe       int
    29  	Root       string
    30  	CapAdd     string
    31  	CapDrop    string
    32  }
    33  
    34  func init() {
    35  	// like always lxc requires a hack to get this to work
    36  	reexec.Register("/.dockerinit", dockerInititalizer)
    37  }
    38  
    39  func dockerInititalizer() {
    40  	initializer()
    41  }
    42  
    43  // initializer is the lxc driver's init function that is run inside the namespace to setup
    44  // additional configurations
    45  func initializer() {
    46  	runtime.LockOSThread()
    47  
    48  	args := getArgs()
    49  
    50  	if err := setupNamespace(args); err != nil {
    51  		log.Fatal(err)
    52  	}
    53  }
    54  
    55  func setupNamespace(args *InitArgs) error {
    56  	if err := setupEnv(args); err != nil {
    57  		return err
    58  	}
    59  
    60  	if err := finalizeNamespace(args); err != nil {
    61  		return err
    62  	}
    63  
    64  	path, err := exec.LookPath(args.Args[0])
    65  	if err != nil {
    66  		log.Printf("Unable to locate %v", args.Args[0])
    67  		os.Exit(127)
    68  	}
    69  
    70  	if err := syscall.Exec(path, args.Args, os.Environ()); err != nil {
    71  		return fmt.Errorf("dockerinit unable to execute %s - %s", path, err)
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  func getArgs() *InitArgs {
    78  	var (
    79  		// Get cmdline arguments
    80  		user       = flag.String("u", "", "username or uid")
    81  		gateway    = flag.String("g", "", "gateway address")
    82  		ip         = flag.String("i", "", "ip address")
    83  		workDir    = flag.String("w", "", "workdir")
    84  		privileged = flag.Bool("privileged", false, "privileged mode")
    85  		mtu        = flag.Int("mtu", 1500, "interface mtu")
    86  		capAdd     = flag.String("cap-add", "", "capabilities to add")
    87  		capDrop    = flag.String("cap-drop", "", "capabilities to drop")
    88  	)
    89  
    90  	flag.Parse()
    91  
    92  	return &InitArgs{
    93  		User:       *user,
    94  		Gateway:    *gateway,
    95  		Ip:         *ip,
    96  		WorkDir:    *workDir,
    97  		Privileged: *privileged,
    98  		Args:       flag.Args(),
    99  		Mtu:        *mtu,
   100  		CapAdd:     *capAdd,
   101  		CapDrop:    *capDrop,
   102  	}
   103  }
   104  
   105  // Clear environment pollution introduced by lxc-start
   106  func setupEnv(args *InitArgs) error {
   107  	// Get env
   108  	var env []string
   109  	dockerenv, err := os.Open(".dockerenv")
   110  	if err != nil {
   111  		return fmt.Errorf("Unable to load environment variables: %v", err)
   112  	}
   113  	defer dockerenv.Close()
   114  	if err := json.NewDecoder(dockerenv).Decode(&env); err != nil {
   115  		return fmt.Errorf("Unable to decode environment variables: %v", err)
   116  	}
   117  	// Propagate the plugin-specific container env variable
   118  	env = append(env, "container="+os.Getenv("container"))
   119  
   120  	args.Env = env
   121  
   122  	os.Clearenv()
   123  	for _, kv := range args.Env {
   124  		parts := strings.SplitN(kv, "=", 2)
   125  		if len(parts) == 1 {
   126  			parts = append(parts, "")
   127  		}
   128  		os.Setenv(parts[0], parts[1])
   129  	}
   130  
   131  	return nil
   132  }
   133  
   134  // Setup working directory
   135  func setupWorkingDirectory(args *InitArgs) error {
   136  	if args.WorkDir == "" {
   137  		return nil
   138  	}
   139  	if err := syscall.Chdir(args.WorkDir); err != nil {
   140  		return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
   141  	}
   142  	return nil
   143  }