예제 #1
0
파일: container.go 프로젝트: hyperhq/runv
func (c *Container) create(p *Process) error {
	// save the state

	glog.V(3).Infof("prepare hypervisor info")
	config := api.ContainerDescriptionFromOCF(c.Id, c.Spec)

	rootPath := c.Spec.Root.Path
	if !filepath.IsAbs(rootPath) {
		rootPath = filepath.Join(c.BundlePath, rootPath)
	}
	vmRootfs := filepath.Join(hypervisor.BaseDir, c.ownerPod.vm.Id, hypervisor.ShareDirTag, c.Id, "rootfs")
	os.MkdirAll(vmRootfs, 0755)

	// Mount rootfs
	err := utils.Mount(rootPath, vmRootfs)
	if err != nil {
		glog.Errorf("mount %s to %s failed: %s\n", rootPath, vmRootfs, err.Error())
		return err
	}

	// Pre-create dirs necessary for hyperstart before setting rootfs readonly
	// TODO: a better way to support readonly rootfs
	if err = preCreateDirs(rootPath); err != nil {
		return err
	}

	// Mount necessary files and directories from spec
	for _, m := range c.Spec.Mounts {
		if err := mountToRootfs(&m, vmRootfs, ""); err != nil {
			return fmt.Errorf("mounting %q to rootfs %q at %q failed: %v", m.Source, m.Destination, vmRootfs, err)
		}
	}

	// set rootfs readonly
	if c.Spec.Root.Readonly {
		err = utils.SetReadonly(vmRootfs)
		if err != nil {
			glog.Errorf("set rootfs %s readonly failed: %s\n", vmRootfs, err.Error())
			return err
		}
	}

	r := c.ownerPod.vm.AddContainer(config)
	if !r.IsSuccess() {
		return fmt.Errorf("add container %s failed: %s", c.Id, r.Message())
	}

	return nil
}
예제 #2
0
파일: container.go 프로젝트: feiskyer/runv
func (c *Container) start(p *Process) error {
	// save the state
	glog.V(3).Infof("save state id %s, boundle %s", c.Id, c.BundlePath)
	stateDir := filepath.Join(c.ownerPod.sv.StateDir, c.Id)
	_, err := os.Stat(stateDir)
	if err == nil {
		glog.V(1).Infof("Container %s exists\n", c.Id)
		return fmt.Errorf("Container %s exists\n", c.Id)
	}
	err = os.MkdirAll(stateDir, 0644)
	if err != nil {
		glog.V(1).Infof("%s\n", err.Error())
		return err
	}

	state := &specs.State{
		Version:    c.Spec.Version,
		ID:         c.Id,
		Pid:        c.ownerPod.getNsPid(),
		BundlePath: c.BundlePath,
	}
	stateData, err := json.MarshalIndent(state, "", "\t")
	if err != nil {
		glog.V(1).Infof("%s\n", err.Error())
		return err
	}
	stateFile := filepath.Join(stateDir, "state.json")
	err = ioutil.WriteFile(stateFile, stateData, 0644)
	if err != nil {
		glog.V(1).Infof("%s\n", err.Error())
		return err
	}

	glog.V(3).Infof("prepare hypervisor info")
	u := pod.ConvertOCF2UserContainer(c.Spec)
	if !filepath.IsAbs(u.Image) {
		u.Image = filepath.Join(c.BundlePath, u.Image)
	}
	vmRootfs := filepath.Join(hypervisor.BaseDir, c.ownerPod.vm.Id, hypervisor.ShareDirTag, c.Id, "rootfs")
	os.MkdirAll(vmRootfs, 0755)

	// Mount rootfs
	err = utils.Mount(u.Image, vmRootfs)
	if err != nil {
		glog.Errorf("mount %s to %s failed: %s\n", u.Image, vmRootfs, err.Error())
		return err
	}

	// Pre-create dirs necessary for hyperstart before setting rootfs readonly
	// TODO: a better way to support readonly rootfs
	if err = preCreateDirs(u.Image); err != nil {
		return err
	}

	// Mount necessary files and directories from spec
	for _, m := range c.Spec.Mounts {
		if err := mountToRootfs(&m, vmRootfs, ""); err != nil {
			return fmt.Errorf("mounting %q to rootfs %q at %q failed: %v", m.Source, vmRootfs, m.Destination, err)
		}
	}

	// set rootfs readonly
	if c.Spec.Root.Readonly {
		err = utils.SetReadonly(vmRootfs)
		if err != nil {
			glog.Errorf("set rootfs %s readonly failed: %s\n", vmRootfs, err.Error())
			return err
		}
	}

	envs := make(map[string]string)
	for _, env := range u.Envs {
		envs[env.Env] = env.Value
	}

	info := &hypervisor.ContainerInfo{
		Id:     c.Id,
		Rootfs: "rootfs",
		Image:  pod.UserVolume{Source: c.Id},
		Fstype: "dir",
		Cmd:    u.Command,
		Envs:   envs,
	}

	err = c.ownerPod.vm.Attach(p.stdio, c.Id, nil)
	if err != nil {
		glog.V(1).Infof("StartPod fail: fail to set up tty connection.\n")
		return err
	}

	err = execPrestartHooks(c.Spec, state)
	if err != nil {
		glog.V(1).Infof("execute Prestart hooks failed, %s\n", err.Error())
		return err
	}

	err = c.ownerPod.initPodNetwork(c)
	if err != nil {
		glog.Errorf("fail to initialize pod network %v", err)
		return err
	}

	c.ownerPod.podStatus.AddContainer(c.Id, c.ownerPod.podStatus.Id, "", []string{}, types.S_POD_CREATED)
	return c.ownerPod.vm.NewContainer(u, info)
}