| package docker |
| |
| import ( |
| "flag" |
| "fmt" |
| "github.com/dotcloud/docker/utils" |
| "log" |
| "os" |
| "os/exec" |
| "strconv" |
| "strings" |
| "syscall" |
| ) |
| |
| // Setup networking |
| func setupNetworking(gw string) { |
| if gw == "" { |
| return |
| } |
| if _, err := ip("route", "add", "default", "via", gw); err != nil { |
| log.Fatalf("Unable to set up networking: %v", err) |
| } |
| } |
| |
| // Setup working directory |
| func setupWorkingDirectory(workdir string) { |
| if workdir == "" { |
| return |
| } |
| syscall.Chdir(workdir) |
| } |
| |
| // Takes care of dropping privileges to the desired user |
| func changeUser(u string) { |
| if u == "" { |
| return |
| } |
| userent, err := utils.UserLookup(u) |
| if err != nil { |
| log.Fatalf("Unable to find user %v: %v", u, err) |
| } |
| |
| uid, err := strconv.Atoi(userent.Uid) |
| if err != nil { |
| log.Fatalf("Invalid uid: %v", userent.Uid) |
| } |
| gid, err := strconv.Atoi(userent.Gid) |
| if err != nil { |
| log.Fatalf("Invalid gid: %v", userent.Gid) |
| } |
| |
| if err := syscall.Setgid(gid); err != nil { |
| log.Fatalf("setgid failed: %v", err) |
| } |
| if err := syscall.Setuid(uid); err != nil { |
| log.Fatalf("setuid failed: %v", err) |
| } |
| } |
| |
| // Clear environment pollution introduced by lxc-start |
| func cleanupEnv(env ListOpts) { |
| os.Clearenv() |
| for _, kv := range env { |
| parts := strings.SplitN(kv, "=", 2) |
| if len(parts) == 1 { |
| parts = append(parts, "") |
| } |
| os.Setenv(parts[0], parts[1]) |
| } |
| } |
| |
| func executeProgram(name string, args []string) { |
| path, err := exec.LookPath(name) |
| if err != nil { |
| log.Printf("Unable to locate %v", name) |
| os.Exit(127) |
| } |
| |
| if err := syscall.Exec(path, args, os.Environ()); err != nil { |
| panic(err) |
| } |
| } |
| |
| // Sys Init code |
| // This code is run INSIDE the container and is responsible for setting |
| // up the environment before running the actual process |
| func SysInit() { |
| if len(os.Args) <= 1 { |
| fmt.Println("You should not invoke docker-init manually") |
| os.Exit(1) |
| } |
| var u = flag.String("u", "", "username or uid") |
| var gw = flag.String("g", "", "gateway address") |
| var workdir = flag.String("w", "", "workdir") |
| |
| var flEnv ListOpts |
| flag.Var(&flEnv, "e", "Set environment variables") |
| |
| flag.Parse() |
| |
| cleanupEnv(flEnv) |
| setupNetworking(*gw) |
| setupWorkingDirectory(*workdir) |
| changeUser(*u) |
| executeProgram(flag.Arg(0), flag.Args()) |
| } |