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