Пример #1
0
func ProbeExistingVolume(v *pod.UserVolume, sharedDir string) (*hypervisor.VolumeInfo, error) {
	if v == nil || v.Source == "" { //do not create volume in this function, it depends on storage driver.
		return nil, fmt.Errorf("can not generate volume info from %v", v)
	}

	var err error = nil
	vol := &hypervisor.VolumeInfo{
		Name: v.Name,
	}

	if v.Driver == "vfs" {
		vol.Fstype = "dir"
		vol.Filepath, err = storage.MountVFSVolume(v.Source, sharedDir)
		if err != nil {
			return nil, err
		}
		glog.V(1).Infof("dir %s is bound to %s", v.Source, vol.Filepath)
	} else {
		vol.Fstype, err = dm.ProbeFsType(v.Source)
		if err != nil {
			vol.Fstype = DEFAULT_VOL_FS //FIXME: for qcow2, the ProbeFsType doesn't work, should be fix later
		}
		vol.Format = v.Driver
		vol.Filepath = v.Source
	}

	return vol, nil
}
Пример #2
0
func (dms *DevMapperStorage) PrepareContainer(id, sharedDir string) (*hypervisor.ContainerInfo, error) {
	if err := dm.CreateNewDevice(id, dms.DevPrefix, dms.RootPath()); err != nil {
		return nil, err
	}
	devFullName, err := dm.MountContainerToSharedDir(id, sharedDir, dms.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"
	}
	return &hypervisor.ContainerInfo{
		Id:     id,
		Rootfs: "/rootfs",
		Image:  devFullName,
		Fstype: fstype,
	}, nil
}
Пример #3
0
func (dms *DevMapperStorage) CreateVolume(daemon *Daemon, podId, shortName string) (*hypervisor.VolumeInfo, error) {
	volName := fmt.Sprintf("%s-%s-%s", dms.VolPoolName, podId, shortName)
	dev_id, _ := daemon.GetVolumeId(podId, volName)
	glog.Infof("DeviceID is %d", dev_id)

	restore := dev_id > 0

	for {
		if !restore {
			dev_id = dms.randDevId()
		}
		dev_id_str := strconv.Itoa(dev_id)

		err := dm.CreateVolume(dms.VolPoolName, volName, dev_id_str, DEFAULT_DM_VOL_SIZE, restore)
		if err != nil && !restore && strings.Contains(err.Error(), "failed: File exists") {
			glog.V(1).Infof("retry for dev_id #%d creating collision: %v", dev_id, err)
			continue
		} else if err != nil {
			glog.V(1).Infof("failed to create dev_id #%d: %v", dev_id, err)
			return nil, err
		}

		glog.V(3).Infof("device (%d) created (restore:%v) for %s: %s", dev_id, restore, podId, volName)
		daemon.SetVolumeId(podId, volName, dev_id_str)
		break
	}

	fstype, err := dm.ProbeFsType("/dev/mapper/" + volName)
	if err != nil {
		fstype = "ext4"
	}

	glog.V(1).Infof("volume %s created with dm as %s", shortName, volName)

	return &hypervisor.VolumeInfo{
		Name:     shortName,
		Filepath: path.Join("/dev/mapper/", volName),
		Fstype:   fstype,
		Format:   "raw",
	}, nil
}
Пример #4
0
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
}
Пример #5
0
func (daemon *Daemon) PrepareVolume(mypod *hypervisor.Pod, userPod *pod.UserPod,
	vmId string) ([]*hypervisor.VolumeInfo, error) {
	var (
		fstype         string
		volPoolName    string
		err            error
		sharedDir      = path.Join(hypervisor.BaseDir, vmId, hypervisor.ShareDirTag)
		volumeInfoList = []*hypervisor.VolumeInfo{}
	)

	// Process the 'Volumes' section
	for _, v := range userPod.Volumes {
		if v.Source == "" {
			if daemon.Storage.StorageType == "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, err
					}
				} else {
					err := daemon.CreateVolume(mypod.Id, volName, fmt.Sprintf("%d", dev_id), true)
					if err != nil {
						return 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, 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, 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, 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 volumeInfoList, nil
}
Пример #6
0
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
}
Пример #7
0
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
		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 = path.Join(utils.HYPER_ROOT, "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
			if strings.HasSuffix(targetPath, "/") {
				targetPath = targetPath + f.Filename
			}
			file, ok := files[f.Filename]
			if !ok {
				continue
			}

			var src io.Reader

			if file.Uri != "" {
				urisrc, err := utils.UriReader(file.Uri)
				if err != nil {
					return nil, err
				}
				defer urisrc.Close()
				src = urisrc
			} else {
				src = strings.NewReader(file.Contents)
			}

			switch file.Encoding {
			case "base64":
				src = base64.NewDecoder(base64.StdEncoding, src)
			default:
			}

			if storageDriver == "devicemapper" {
				err := dm.InjectFile(src, c.Id, devPrefix, targetPath, rootPath,
					utils.PermInt(f.Perm), utils.UidInt(f.User), utils.UidInt(f.Group))
				if err != nil {
					glog.Error("got error when inject files ", err.Error())
					return nil, err
				}
			} else if storageDriver == "aufs" || storageDriver == "overlay" {
				err := storage.FsInjectFile(src, c.Id, targetPath, sharedDir,
					utils.PermInt(f.Perm), utils.UidInt(f.User), utils.UidInt(f.Group))
				if err != nil {
					glog.Error("got error when inject 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
}
Пример #8
0
func (daemon *Daemon) PrepareContainer(mypod *hypervisor.PodStatus, userPod *pod.UserPod,
	vmId string) ([]*hypervisor.ContainerInfo, error) {
	var (
		fstype            string
		poolName          string
		volPoolName       string
		devPrefix         string
		rootPath          string
		devFullName       string
		rootfs            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 = path.Join(utils.HYPER_ROOT, "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"
		}

		err = processInjectFiles(&userPod.Containers[i], files, c.Id, storageDriver, devPrefix, rootPath, sharedDir)
		if err != nil {
			return nil, err
		}

		processImageVolumes(jsonResponse, c.Id, userPod, &userPod.Containers[i])

		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
}