123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package lxc
- import (
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "os/exec"
- "runtime"
- "strings"
- "syscall"
- "github.com/docker/docker/pkg/reexec"
- )
- // 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
- }
- 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,
- }
- }
- // Clear environment pollution introduced by lxc-start
- func setupEnv(args *InitArgs) error {
- // 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
- }
- // Setup working directory
- func setupWorkingDirectory(args *InitArgs) error {
- 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
- }
- func getEnv(args *InitArgs, key string) string {
- for _, kv := range args.Env {
- parts := strings.SplitN(kv, "=", 2)
- if parts[0] == key && len(parts) == 2 {
- return parts[1]
- }
- }
- return ""
- }
|