2014-01-13 21:36:59 -05:00
|
|
|
package lxc
|
|
|
|
|
|
|
|
import (
|
2014-03-03 13:19:00 -05:00
|
|
|
"encoding/json"
|
2014-08-08 16:18:18 -04:00
|
|
|
"flag"
|
2014-01-13 21:36:59 -05:00
|
|
|
"fmt"
|
2014-03-03 13:19:00 -05:00
|
|
|
"io/ioutil"
|
2014-08-08 16:18:18 -04:00
|
|
|
"log"
|
2014-01-13 21:36:59 -05:00
|
|
|
"os"
|
2014-08-08 16:18:18 -04:00
|
|
|
"os/exec"
|
|
|
|
"runtime"
|
2014-01-13 21:36:59 -05:00
|
|
|
"strings"
|
|
|
|
"syscall"
|
2014-05-02 17:17:31 -04:00
|
|
|
|
2014-10-30 08:48:30 -04:00
|
|
|
"github.com/docker/docker/pkg/reexec"
|
2014-01-13 21:36:59 -05:00
|
|
|
)
|
|
|
|
|
2014-08-08 16:18:18 -04:00
|
|
|
// Args provided to the init function for a driver
|
|
|
|
type InitArgs struct {
|
|
|
|
User string
|
|
|
|
Gateway string
|
|
|
|
Ip string
|
|
|
|
WorkDir string
|
|
|
|
Privileged bool
|
|
|
|
Env []string
|
|
|
|
Args []string
|
|
|
|
Mtu int
|
|
|
|
Console string
|
|
|
|
Pipe int
|
|
|
|
Root string
|
|
|
|
CapAdd string
|
|
|
|
CapDrop string
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// like always lxc requires a hack to get this to work
|
|
|
|
reexec.Register("/.dockerinit", dockerInititalizer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func dockerInititalizer() {
|
|
|
|
initializer()
|
|
|
|
}
|
|
|
|
|
|
|
|
// initializer is the lxc driver's init function that is run inside the namespace to setup
|
|
|
|
// additional configurations
|
|
|
|
func initializer() {
|
|
|
|
runtime.LockOSThread()
|
|
|
|
|
|
|
|
args := getArgs()
|
|
|
|
|
|
|
|
if err := setupNamespace(args); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupNamespace(args *InitArgs) error {
|
|
|
|
if err := setupEnv(args); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2014-11-28 14:25:14 -05:00
|
|
|
|
2014-08-08 16:18:18 -04:00
|
|
|
if err := finalizeNamespace(args); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
path, err := exec.LookPath(args.Args[0])
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Unable to locate %v", args.Args[0])
|
|
|
|
os.Exit(127)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := syscall.Exec(path, args.Args, os.Environ()); err != nil {
|
|
|
|
return fmt.Errorf("dockerinit unable to execute %s - %s", path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getArgs() *InitArgs {
|
|
|
|
var (
|
|
|
|
// Get cmdline arguments
|
|
|
|
user = flag.String("u", "", "username or uid")
|
|
|
|
gateway = flag.String("g", "", "gateway address")
|
|
|
|
ip = flag.String("i", "", "ip address")
|
|
|
|
workDir = flag.String("w", "", "workdir")
|
|
|
|
privileged = flag.Bool("privileged", false, "privileged mode")
|
|
|
|
mtu = flag.Int("mtu", 1500, "interface mtu")
|
|
|
|
capAdd = flag.String("cap-add", "", "capabilities to add")
|
|
|
|
capDrop = flag.String("cap-drop", "", "capabilities to drop")
|
|
|
|
)
|
|
|
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
return &InitArgs{
|
|
|
|
User: *user,
|
|
|
|
Gateway: *gateway,
|
|
|
|
Ip: *ip,
|
|
|
|
WorkDir: *workDir,
|
|
|
|
Privileged: *privileged,
|
|
|
|
Args: flag.Args(),
|
|
|
|
Mtu: *mtu,
|
|
|
|
CapAdd: *capAdd,
|
|
|
|
CapDrop: *capDrop,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-03 13:19:00 -05:00
|
|
|
// Clear environment pollution introduced by lxc-start
|
2014-08-08 16:18:18 -04:00
|
|
|
func setupEnv(args *InitArgs) error {
|
2014-03-03 13:19:00 -05:00
|
|
|
// Get env
|
|
|
|
var env []string
|
|
|
|
content, err := ioutil.ReadFile(".dockerenv")
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to load environment variables: %v", err)
|
|
|
|
}
|
|
|
|
if err := json.Unmarshal(content, &env); err != nil {
|
|
|
|
return fmt.Errorf("Unable to unmarshal environment variables: %v", err)
|
|
|
|
}
|
|
|
|
// Propagate the plugin-specific container env variable
|
|
|
|
env = append(env, "container="+os.Getenv("container"))
|
|
|
|
|
|
|
|
args.Env = env
|
|
|
|
|
|
|
|
os.Clearenv()
|
|
|
|
for _, kv := range args.Env {
|
|
|
|
parts := strings.SplitN(kv, "=", 2)
|
|
|
|
if len(parts) == 1 {
|
|
|
|
parts = append(parts, "")
|
|
|
|
}
|
|
|
|
os.Setenv(parts[0], parts[1])
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-13 21:36:59 -05:00
|
|
|
// Setup working directory
|
2014-08-08 16:18:18 -04:00
|
|
|
func setupWorkingDirectory(args *InitArgs) error {
|
2014-01-13 21:36:59 -05:00
|
|
|
if args.WorkDir == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if err := syscall.Chdir(args.WorkDir); err != nil {
|
|
|
|
return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-08 16:18:18 -04:00
|
|
|
func getEnv(args *InitArgs, key string) string {
|
2014-01-13 21:36:59 -05:00
|
|
|
for _, kv := range args.Env {
|
|
|
|
parts := strings.SplitN(kv, "=", 2)
|
|
|
|
if parts[0] == key && len(parts) == 2 {
|
|
|
|
return parts[1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|