feat(region,host): support post overlay uppper config (#24318)

This commit is contained in:
Zexi Li
2026-02-11 16:57:52 +08:00
committed by GitHub
parent 4ccb4147e9
commit cfaf88752a
5 changed files with 55 additions and 7 deletions
+19
View File
@@ -272,6 +272,22 @@ type ContainerVolumeMountDiskPostImageOverlay struct {
PathMap map[string]string `json:"path_map"`
// 宿主机底层目录映射, key 为 PathMap 的 key,value 为 overlay lower 格式,多目录以 ":" 分隔
HostLowerMap map[string]*HostLowerPath `json:"host_lower_map"`
UpperConfig *PostOverlayUpperConfig `json:"upper_config"`
}
type PostOverlayUpperConfigType string
const (
PostOverlayUpperConfigTypeDisk PostOverlayUpperConfigType = "disk"
)
type PostOverlayUpperConfigDisk struct {
SubPath string `json:"sub_path"`
}
type PostOverlayUpperConfig struct {
Type PostOverlayUpperConfigType `json:"type"`
Disk *PostOverlayUpperConfigDisk `json:"disk"`
}
type ContainerVolumeMountDiskPostImageOverlayUnpacker ContainerVolumeMountDiskPostImageOverlay
@@ -285,6 +301,7 @@ func (ov *ContainerVolumeMountDiskPostImageOverlay) UnmarshalJSON(data []byte) e
// 防止 PathMap 被合并,总是用 Unarmshal data 里面的 path_map
ov.PathMap = nov.PathMap
ov.HostLowerMap = nov.HostLowerMap
ov.UpperConfig = nov.UpperConfig
return nil
}
@@ -298,6 +315,8 @@ const (
type ContainerVolumeMountDiskPostOverlay struct {
// 宿主机底层目录
HostLowerDir []string `json:"host_lower_dir"`
// 宿主机上层目录
HostUpperDir string `json:"host_upper_dir"`
// 合并后要挂载到容器的目录
ContainerTargetDir string `json:"container_target_dir"`
Image *ContainerVolumeMountDiskPostImageOverlay `json:"image"`
@@ -50,7 +50,7 @@ type IVolumeMountDisk interface {
GetHostDiskRootPath(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount) (string, error)
GetPostOverlayRootWorkDir(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string) (string, error)
GetPostOverlayRootUpperDir(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string) (string, error)
GetPostOverlayRootUpperDir(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string, pov *apis.ContainerVolumeMountDiskPostOverlay) (string, error)
}
type disk struct {
@@ -60,7 +60,19 @@ func (d disk) GetPostOverlayRootWorkDir(pod volume_mount.IPodInfo, vm *hostapi.C
return d.getPostOverlayRootPrefixDir(POST_OVERLAY_PREFIX_WORK_DIR, pod, vm, ctrId)
}
func (d disk) GetPostOverlayRootUpperDir(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string) (string, error) {
func (d disk) GetPostOverlayRootUpperDir(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string, pov *apis.ContainerVolumeMountDiskPostOverlay) (string, error) {
if pov.Image != nil && pov.Image.UpperConfig != nil {
config := pov.Image.UpperConfig
if config.Disk.SubPath == "" {
return "", errors.Errorf("sub_path of upper config is empty")
}
hostPath, err := d.GetHostDiskRootPath(pod, vm)
if err != nil {
return "", errors.Wrap(err, "get host disk root path")
}
upperDir := filepath.Join(hostPath, vm.Disk.SubDirectory, config.Disk.SubPath)
return upperDir, nil
}
return d.getPostOverlayRootPrefixDir(POST_OVERLAY_PREFIX_UPPER_DIR, pod, vm, ctrId)
}
@@ -188,6 +200,9 @@ func (d diskPostOverlay) getPostOverlayUpperDir(
ov *apis.ContainerVolumeMountDiskPostOverlay,
ensure bool,
) (string, error) {
if ov.HostUpperDir != "" {
return ov.HostUpperDir, nil
}
return d.getPostOverlayDirWithPrefix(POST_OVERLAY_PREFIX_UPPER_DIR, pod, ctrId, vm, ov, ensure)
}
@@ -78,7 +78,7 @@ func parseColonSeparatedPaths(pathStr string) []string {
return paths
}
func (i postOverlayImage) convertToDiskOV(ov *apis.ContainerVolumeMountDiskPostOverlay, hostPath, ctrPath string, hostLowerPath *apis.HostLowerPath) *apis.ContainerVolumeMountDiskPostOverlay {
func (i postOverlayImage) convertToDiskOV(ov *apis.ContainerVolumeMountDiskPostOverlay, hostPath, ctrPath string, hostLowerPath *apis.HostLowerPath, hostUpperDir string) *apis.ContainerVolumeMountDiskPostOverlay {
hostLowerDir := []string{}
if hostLowerPath != nil {
// 添加 PrePath 中的路径
@@ -92,6 +92,7 @@ func (i postOverlayImage) convertToDiskOV(ov *apis.ContainerVolumeMountDiskPostO
}
return &apis.ContainerVolumeMountDiskPostOverlay{
HostLowerDir: hostLowerDir,
HostUpperDir: hostUpperDir,
ContainerTargetDir: ctrPath,
FsUser: ov.FsUser,
FsGroup: ov.FsGroup,
@@ -100,6 +101,7 @@ func (i postOverlayImage) convertToDiskOV(ov *apis.ContainerVolumeMountDiskPostO
}
func (i postOverlayImage) withAction(
vm *hostapi.ContainerVolumeMount,
d diskPostOverlay, pod volume_mount.IPodInfo, ov *apis.ContainerVolumeMountDiskPostOverlay,
af func(iDiskPostOverlayDriver, *apis.ContainerVolumeMountDiskPostOverlay) error,
accquire bool) error {
@@ -108,9 +110,21 @@ func (i postOverlayImage) withAction(
if err != nil {
return errors.Wrapf(err, "get cached image paths")
}
hostUpperDir := ""
if img.UpperConfig != nil {
config := img.UpperConfig
if config.Disk.SubPath == "" {
return errors.Errorf("sub_path of upper config is empty")
}
hostPath, err := d.disk.GetHostDiskRootPath(pod, vm)
if err != nil {
return errors.Wrap(err, "get host disk root path")
}
hostUpperDir = filepath.Join(hostPath, vm.Disk.SubDirectory, config.Disk.SubPath)
}
for hostPath, ctrPath := range paths {
hostLowerPath := hostLowerPaths[hostPath]
dov := i.convertToDiskOV(ov, hostPath, ctrPath, hostLowerPath)
dov := i.convertToDiskOV(ov, hostPath, ctrPath, hostLowerPath, hostUpperDir)
drv := d.getDriver(dov)
if err := af(drv, dov); err != nil {
return errors.Wrapf(err, "host path %s to %s", hostPath, ctrPath)
@@ -120,14 +134,14 @@ func (i postOverlayImage) withAction(
}
func (i postOverlayImage) Mount(d diskPostOverlay, pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ov *apis.ContainerVolumeMountDiskPostOverlay) error {
return i.withAction(d, pod, ov,
return i.withAction(vm, d, pod, ov,
func(driver iDiskPostOverlayDriver, dov *apis.ContainerVolumeMountDiskPostOverlay) error {
return driver.Mount(d, pod, ctrId, vm, dov)
}, true)
}
func (i postOverlayImage) Unmount(d diskPostOverlay, pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ov *apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, clearLayers bool) error {
return i.withAction(d, pod, ov,
return i.withAction(vm, d, pod, ov,
func(driver iDiskPostOverlayDriver, dov *apis.ContainerVolumeMountDiskPostOverlay) error {
return driver.Unmount(d, pod, ctrId, vm, dov, useLazy, clearLayers)
}, false)
+1 -1
View File
@@ -2827,7 +2827,7 @@ func (s *sPodGuestInstance) DoSnapshot(ctx context.Context, params *SDiskSnapsho
diskDrv := drv.(disk.IVolumeMountDisk)
for _, pov := range vol.Disk.PostOverlay {
// bind mount post overlay dirs to tmpBackRootDir
upperDir, err := diskDrv.GetPostOverlayRootUpperDir(s, vol, input.ContainerId)
upperDir, err := diskDrv.GetPostOverlayRootUpperDir(s, vol, input.ContainerId, pov)
if err != nil {
return nil, errors.Wrapf(err, "get post overlay root upper dir: %s", jsonutils.Marshal(pov))
}