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 }
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) }