Exemplo n.º 1
0
Arquivo: init.go Projeto: drptbl/oz
func parseArgs() *initState {
	log := createLogger()

	if os.Getuid() != 0 {
		log.Error("oz-init must run as root\n")
		os.Exit(1)
	}

	if os.Getpid() != 1 {
		log.Error("oz-init must be launched in new pid namespace.")
		os.Exit(1)
	}

	getvar := func(name string) string {
		val := os.Getenv(name)
		if val == "" {
			log.Error("Error: missing required '%s' argument", name)
			os.Exit(1)
		}
		return val
	}
	pname := getvar("INIT_PROFILE")
	sockaddr := getvar("INIT_SOCKET")
	uidval := getvar("INIT_UID")
	dispval := os.Getenv("INIT_DISPLAY")

	stnip := os.Getenv("INIT_ADDR")
	stnvhost := os.Getenv("INIT_VHOST")
	stnvguest := os.Getenv("INIT_VGUEST")
	stngateway := os.Getenv("INIT_GATEWAY")

	var config *oz.Config
	config, err := oz.LoadConfig(oz.DefaultConfigPath)
	if err != nil {
		if os.IsNotExist(err) {
			log.Info("Configuration file (%s) is missing, using defaults.", oz.DefaultConfigPath)
			config = oz.NewDefaultConfig()
		} else {
			log.Error("Could not load configuration: %s", oz.DefaultConfigPath, err)
			os.Exit(1)
		}
	}

	p, err := loadProfile(config.ProfileDir, pname)
	if err != nil {
		log.Error("Could not load profile %s: %v", pname, err)
		os.Exit(1)
	}
	uid, err := strconv.Atoi(uidval)
	if err != nil {
		log.Error("Could not parse INIT_UID argument (%s) into an integer: %v", uidval, err)
		os.Exit(1)
	}
	u, err := user.LookupId(uidval)
	if err != nil {
		log.Error("Failed to look up user with uid=%s: %v", uidval, err)
		os.Exit(1)
	}
	gid, err := strconv.Atoi(u.Gid)
	if err != nil {
		log.Error("Failed to parse gid value (%s) from user struct: %v", u.Gid, err)
		os.Exit(1)
	}
	display := 0
	if dispval != "" {
		d, err := strconv.Atoi(dispval)
		if err != nil {
			log.Error("Unable to parse display (%s) into an integer: %v", dispval, err)
			os.Exit(1)
		}
		display = d
	}

	stn := new(network.SandboxNetwork)
	if stnip != "" {
		gateway, _, err := net.ParseCIDR(stngateway)
		if err != nil {
			log.Error("Unable to parse network configuration gateway (%s): %v", stngateway, err)
			os.Exit(1)
		}

		stn.Ip = stnip
		stn.VethHost = stnvhost
		stn.VethGuest = stnvguest
		stn.Gateway = gateway
	}

	env := []string{}
	for _, e := range os.Environ() {
		if strings.HasPrefix(e, EnvPrefix) {
			e = e[len(EnvPrefix):]
			log.Debug("Adding (%s) to launch environment", e)
			env = append(env, e)
		}
	}

	env = append(env, "PATH=/usr/bin:/bin")

	if p.XServer.Enabled {
		env = append(env, "DISPLAY=:"+strconv.Itoa(display))
	}

	return &initState{
		log:       log,
		config:    config,
		sockaddr:  sockaddr,
		launchEnv: env,
		profile:   p,
		children:  make(map[int]*exec.Cmd),
		uid:       uid,
		gid:       gid,
		user:      u,
		display:   display,
		fs:        fs.NewFilesystem(config, log),
		network:   stn,
	}
}