Skip to content

Commit 9fbad19

Browse files
authored
Automated cherry pick of #24012: feat(host): mount post overlay layers by shortest path order (#24018)
* fix(host): mount and umount order for post overlay - support host_lower_map for post overlay image * feat(host): tar dirs of pod with include patterns
1 parent aaeb09f commit 9fbad19

File tree

17 files changed

+296
-43
lines changed

17 files changed

+296
-43
lines changed

pkg/apis/compute/backup.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ type DiskBackupDetails struct {
126126

127127
type DiskBackupAsTarInput struct {
128128
IncludeFiles []string `json:"include_files"`
129+
IncludePatterns []string `json:"include_patterns"`
129130
ExcludeFiles []string `json:"exclude_files"`
130131
ContainerId string `json:"container_id"`
131132
IgnoreNotExistFile bool `json:"ignore_not_exist_file"`

pkg/apis/compute/container.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ type ContainerSaveVolumeMountToImageInput struct {
218218
Dirs []string `json:"dirs"`
219219
UsedByPostOverlay bool `json:"used_by_post_overlay"`
220220

221-
DirPrefix string `json:"dir_prefix"`
221+
DirPrefix string `json:"dir_prefix"`
222+
ExcludePaths []string `json:"exclude_paths"`
222223
}
223224

224225
type ContainerExecInfoOutput struct {

pkg/apis/container.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,16 @@ func (o ContainerVolumeMountDiskOverlay) IsValid() error {
262262
return nil
263263
}
264264

265+
type HostLowerPath struct {
266+
PrePath string `json:"pre_path"`
267+
PostPath string `json:"post_path"`
268+
}
269+
265270
type ContainerVolumeMountDiskPostImageOverlay struct {
266271
Id string `json:"id"`
267272
PathMap map[string]string `json:"path_map"`
273+
// 宿主机底层目录映射, key 为 PathMap 的 key,value 为 overlay lower 格式,多目录以 ":" 分隔
274+
HostLowerMap map[string]*HostLowerPath `json:"host_lower_map"`
268275
}
269276

270277
type ContainerVolumeMountDiskPostImageOverlayUnpacker ContainerVolumeMountDiskPostImageOverlay
@@ -277,6 +284,7 @@ func (ov *ContainerVolumeMountDiskPostImageOverlay) UnmarshalJSON(data []byte) e
277284
ov.Id = nov.Id
278285
// 防止 PathMap 被合并,总是用 Unarmshal data 里面的 path_map
279286
ov.PathMap = nov.PathMap
287+
ov.HostLowerMap = nov.HostLowerMap
280288
return nil
281289
}
282290

@@ -295,6 +303,7 @@ type ContainerVolumeMountDiskPostOverlay struct {
295303
Image *ContainerVolumeMountDiskPostImageOverlay `json:"image"`
296304
FsUser *int64 `json:"fs_user,omitempty"`
297305
FsGroup *int64 `json:"fs_group,omitempty"`
306+
FlattenLayers bool `json:"flatten_layers"`
298307
}
299308

300309
func (o ContainerVolumeMountDiskPostOverlay) IsEqual(input ContainerVolumeMountDiskPostOverlay) bool {

pkg/apis/host/container.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ type ContainerSaveVolumeMountToImageInput struct {
147147
VolumeMount *ContainerVolumeMount `json:"volume_mount"`
148148
VolumeMountDirs []string `json:"volume_mount_dirs"`
149149

150-
VolumeMountPrefix string `json:"volume_mount_prefix"`
150+
VolumeMountPrefix string `json:"volume_mount_prefix"`
151+
ExcludePaths []string `json:"exclude_paths"`
151152
}
152153

153154
type ContainerCommitInput struct {

pkg/compute/container_drivers/volume_mount/disk_pov_image.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ func (p povImage) validateData(ctx context.Context, userCred mcclient.TokenCrede
7171
if len(pov.Image.PathMap) == 0 {
7272
pov.Image.PathMap = pathMap
7373
}
74+
if len(pov.Image.HostLowerMap) != 0 {
75+
for hostPath, _ := range pov.Image.HostLowerMap {
76+
_, ok := pov.Image.PathMap[hostPath]
77+
if !ok {
78+
return httperrors.NewNotFoundError("host_path %s of host_lower_map doesn't found in path_map", hostPath)
79+
}
80+
}
81+
}
7482
return nil
7583
}
7684

pkg/compute/guestdrivers/base.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"yunion.io/x/pkg/util/fileutils"
3030
"yunion.io/x/pkg/util/osprofile"
3131
"yunion.io/x/pkg/util/regutils"
32+
"yunion.io/x/pkg/utils"
3233

3334
api "yunion.io/x/onecloud/pkg/apis/compute"
3435
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
@@ -716,3 +717,10 @@ func (base *SBaseGuestDriver) BeforeAttachIsolatedDevice(ctx context.Context, cr
716717
func (base *SBaseGuestDriver) RequestUploadGuestStatus(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
717718
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestUploadGuestStatus")
718719
}
720+
721+
func (base *SBaseGuestDriver) CanStop(guest *models.SGuest) error {
722+
if utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED, api.POD_STATUS_CRASH_LOOP_BACK_OFF, api.POD_STATUS_CONTAINER_EXITED, api.VM_KICKSTART_INSTALLING, api.VM_KICKSTART_FAILED, api.VM_KICKSTART_COMPLETED}) {
723+
return nil
724+
}
725+
return errors.Wrapf(errors.ErrInvalidStatus, "Cannot stop server in status %s", guest.Status)
726+
}

pkg/compute/guestdrivers/pod.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,13 @@ func (p *SPodDriver) OnGuestDeployTaskDataReceived(ctx context.Context, guest *m
329329
return nil
330330
}
331331

332+
func (p *SPodDriver) CanStop(guest *models.SGuest) error {
333+
if guest.PowerStates == api.VM_POWER_STATES_ON {
334+
return nil
335+
}
336+
return p.SKVMGuestDriver.CanStop(guest)
337+
}
338+
332339
func (p *SPodDriver) StartGuestStopTask(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
333340
task, err := taskman.TaskManager.NewTask(ctx, "PodStopTask", guest, userCred, params, parentTaskId, "", nil)
334341
if err != nil {

pkg/compute/models/containers.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,15 @@ func (c *SContainer) StartCreateTask(ctx context.Context, userCred mcclient.Toke
482482
return task.ScheduleRun(nil)
483483
}
484484

485-
func (c *SContainer) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ContainerUpdateInput) (*api.ContainerUpdateInput, error) {
485+
// func (c *SContainer) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ContainerUpdateInput) (*api.ContainerUpdateInput, error) {
486+
func (c *SContainer) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (*api.ContainerUpdateInput, error) {
486487
if !api.ContainerExitedStatus.Has(c.GetStatus()) {
487488
return nil, httperrors.NewInvalidStatusError("current status %s is not in %v", c.GetStatus(), api.ContainerExitedStatus.List())
488489
}
490+
input := new(api.ContainerUpdateInput)
491+
if err := data.Unmarshal(input); err != nil {
492+
return nil, errors.Wrap(err, "Unmarshal")
493+
}
489494

490495
baseInput, err := c.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input.VirtualResourceBaseUpdateInput)
491496
if err != nil {
@@ -968,6 +973,7 @@ func (c *SContainer) PerformSaveVolumeMountImage(ctx context.Context, userCred m
968973

969974
VolumeMountDirs: cleanupDirPaths(input.Dirs),
970975
VolumeMountPrefix: cleanupDirPath(input.DirPrefix),
976+
ExcludePaths: cleanupDirPaths(input.ExcludePaths),
971977
}
972978

973979
return hostInput, c.StartSaveVolumeMountImage(ctx, userCred, hostInput, "")

pkg/compute/models/guest_actions.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3857,14 +3857,20 @@ func (self *SGuest) PerformStatus(ctx context.Context, userCred mcclient.TokenCr
38573857
// 关机
38583858
func (self *SGuest) PerformStop(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject,
38593859
input api.ServerStopInput) (jsonutils.JSONObject, error) {
3860-
// XXX if is force, force stop guest
3861-
if input.IsForce || utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED, api.POD_STATUS_CRASH_LOOP_BACK_OFF, api.POD_STATUS_CONTAINER_EXITED, api.VM_KICKSTART_INSTALLING, api.VM_KICKSTART_FAILED, api.VM_KICKSTART_COMPLETED}) {
3862-
if err := self.ValidateEncryption(ctx, userCred); err != nil {
3863-
return nil, errors.Wrap(httperrors.ErrForbidden, "encryption key not accessible")
3860+
drv, err := self.GetDriver()
3861+
if err != nil {
3862+
return nil, errors.Wrap(err, "GetDriver")
3863+
}
3864+
if !input.IsForce {
3865+
err := drv.CanStop(self)
3866+
if err != nil {
3867+
return nil, errors.Wrap(err, "Cannot stop server")
38643868
}
3865-
return nil, self.StartGuestStopTask(ctx, userCred, input.TimeoutSecs, input.IsForce, input.StopCharging, "")
38663869
}
3867-
return nil, httperrors.NewInvalidStatusError("Cannot stop server in status %s", self.Status)
3870+
if err := self.ValidateEncryption(ctx, userCred); err != nil {
3871+
return nil, errors.Wrap(httperrors.ErrForbidden, "encryption key not accessible")
3872+
}
3873+
return nil, self.StartGuestStopTask(ctx, userCred, input.TimeoutSecs, input.IsForce, input.StopCharging, "")
38683874
}
38693875

38703876
// 冻结虚拟机

pkg/compute/models/guestdrivers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type IGuestDriver interface {
8484

8585
RequestGuestCreateInsertIso(ctx context.Context, imageId string, bootIndex *int8, task taskman.ITask, guest *SGuest) error
8686

87+
CanStop(guest *SGuest) error
8788
StartGuestStopTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error
8889
StartGuestResetTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, isHard bool, parentTaskId string) error
8990
StartGuestRestartTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, isForce bool, parentTaskId string) error

0 commit comments

Comments
 (0)