func toMountPoints(mounts []dockertypes.MountPoint) ([]*pouchtypes.MountPoint, error) {
	pouchMounts := []*pouchtypes.MountPoint{}
	for _, m := range mounts {
		mount := &pouchtypes.MountPoint{
			Name:        m.Name,
			Source:      m.Source,
			Destination: m.Destination,
			Driver:      m.Driver,
			Mode:        m.Mode,
			RW:          m.RW,
			Propagation: string(m.Propagation),
		}
		if utils.StringInSlice([]string{"alilocal", "ultron"}, mount.Driver) {
			mount.Named = true
		}
		pouchMounts = append(pouchMounts, mount)
	}
	return pouchMounts, nil
}
toMountPoints takeover all mounts information of container
package convertor
import (
	"fmt"
	"strings"
	"time"
	localtypes "github.com/pouchcontainer/d2p-migrator/pouch/types"
	"github.com/pouchcontainer/d2p-migrator/utils"
	pouchtypes "github.com/alibaba/pouch/apis/types"
	"github.com/alibaba/pouch/cri/annotations"
	dockertypes "github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/blkiodev"
	containertypes "github.com/docker/engine-api/types/container"
	networktypes "github.com/docker/engine-api/types/network"
	"github.com/docker/go-connections/nat"
	"github.com/go-openapi/strfmt"
)
func ToPouchContainerMeta(meta *dockertypes.ContainerJSON) (*localtypes.Container, error) {
	if meta == nil {
		return nil, nil
	}
	pouchMeta := &localtypes.Container{
		AppArmorProfile: meta.AppArmorProfile,
		Args:            meta.Args,
		Created:         convertTime(meta.Created),
		Driver:         meta.Driver,
		HostnamePath:   meta.HostnamePath,
		HostsPath:      meta.HostsPath,
		ResolvConfPath: meta.ResolvConfPath,
		ID:             meta.ID,
		Image:          meta.Image,
		LogPath:        meta.LogPath,
		MountLabel:     meta.MountLabel,
		Path:           meta.Path,
		ProcessLabel:   meta.ProcessLabel,
		RestartCount:   int64(meta.RestartCount),
		RootFSProvided: true,
	}
	pouchMeta.Name = strings.TrimPrefix(meta.Name, "/")
	pouchMeta.BaseFS = meta.GraphDriver.Data["MergedDir"]
	if meta.SizeRootFs != nil {
		pouchMeta.SizeRootFs = *meta.SizeRootFs
	}
	if meta.SizeRw != nil {
		pouchMeta.SizeRw = *meta.SizeRw
	}
	pouchMeta.Snapshotter = &pouchtypes.SnapshotterData{
		Name: "overlayfs",
		Data: meta.GraphDriver.Data,
	}
	pouchMeta.State = &pouchtypes.ContainerState{
		Dead:       meta.State.Dead,
		Error:      meta.State.Error,
		ExitCode:   int64(meta.State.ExitCode),
		FinishedAt: convertTime(meta.State.FinishedAt),
		OOMKilled:  false,
		Paused:     meta.State.Paused,
		Pid:        int64(meta.State.Pid),
		Restarting: false,
		Running:    meta.State.Running,
		StartedAt:  convertTime(meta.State.StartedAt),
		Status:     toContainerStatus(meta.State.Status),
	}
	config, err := toContainerConfig(meta.Config)
	if err != nil || config == nil {
		if err == nil {
			err = fmt.Errorf("got an empty ContainerConfig")
		}
		return nil, err
	}
	if SandboxNameRegex.Match([]byte(pouchMeta.Name)) {
		config.Labels[PouchContainerTypeLabelKey] = PouchContainerTypeLabelSandbox
	}
	containerType, ok := config.Labels[DockerContainerTypeLabelKey]
	if ok && containerType == PouchContainerTypeLabelContainer {
		config.Labels[PouchContainerTypeLabelKey] = PouchContainerTypeLabelContainer
		if config.SpecAnnotation == nil {
			config.SpecAnnotation = map[string]string{}
			config.SpecAnnotation[annotations.ContainerType] = annotations.ContainerTypeContainer
		}
		if v, ok := config.Labels[SandboxIDLabelKey]; ok {
			config.SpecAnnotation[annotations.SandboxName] = v
			config.SpecAnnotation[annotations.SandboxID] = v
		}
	}
	pouchMeta.Config = config
	envs, err := parseEnv(config.Env)
	if err != nil {
		return nil, err
	}
	if mode, exists := envs["ali_run_mode"]; exists {
		if mode != "vm" {
			oldRunMode := fmt.Sprintf("ali_run_mode=%s", mode)
			newRunMode := "ali_run_mode=vm"
			for i, v := range config.Env {
				if v == oldRunMode {
					config.Env[i] = newRunMode
					break
				}
			}
		}
	}
	hostconfig, err := toHostConfig(meta.HostConfig)
	if err != nil {
		return nil, err
	}
	if hostconfig.LogConfig.LogDriver == "" && pouchMeta.LogPath != "" {
		hostconfig.LogConfig.LogDriver = "json-file"
	}
	mountPoints, err := toMountPoints(meta.Mounts)
	if err != nil {
		return nil, err
	}
	pouchMeta.Mounts = mountPoints
	ldBind := ""
	if path, exists := envs["LD_PRELOAD"]; exists {
		if path != "" {
			ldBind = fmt.Sprintf("%s:%s:ro", path, path)
		}
	}
	if ldBind != "" && !utils.StringInSlice(hostconfig.Binds, ldBind) {
		hostconfig.Binds = append(hostconfig.Binds, ldBind)
	}
	pouchMeta.HostConfig = hostconfig
	networks, err := toNetworkSettings(meta.NetworkSettings)
	if err != nil {
		return nil, err
	}
	pouchMeta.NetworkSettings = networks
	return pouchMeta, nil
}
func toContainerStatus(status string) pouchtypes.Status {
	var containerStatus pouchtypes.Status
	switch status {
	case "running":
		containerStatus = pouchtypes.StatusRunning
	case "exited":
		containerStatus = pouchtypes.StatusStopped
	case "created":
		containerStatus = pouchtypes.StatusCreated
	case "paused":
		containerStatus = pouchtypes.StatusPaused
	case "dead":
		containerStatus = pouchtypes.StatusDead
	}
	return containerStatus
}
func toContainerConfig(config *containertypes.Config) (*pouchtypes.ContainerConfig, error) {
	if config == nil {
		return nil, nil
	}
	pouchConfig := &pouchtypes.ContainerConfig{
		Hostname:        strfmt.Hostname(config.Hostname),
		Domainname:      config.Domainname,
		User:            config.User,
		AttachStdin:     config.AttachStdin,
		AttachStdout:    config.AttachStdout,
		AttachStderr:    config.AttachStderr,
		Tty:             config.Tty,
		Cmd:             []string(config.Cmd),
		Entrypoint:      []string(config.Entrypoint),
		Env:             config.Env,
		Image:           config.Image,
		Labels:          config.Labels,
		MacAddress:      config.MacAddress,
		NetworkDisabled: config.NetworkDisabled,
		OnBuild:         config.OnBuild,
		OpenStdin:       config.OpenStdin,
		Shell:           []string(config.Shell),
		StopSignal:      config.StopSignal,
		WorkingDir:      config.WorkingDir,
	}
	volumes := map[string]interface{}{}
	for vol := range config.Volumes {
		volumes[vol] = struct{}{}
	}
	pouchConfig.Volumes = volumes
	if pouchConfig.Labels == nil {
		pouchConfig.Labels = map[string]string{}
	}
	if v, exists := pouchConfig.Labels["QuotaId"]; exists {
		pouchConfig.QuotaID = v
	}
	return pouchConfig, nil
}
func toHostConfig(hostconfig *containertypes.HostConfig) (*pouchtypes.HostConfig, error) {
	if hostconfig == nil {
		return nil, nil
	}
	pouchHostConfig := &pouchtypes.HostConfig{
		AutoRemove: hostconfig.AutoRemove,
		CapAdd:     []string(hostconfig.CapAdd),
		CapDrop:    []string(hostconfig.CapDrop),
		Cgroup:     string(hostconfig.Cgroup),
		ContainerIDFile: hostconfig.ContainerIDFile,
		DNS:             hostconfig.DNS,
		DNSOptions:      hostconfig.DNSOptions,
		DNSSearch:       hostconfig.DNSSearch,
		ExtraHosts: hostconfig.ExtraHosts,
		GroupAdd:   hostconfig.GroupAdd,
		IpcMode:   string(hostconfig.IpcMode),
		Isolation: string(hostconfig.Isolation),
		Links:     hostconfig.Links,
		LogConfig: &pouchtypes.LogConfig{
			LogDriver: hostconfig.LogConfig.Type,
			LogOpts:   hostconfig.LogConfig.Config,
		},
		NetworkMode: string(hostconfig.NetworkMode),
		OomScoreAdj: int64(hostconfig.OomScoreAdj),
		PidMode:     string(hostconfig.PidMode),
		Privileged:      hostconfig.Privileged,
		PublishAllPorts: hostconfig.PublishAllPorts,
		ReadonlyRootfs:  hostconfig.ReadonlyRootfs,
		Runtime:      "runc",
		SecurityOpt:  hostconfig.SecurityOpt,
		ShmSize:      &hostconfig.ShmSize,
		StorageOpt:   hostconfig.StorageOpt,
		Sysctls:      hostconfig.Sysctls,
		Tmpfs:        hostconfig.Tmpfs,
		UTSMode:      string(hostconfig.UTSMode),
		VolumeDriver: hostconfig.VolumeDriver,
		VolumesFrom:  nil,
		Binds:        hostconfig.Binds,
	}
	for _, cap := range []string{"SYS_RESOURCE", "SYS_MODULE", "SYS_PTRACE", "SYS_PACCT", "NET_ADMIN", "SYS_ADMIN"} {
		if utils.StringInSlice(pouchHostConfig.CapAdd, cap) {
			continue
		}
		pouchHostConfig.CapAdd = append(pouchHostConfig.CapAdd, cap)
	}
	pouchHostConfig.RestartPolicy = &pouchtypes.RestartPolicy{
		Name:              hostconfig.RestartPolicy.Name,
		MaximumRetryCount: int64(hostconfig.RestartPolicy.MaximumRetryCount),
	}
	resources, err := toResources(hostconfig.Resources)
	if err != nil {
		return nil, err
	}
	pouchHostConfig.Resources = resources
	return pouchHostConfig, nil
}
func toResources(resources containertypes.Resources) (pouchtypes.Resources, error) {
	weightDevs, err := toWeightDevice(resources.BlkioWeightDevice)
	if err != nil {
		return pouchtypes.Resources{}, fmt.Errorf("failed to convert WeightDevices: %v", err)
	}
	pouchBlkDevs := [][]*pouchtypes.ThrottleDevice{}
	for _, devs := range [][]*blkiodev.ThrottleDevice{
		resources.BlkioDeviceReadBps,
		resources.BlkioDeviceReadIOps,
		resources.BlkioDeviceWriteBps,
		resources.BlkioDeviceWriteIOps,
	} {
		convertBlkDevs, err := toThrottleDevices(devs)
		if err != nil {
			return pouchtypes.Resources{}, fmt.Errorf("failed to convert ThrottleDevices: %v", err)
		}
		pouchBlkDevs = append(pouchBlkDevs, convertBlkDevs)
	}
	pouchDevices, err := toDevices(resources.Devices)
	if err != nil {
		return pouchtypes.Resources{}, fmt.Errorf("failed to convert Devices: %v", err)
	}
	var ulimits []*pouchtypes.Ulimit
	if resources.Ulimits != nil {
		for _, u := range resources.Ulimits {
			ulimit := &pouchtypes.Ulimit{
				Hard: u.Hard,
				Name: u.Name,
				Soft: u.Soft,
			}
			ulimits = append(ulimits, ulimit)
		}
	}
	pouchResources := pouchtypes.Resources{
		BlkioDeviceReadBps:   pouchBlkDevs[0],
		BlkioDeviceReadIOps:  pouchBlkDevs[1],
		BlkioDeviceWriteBps:  pouchBlkDevs[2],
		BlkioDeviceWriteIOps: pouchBlkDevs[3],
		BlkioWeight:          resources.BlkioWeight,
		BlkioWeightDevice:    weightDevs,
		CgroupParent:         resources.CgroupParent,
		CPUCount:             resources.CPUCount,
		CPUPercent:           resources.CPUPercent,
		CPUPeriod:            resources.CPUPeriod,
		CPUQuota:             resources.CPUQuota,
		CPUShares:  resources.CPUShares,
		CpusetCpus: resources.CpusetCpus,
		CpusetMems: resources.CpusetMems,
		Devices:            pouchDevices,
		IOMaximumIOps:      resources.IOMaximumIOps,
		IOMaximumBandwidth: resources.IOMaximumBandwidth,
		KernelMemory:      resources.KernelMemory,
		Memory:            resources.Memory,
		MemoryReservation: resources.MemoryReservation,
		MemorySwap:        resources.MemorySwap,
		MemorySwappiness:  resources.MemorySwappiness,
		OomKillDisable: resources.OomKillDisable,
		PidsLimit:      resources.PidsLimit,
		Ulimits:        ulimits,
	}
	return pouchResources, nil
}
func toDevices(devs []containertypes.DeviceMapping) ([]*pouchtypes.DeviceMapping, error) {
	pouchDevices := []*pouchtypes.DeviceMapping{}
	for _, d := range devs {
		dev := &pouchtypes.DeviceMapping{
			CgroupPermissions: d.CgroupPermissions,
			PathInContainer:   d.PathInContainer,
			PathOnHost:        d.PathOnHost,
		}
		pouchDevices = append(pouchDevices, dev)
	}
	return pouchDevices, nil
}