mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-31 02:38:07 +08:00
fix(region,host): validate and umount container's backup tar file (#21179)
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -290,11 +291,26 @@ func (dm *SDiskBackupManager) ValidateCreateData(
|
||||
return input, httperrors.NewNotFoundError("fetch container by %s", input.BackupAsTar.ContainerId)
|
||||
}
|
||||
input.BackupAsTar.ContainerId = ctr.GetId()
|
||||
if err := dm.validateBackupAsTarFiles(input.BackupAsTar.IncludeFiles); err != nil {
|
||||
return input, httperrors.NewInputParameterError("validate include_files: %s", err)
|
||||
}
|
||||
if err := dm.validateBackupAsTarFiles(input.BackupAsTar.ExcludeFiles); err != nil {
|
||||
return input, httperrors.NewInputParameterError("validate exclude_files: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (dm *SDiskBackupManager) validateBackupAsTarFiles(paths []string) error {
|
||||
for _, p := range paths {
|
||||
if strings.HasPrefix(p, "/") {
|
||||
return httperrors.NewInputParameterError("%s can't start with /", p)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *SDiskBackup) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
input := new(api.DiskBackupCreateInput)
|
||||
if err := data.Unmarshal(input); err != nil {
|
||||
|
||||
+28
-18
@@ -1851,28 +1851,38 @@ func (s *sPodGuestInstance) DoSnapshot(ctx context.Context, params *SDiskSnapsho
|
||||
return nil, errors.Wrapf(err, "bind mount %s to %s: %s", mntPath, targetBindMntPath, out)
|
||||
}
|
||||
}
|
||||
deferUmount := func() error {
|
||||
for _, vol := range vols {
|
||||
// unbind mount
|
||||
// umount
|
||||
targetBindMntPath := filepath.Join(tmpBackRootDir, vol.Disk.SubDirectory)
|
||||
if vol.Disk.StorageSizeFile != "" {
|
||||
targetBindMntPath = filepath.Join(tmpBackRootDir, vol.Disk.StorageSizeFile)
|
||||
}
|
||||
out, err := procutils.NewRemoteCommandAsFarAsPossible("umount", targetBindMntPath).Output()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "umount bind point %s: %s", targetBindMntPath, out)
|
||||
}
|
||||
}
|
||||
for _, vol := range vols {
|
||||
drv := volume_mount.GetDriver(vol.Type)
|
||||
if err := drv.Unmount(s, input.ContainerId, vol); err != nil {
|
||||
return errors.Wrapf(err, "unmount %s to %s", input.ContainerId, jsonutils.Marshal(vol))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
if err := deferUmount(); err != nil {
|
||||
log.Errorf("deferUmount after snapshot error: %s", err)
|
||||
} else {
|
||||
log.Infof("defer umount success")
|
||||
}
|
||||
}()
|
||||
snapshotPath, err := s.createSnapshot(params, tmpBackRootDir)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create snapshot")
|
||||
}
|
||||
for _, vol := range vols {
|
||||
// unbind mount
|
||||
// umount
|
||||
targetBindMntPath := filepath.Join(tmpBackRootDir, vol.Disk.SubDirectory)
|
||||
if vol.Disk.StorageSizeFile != "" {
|
||||
targetBindMntPath = filepath.Join(tmpBackRootDir, vol.Disk.StorageSizeFile)
|
||||
}
|
||||
out, err := procutils.NewRemoteCommandAsFarAsPossible("umount", targetBindMntPath).Output()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "umount bind point %s: %s", targetBindMntPath, out)
|
||||
}
|
||||
}
|
||||
for _, vol := range vols {
|
||||
drv := volume_mount.GetDriver(vol.Type)
|
||||
if err := drv.Unmount(s, input.ContainerId, vol); err != nil {
|
||||
return nil, errors.Wrapf(err, "unmount %s to %s", input.ContainerId, jsonutils.Marshal(vol))
|
||||
}
|
||||
}
|
||||
res := jsonutils.NewDict()
|
||||
res.Set("location", jsonutils.NewString(snapshotPath))
|
||||
return res, nil
|
||||
|
||||
Reference in New Issue
Block a user