func (daemon *Daemon) ParsePod(mypod *hypervisor.Pod, userPod *pod.UserPod, vmId string) ([]*hypervisor.ContainerInfo, []*hypervisor.VolumeInfo, error) { var ( fstype string poolName string volPoolName string devPrefix string storageDriver string rootPath string devFullName string rootfs string uid string gid string err error sharedDir = path.Join(hypervisor.BaseDir, vmId, hypervisor.ShareDirTag) containerInfoList = []*hypervisor.ContainerInfo{} volumeInfoList = []*hypervisor.VolumeInfo{} cli = daemon.DockerCli ) storageDriver = daemon.Storage.StorageType if storageDriver == "devicemapper" { poolName = daemon.Storage.PoolName fstype = daemon.Storage.Fstype volPoolName = "hyper-volume-pool" devPrefix = poolName[:strings.Index(poolName, "-pool")] rootPath = "/var/lib/docker/devicemapper" rootfs = "/rootfs" } else if storageDriver == "aufs" { rootPath = daemon.Storage.RootPath fstype = daemon.Storage.Fstype rootfs = "" } else if storageDriver == "overlay" { rootPath = daemon.Storage.RootPath fstype = daemon.Storage.Fstype rootfs = "" } else if storageDriver == "vbox" { fstype = daemon.Storage.Fstype rootPath = daemon.Storage.RootPath rootfs = "/rootfs" _ = devPrefix _ = volPoolName _ = poolName } // Process the 'Files' section files := make(map[string](pod.UserFile)) for _, v := range userPod.Files { files[v.Name] = v } for i, c := range mypod.Containers { var jsonResponse *dockertypes.ContainerJSONRaw if jsonResponse, err = cli.GetContainerInfo(c.Id); err != nil { glog.Error("got error when get container Info ", err.Error()) return nil, nil, err } if c.Name == "" { c.Name = jsonResponse.Name } if c.Image == "" { c.Image = jsonResponse.Config.Image } if storageDriver == "devicemapper" { if err := dm.CreateNewDevice(c.Id, devPrefix, rootPath); err != nil { return nil, nil, err } devFullName, err = dm.MountContainerToSharedDir(c.Id, sharedDir, devPrefix) if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, nil, err } fstype, err = dm.ProbeFsType(devFullName) if err != nil { fstype = "ext4" } } else if storageDriver == "aufs" { devFullName, err = aufs.MountContainerToSharedDir(c.Id, rootPath, sharedDir, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, nil, err } devFullName = "/" + c.Id + "/rootfs" } else if storageDriver == "overlay" { devFullName, err = overlay.MountContainerToSharedDir(c.Id, rootPath, sharedDir, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, nil, err } devFullName = "/" + c.Id + "/rootfs" } else if storageDriver == "vbox" { devFullName, err = vbox.MountContainerToSharedDir(c.Id, rootPath, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, nil, err } fstype = "ext4" } for _, f := range userPod.Containers[i].Files { targetPath := f.Path file, ok := files[f.Filename] if !ok { continue } var fromFile = "/tmp/" + file.Name defer os.RemoveAll(fromFile) if file.Uri != "" { err = utils.DownloadFile(file.Uri, fromFile) if err != nil { return nil, nil, err } } else if file.Contents != "" { err = ioutil.WriteFile(fromFile, []byte(file.Contents), 0666) if err != nil { return nil, nil, err } } else { continue } // we need to decode the content fi, err := os.Open(fromFile) if err != nil { return nil, nil, err } defer fi.Close() fileContent, err := ioutil.ReadAll(fi) if err != nil { return nil, nil, err } if file.Encoding == "base64" { newContent, err := utils.Base64Decode(string(fileContent)) if err != nil { return nil, nil, err } err = ioutil.WriteFile(fromFile, []byte(newContent), 0666) if err != nil { return nil, nil, err } } else { err = ioutil.WriteFile(fromFile, []byte(file.Contents), 0666) if err != nil { return nil, nil, err } } // get the uid and gid for that attached file fileUser := f.User fileGroup := f.Group u, _ := user.Current() if fileUser == "" { uid = u.Uid } else { u, _ = user.Lookup(fileUser) uid = u.Uid gid = u.Gid } if fileGroup == "" { gid = u.Gid } if storageDriver == "devicemapper" { err := dm.AttachFiles(c.Id, devPrefix, fromFile, targetPath, rootPath, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, nil, err } } else if storageDriver == "aufs" { err := aufs.AttachFiles(c.Id, fromFile, targetPath, sharedDir, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, nil, err } } else if storageDriver == "overlay" { err := overlay.AttachFiles(c.Id, fromFile, targetPath, sharedDir, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, nil, err } } } env := make(map[string]string) for _, v := range jsonResponse.Config.Env { env[v[:strings.Index(v, "=")]] = v[strings.Index(v, "=")+1:] } for _, e := range userPod.Containers[i].Envs { env[e.Env] = e.Value } glog.V(1).Infof("Parsing envs for container %d: %d Evs", i, len(env)) glog.V(1).Infof("The fs type is %s", fstype) glog.V(1).Infof("WorkingDir is %s", string(jsonResponse.Config.WorkingDir)) glog.V(1).Infof("Image is %s", string(devFullName)) containerInfo := &hypervisor.ContainerInfo{ Id: c.Id, Rootfs: rootfs, Image: devFullName, Fstype: fstype, Workdir: jsonResponse.Config.WorkingDir, Entrypoint: jsonResponse.Config.Entrypoint.Slice(), Cmd: jsonResponse.Config.Cmd.Slice(), Envs: env, } glog.V(1).Infof("Container Info is \n%v", containerInfo) containerInfoList = append(containerInfoList, containerInfo) glog.V(1).Infof("container %d created %s, workdir %s, env: %v", i, c.Id, jsonResponse.Config.WorkingDir, env) } // Process the 'Volumes' section for _, v := range userPod.Volumes { if v.Source == "" { if storageDriver == "devicemapper" { volName := fmt.Sprintf("%s-%s-%s", volPoolName, mypod.Id, v.Name) dev_id, _ := daemon.GetVolumeId(mypod.Id, volName) glog.Error("DeviceID is %d", dev_id) if dev_id < 1 { dev_id, _ = daemon.GetMaxDeviceId() err := daemon.CreateVolume(mypod.Id, volName, fmt.Sprintf("%d", dev_id+1), false) if err != nil { return nil, nil, err } } else { err := daemon.CreateVolume(mypod.Id, volName, fmt.Sprintf("%d", dev_id), true) if err != nil { return nil, nil, err } } fstype, err = dm.ProbeFsType("/dev/mapper/" + volName) if err != nil { fstype = "ext4" } myVol := &hypervisor.VolumeInfo{ Name: v.Name, Filepath: path.Join("/dev/mapper/", volName), Fstype: fstype, Format: "raw", } volumeInfoList = append(volumeInfoList, myVol) glog.V(1).Infof("volume %s created with dm as %s", v.Name, volName) continue } else { // Make sure the v.Name is given v.Source = path.Join("/var/tmp/hyper/", v.Name) if _, err := os.Stat(v.Source); err != nil && os.IsNotExist(err) { if err := os.MkdirAll(v.Source, os.FileMode(0777)); err != nil { return nil, nil, err } } v.Driver = "vfs" } } if v.Driver != "vfs" { glog.V(1).Infof("bypass %s volume %s", v.Driver, v.Name) continue } // Process the situation if the source is not NULL, we need to bind that dir to sharedDir var flags uintptr = utils.MS_BIND mountSharedDir := pod.RandStr(10, "alpha") targetDir := path.Join(sharedDir, mountSharedDir) glog.V(1).Infof("trying to bind dir %s to %s", v.Source, targetDir) if runtime.GOOS == "linux" { if err := os.MkdirAll(targetDir, 0755); err != nil && !os.IsExist(err) { glog.Errorf("error to create dir %s for volume %s", targetDir, v.Name) return nil, nil, err } } if err := utils.Mount(v.Source, targetDir, "dir", flags, "--bind"); err != nil { glog.Errorf("bind dir %s failed: %s", v.Source, err.Error()) return nil, nil, err } myVol := &hypervisor.VolumeInfo{ Name: v.Name, Filepath: mountSharedDir, Fstype: "dir", Format: "", } glog.V(1).Infof("dir %s is bound to %s", v.Source, targetDir) volumeInfoList = append(volumeInfoList, myVol) } return containerInfoList, volumeInfoList, nil }
func (daemon *Daemon) PrepareContainer(mypod *hypervisor.Pod, userPod *pod.UserPod, vmId string) ([]*hypervisor.ContainerInfo, error) { var ( fstype string poolName string volPoolName string devPrefix string rootPath string devFullName string rootfs string uid string gid string err error sharedDir = path.Join(hypervisor.BaseDir, vmId, hypervisor.ShareDirTag) containerInfoList = []*hypervisor.ContainerInfo{} storageDriver = daemon.Storage.StorageType cli = daemon.DockerCli ) if storageDriver == "devicemapper" { poolName = daemon.Storage.PoolName fstype = daemon.Storage.Fstype volPoolName = "hyper-volume-pool" devPrefix = poolName[:strings.Index(poolName, "-pool")] rootPath = "/var/lib/docker/devicemapper" rootfs = "/rootfs" } else if storageDriver == "aufs" { rootPath = daemon.Storage.RootPath fstype = daemon.Storage.Fstype rootfs = "" } else if storageDriver == "overlay" { rootPath = daemon.Storage.RootPath fstype = daemon.Storage.Fstype rootfs = "" } else if storageDriver == "vbox" { fstype = daemon.Storage.Fstype rootPath = daemon.Storage.RootPath rootfs = "/rootfs" _ = devPrefix _ = volPoolName _ = poolName } // Process the 'Files' section files := make(map[string](pod.UserFile)) for _, v := range userPod.Files { files[v.Name] = v } for i, c := range mypod.Containers { var jsonResponse *dockertypes.ContainerJSONRaw if jsonResponse, err = cli.GetContainerInfo(c.Id); err != nil { glog.Error("got error when get container Info ", err.Error()) return nil, err } if c.Name == "" { c.Name = jsonResponse.Name } if c.Image == "" { c.Image = jsonResponse.Config.Image } if storageDriver == "devicemapper" { if err := dm.CreateNewDevice(c.Id, devPrefix, rootPath); err != nil { return nil, err } devFullName, err = dm.MountContainerToSharedDir(c.Id, sharedDir, devPrefix) if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, err } fstype, err = dm.ProbeFsType(devFullName) if err != nil { fstype = "ext4" } } else if storageDriver == "aufs" { devFullName, err = aufs.MountContainerToSharedDir(c.Id, rootPath, sharedDir, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, err } devFullName = "/" + c.Id + "/rootfs" } else if storageDriver == "overlay" { devFullName, err = overlay.MountContainerToSharedDir(c.Id, rootPath, sharedDir, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, err } devFullName = "/" + c.Id + "/rootfs" } else if storageDriver == "vbox" { devFullName, err = vbox.MountContainerToSharedDir(c.Id, rootPath, "") if err != nil { glog.Error("got error when mount container to share dir ", err.Error()) return nil, err } fstype = "ext4" } for _, f := range userPod.Containers[i].Files { targetPath := f.Path file, ok := files[f.Filename] if !ok { continue } var fromFile = "/tmp/" + file.Name defer os.RemoveAll(fromFile) if file.Uri != "" { err = utils.DownloadFile(file.Uri, fromFile) if err != nil { return nil, err } } else if file.Contents != "" { err = ioutil.WriteFile(fromFile, []byte(file.Contents), 0666) if err != nil { return nil, err } } else { continue } // we need to decode the content fi, err := os.Open(fromFile) if err != nil { return nil, err } defer fi.Close() fileContent, err := ioutil.ReadAll(fi) if err != nil { return nil, err } if file.Encoding == "base64" { newContent, err := utils.Base64Decode(string(fileContent)) if err != nil { return nil, err } err = ioutil.WriteFile(fromFile, []byte(newContent), 0666) if err != nil { return nil, err } } else { err = ioutil.WriteFile(fromFile, []byte(file.Contents), 0666) if err != nil { return nil, err } } // get the uid and gid for that attached file fileUser := f.User fileGroup := f.Group u, _ := user.Current() if fileUser == "" { uid = u.Uid } else { u, _ = user.Lookup(fileUser) uid = u.Uid gid = u.Gid } if fileGroup == "" { gid = u.Gid } if storageDriver == "devicemapper" { err := dm.AttachFiles(c.Id, devPrefix, fromFile, targetPath, rootPath, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, err } } else if storageDriver == "aufs" { err := aufs.AttachFiles(c.Id, fromFile, targetPath, sharedDir, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, err } } else if storageDriver == "overlay" { err := overlay.AttachFiles(c.Id, fromFile, targetPath, sharedDir, f.Perm, uid, gid) if err != nil { glog.Error("got error when attach files ", err.Error()) return nil, err } } } env := make(map[string]string) for _, v := range jsonResponse.Config.Env { env[v[:strings.Index(v, "=")]] = v[strings.Index(v, "=")+1:] } for _, e := range userPod.Containers[i].Envs { env[e.Env] = e.Value } glog.V(1).Infof("Parsing envs for container %d: %d Evs", i, len(env)) glog.V(1).Infof("The fs type is %s", fstype) glog.V(1).Infof("WorkingDir is %s", string(jsonResponse.Config.WorkingDir)) glog.V(1).Infof("Image is %s", string(devFullName)) containerInfo := &hypervisor.ContainerInfo{ Id: c.Id, Rootfs: rootfs, Image: devFullName, Fstype: fstype, Workdir: jsonResponse.Config.WorkingDir, Entrypoint: jsonResponse.Config.Entrypoint.Slice(), Cmd: jsonResponse.Config.Cmd.Slice(), Envs: env, } glog.V(1).Infof("Container Info is \n%v", containerInfo) containerInfoList = append(containerInfoList, containerInfo) glog.V(1).Infof("container %d created %s, workdir %s, env: %v", i, c.Id, jsonResponse.Config.WorkingDir, env) } return containerInfoList, nil }