Example #1
0
// init prepares the LXContainer for this LXD Container
// TODO: This gets called on each load of the container,
//       we might be able to split this is up into c.Start().
func (c *containerLXD) init() error {
	templateConfBase := "ubuntu"
	templateConfDir := os.Getenv("LXC_TEMPLATE_CONFIG")
	if templateConfDir == "" {
		templateConfDir = "/usr/share/lxc/config"
	}

	cc, err := lxc.NewContainer(c.NameGet(), c.daemon.lxcpath)
	if err != nil {
		return err
	}
	c.c = cc

	logfile := c.LogFilePathGet()
	if err := os.MkdirAll(filepath.Dir(logfile), 0700); err != nil {
		return err
	}

	if err = c.c.SetLogFile(logfile); err != nil {
		return err
	}

	personality, err := shared.ArchitecturePersonality(c.architecture)
	if err == nil {
		if err := c.c.SetConfigItem("lxc.arch", personality); err != nil {
			return err
		}
	}

	err = c.c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.common.conf", templateConfDir, templateConfBase))
	if err != nil {
		return err
	}

	if !c.IsPrivileged() {
		err = c.c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.userns.conf", templateConfDir, templateConfBase))
		if err != nil {
			return err
		}
	}

	if err := c.c.SetConfigItem("lxc.rootfs", c.RootfsPathGet()); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.loglevel", "0"); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.utsname", c.NameGet()); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.tty", "0"); err != nil {
		return err
	}
	if err := setupDevLxdMount(c.c); err != nil {
		return err
	}

	/* apply profiles */
	for _, p := range c.profiles {
		if err := c.applyProfile(p); err != nil {
			return err
		}
	}

	if err := c.setupMacAddresses(); err != nil {
		return err
	}

	/* now add the lxc.* entries for the configured devices */
	if err := c.applyDevices(); err != nil {
		return err
	}

	if !c.IsPrivileged() {
		c.idmapset = c.daemon.IdmapSet // TODO - per-tenant idmaps
	}

	if err := c.mountShared(); err != nil {
		return err
	}

	if err := c.applyIdmapSet(); err != nil {
		return err
	}

	if err := c.applyConfig(c.config, false); err != nil {
		return err
	}

	return nil
}
Example #2
0
func newLxdContainer(name string, daemon *Daemon) (*lxdContainer, error) {
	d := &lxdContainer{
		daemon:       daemon,
		ephemeral:    false,
		architecture: -1,
		cType:        -1,
		id:           -1}

	ephemInt := -1

	templateConfBase := "ubuntu"
	templateConfDir := os.Getenv("LXC_TEMPLATE_CONFIG")
	if templateConfDir == "" {
		templateConfDir = "/usr/share/lxc/config"
	}

	q := "SELECT id, architecture, type, ephemeral FROM containers WHERE name=?"
	arg1 := []interface{}{name}
	arg2 := []interface{}{&d.id, &d.architecture, &d.cType, &ephemInt}
	err := dbQueryRowScan(daemon.db, q, arg1, arg2)
	if err != nil {
		return nil, err
	}
	if d.id == -1 {
		return nil, fmt.Errorf("Unknown container")
	}

	if ephemInt == 1 {
		d.ephemeral = true
	}

	c, err := lxc.NewContainer(name, daemon.lxcpath)
	if err != nil {
		return nil, err
	}
	d.c = c

	dir := shared.LogPath(c.Name())
	err = os.MkdirAll(dir, 0700)
	if err != nil {
		return nil, err
	}

	if err = d.c.SetLogFile(filepath.Join(dir, "lxc.log")); err != nil {
		return nil, err
	}

	personality, err := shared.ArchitecturePersonality(d.architecture)
	if err == nil {
		err = c.SetConfigItem("lxc.arch", personality)
		if err != nil {
			return nil, err
		}
	}

	err = c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.common.conf", templateConfDir, templateConfBase))
	if err != nil {
		return nil, err
	}

	if !d.isPrivileged() {
		err = c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.userns.conf", templateConfDir, templateConfBase))
		if err != nil {
			return nil, err
		}
	}

	config, err := dbGetConfig(daemon.db, d.id)
	if err != nil {
		return nil, err
	}
	d.config = config

	profiles, err := dbGetProfiles(daemon.db, d.id)
	if err != nil {
		return nil, err
	}
	d.profiles = profiles
	d.devices = shared.Devices{}
	d.name = name

	rootfsPath := shared.VarPath("lxc", name, "rootfs")
	err = c.SetConfigItem("lxc.rootfs", rootfsPath)
	if err != nil {
		return nil, err
	}
	err = c.SetConfigItem("lxc.loglevel", "0")
	if err != nil {
		return nil, err
	}
	err = c.SetConfigItem("lxc.utsname", name)
	if err != nil {
		return nil, err
	}
	err = c.SetConfigItem("lxc.tty", "0")
	if err != nil {
		return nil, err
	}

	if err := setupDevLxdMount(c); err != nil {
		return nil, err
	}

	/* apply profiles */
	for _, p := range profiles {
		err := applyProfile(daemon, d, p)
		if err != nil {
			return nil, err
		}
	}

	/* get container_devices */
	newdevs, err := dbGetDevices(daemon.db, d.name, false)
	if err != nil {
		return nil, err
	}

	for k, v := range newdevs {
		d.devices[k] = v
	}

	if err := d.setupMacAddresses(daemon); err != nil {
		return nil, err
	}

	/* now add the lxc.* entries for the configured devices */
	err = d.applyDevices()
	if err != nil {
		return nil, err
	}

	if !d.isPrivileged() {
		d.idmapset = daemon.IdmapSet // TODO - per-tenant idmaps
	}

	err = d.applyIdmapSet()
	if err != nil {
		return nil, err
	}

	err = d.applyConfig(d.config, false)
	if err != nil {
		return nil, err
	}

	return d, nil
}
Example #3
0
// init prepares the LXContainer for this LXD Container
// TODO: This gets called on each load of the container,
//       we might be able to split this is up into c.Start().
func (c *containerLXD) init() error {
	templateConfBase := "ubuntu"
	templateConfDir := os.Getenv("LXD_LXC_TEMPLATE_CONFIG")
	if templateConfDir == "" {
		templateConfDir = "/usr/share/lxc/config"
	}

	cc, err := lxc.NewContainer(c.NameGet(), c.daemon.lxcpath)
	if err != nil {
		return err
	}
	c.c = cc

	logfile := c.LogFilePathGet()
	if err := os.MkdirAll(filepath.Dir(logfile), 0700); err != nil {
		return err
	}

	if err = c.c.SetLogFile(logfile); err != nil {
		return err
	}

	personality, err := shared.ArchitecturePersonality(c.architecture)
	if err == nil {
		if err := c.c.SetConfigItem("lxc.arch", personality); err != nil {
			return err
		}
	}

	err = c.c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.common.conf", templateConfDir, templateConfBase))
	if err != nil {
		return err
	}

	if err := c.c.SetConfigItem("lxc.rootfs", c.RootfsPathGet()); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.loglevel", "0"); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.utsname", c.NameGet()); err != nil {
		return err
	}
	if err := c.c.SetConfigItem("lxc.tty", "0"); err != nil {
		return err
	}
	if err := setupDevLxdMount(c.c); err != nil {
		return err
	}

	for _, p := range c.profiles {
		if err := c.applyProfile(p); err != nil {
			return err
		}
	}

	// base per-container config should override profile config, so we apply it second
	if err := c.applyConfig(c.baseConfig); err != nil {
		return err
	}

	if !c.IsPrivileged() || runningInUserns {
		err = c.c.SetConfigItem("lxc.include", fmt.Sprintf("%s/%s.userns.conf", templateConfDir, templateConfBase))
		if err != nil {
			return err
		}
	}

	if c.IsNesting() {
		shared.Debugf("Setting up %s for nesting", c.name)
		orig := c.c.ConfigItem("lxc.mount.auto")
		auto := ""
		if len(orig) == 1 {
			auto = orig[0]
		}
		if !strings.Contains(auto, "cgroup") {
			auto = fmt.Sprintf("%s %s", auto, "cgroup:mixed")
			err = c.c.SetConfigItem("lxc.mount.auto", auto)
			if err != nil {
				return err
			}
		}
		/*
		 * mount extra /proc and /sys to work around kernel
		 * restrictions on remounting them when covered
		 */
		err = c.c.SetConfigItem("lxc.mount.entry", "proc dev/.lxc/proc proc create=dir,optional")
		if err != nil {
			return err
		}
		err = c.c.SetConfigItem("lxc.mount.entry", "sys dev/.lxc/sys sysfs create=dir,optional")
		if err != nil {
			return err
		}
	}

	/*
	 * Until stacked apparmor profiles are possible, we have to run nested
	 * containers unconfined
	 */
	if aaEnabled {
		if aaConfined() {
			curProfile := aaProfile()
			shared.Debugf("Running %s in current profile %s (nested container)", c.name, curProfile)
			curProfile = strings.TrimSuffix(curProfile, " (enforce)")
			if err := c.c.SetConfigItem("lxc.aa_profile", curProfile); err != nil {
				return err
			}
		} else if err := c.c.SetConfigItem("lxc.aa_profile", AAProfileName(c)); err != nil {
			return err
		}
	}

	if err := c.c.SetConfigItem("lxc.seccomp", SeccompProfilePath(c)); err != nil {
		return err
	}

	if err := c.setupMacAddresses(); err != nil {
		return err
	}

	// Allow overwrites of devices
	for k, v := range c.baseDevices {
		c.devices[k] = v
	}

	/* now add the lxc.* entries for the configured devices */
	if err := c.applyDevices(); err != nil {
		return err
	}

	if !c.IsPrivileged() {
		if c.daemon.IdmapSet == nil {
			return fmt.Errorf("user has no subuids")
		}
		c.idmapset = c.daemon.IdmapSet // TODO - per-tenant idmaps
	}

	if err := c.mountShared(); err != nil {
		return err
	}

	if err := c.applyIdmapSet(); err != nil {
		return err
	}

	if err := c.applyPostDeviceConfig(); err != nil {
		return err
	}

	return nil
}