mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
5e1a975b48
ip from iproute2 replaces the legacy route tool which is often not installed by default on recent Linux distributions. The same patch has been done in network.go and is re-used here.
100 lines
2 KiB
Go
100 lines
2 KiB
Go
package docker
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"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)
|
|
}
|
|
}
|
|
|
|
// Takes care of dropping privileges to the desired user
|
|
func changeUser(u string) {
|
|
if u == "" {
|
|
return
|
|
}
|
|
userent, err := user.LookupId(u)
|
|
if err != nil {
|
|
userent, err = user.Lookup(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 := os.Environ()
|
|
os.Clearenv()
|
|
for _, kv := range env {
|
|
parts := strings.SplitN(kv, "=", 2)
|
|
if len(parts) == 1 {
|
|
parts = append(parts, "")
|
|
}
|
|
if parts[0] == "container" {
|
|
continue
|
|
}
|
|
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")
|
|
|
|
flag.Parse()
|
|
|
|
setupNetworking(*gw)
|
|
cleanupEnv()
|
|
changeUser(*u)
|
|
executeProgram(flag.Arg(0), flag.Args())
|
|
}
|