github.com/dougm/docker@v1.5.0/daemon/execdriver/lxc/init.go (about) 1 package lxc 2 3 import ( 4 "encoding/json" 5 "flag" 6 "fmt" 7 "io/ioutil" 8 "log" 9 "os" 10 "os/exec" 11 "runtime" 12 "strings" 13 "syscall" 14 15 "github.com/docker/docker/pkg/reexec" 16 ) 17 18 // Args provided to the init function for a driver 19 type InitArgs struct { 20 User string 21 Gateway string 22 Ip string 23 WorkDir string 24 Privileged bool 25 Env []string 26 Args []string 27 Mtu int 28 Console string 29 Pipe int 30 Root string 31 CapAdd string 32 CapDrop string 33 } 34 35 func init() { 36 // like always lxc requires a hack to get this to work 37 reexec.Register("/.dockerinit", dockerInititalizer) 38 } 39 40 func dockerInititalizer() { 41 initializer() 42 } 43 44 // initializer is the lxc driver's init function that is run inside the namespace to setup 45 // additional configurations 46 func initializer() { 47 runtime.LockOSThread() 48 49 args := getArgs() 50 51 if err := setupNamespace(args); err != nil { 52 log.Fatal(err) 53 } 54 } 55 56 func setupNamespace(args *InitArgs) error { 57 if err := setupEnv(args); err != nil { 58 return err 59 } 60 61 if err := finalizeNamespace(args); err != nil { 62 return err 63 } 64 65 path, err := exec.LookPath(args.Args[0]) 66 if err != nil { 67 log.Printf("Unable to locate %v", args.Args[0]) 68 os.Exit(127) 69 } 70 71 if err := syscall.Exec(path, args.Args, os.Environ()); err != nil { 72 return fmt.Errorf("dockerinit unable to execute %s - %s", path, err) 73 } 74 75 return nil 76 } 77 78 func getArgs() *InitArgs { 79 var ( 80 // Get cmdline arguments 81 user = flag.String("u", "", "username or uid") 82 gateway = flag.String("g", "", "gateway address") 83 ip = flag.String("i", "", "ip address") 84 workDir = flag.String("w", "", "workdir") 85 privileged = flag.Bool("privileged", false, "privileged mode") 86 mtu = flag.Int("mtu", 1500, "interface mtu") 87 capAdd = flag.String("cap-add", "", "capabilities to add") 88 capDrop = flag.String("cap-drop", "", "capabilities to drop") 89 ) 90 91 flag.Parse() 92 93 return &InitArgs{ 94 User: *user, 95 Gateway: *gateway, 96 Ip: *ip, 97 WorkDir: *workDir, 98 Privileged: *privileged, 99 Args: flag.Args(), 100 Mtu: *mtu, 101 CapAdd: *capAdd, 102 CapDrop: *capDrop, 103 } 104 } 105 106 // Clear environment pollution introduced by lxc-start 107 func setupEnv(args *InitArgs) error { 108 // Get env 109 var env []string 110 content, err := ioutil.ReadFile(".dockerenv") 111 if err != nil { 112 return fmt.Errorf("Unable to load environment variables: %v", err) 113 } 114 if err := json.Unmarshal(content, &env); err != nil { 115 return fmt.Errorf("Unable to unmarshal 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 } 144 145 func getEnv(args *InitArgs, key string) string { 146 for _, kv := range args.Env { 147 parts := strings.SplitN(kv, "=", 2) 148 if parts[0] == key && len(parts) == 2 { 149 return parts[1] 150 } 151 } 152 return "" 153 }