]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/trash.py
4 from contextlib
import contextmanager
8 from .template
import GroupTemplate
9 from ..fs_util
import listdir
10 from ..exception
import VolumeException
12 log
= logging
.getLogger(__name__
)
14 class Trash(GroupTemplate
):
15 GROUP_NAME
= "_deleting"
17 def __init__(self
, fs
, vol_spec
):
19 self
.vol_spec
= vol_spec
20 self
.groupname
= Trash
.GROUP_NAME
24 return os
.path
.join(self
.vol_spec
.base_dir
.encode('utf-8'), self
.groupname
.encode('utf-8'))
27 def unique_trash_path(self
):
29 return a unique trash directory entry path
31 return os
.path
.join(self
.path
, str(uuid
.uuid4()).encode('utf-8'))
33 def _get_single_dir_entry(self
, exclude_list
=[]):
34 exclude_list
.extend((b
".", b
".."))
36 with self
.fs
.opendir(self
.path
) as d
:
37 entry
= self
.fs
.readdir(d
)
39 if entry
.d_name
not in exclude_list
and entry
.is_dir():
41 entry
= self
.fs
.readdir(d
)
43 except cephfs
.Error
as e
:
44 raise VolumeException(-e
.args
[0], e
.args
[1])
46 def get_trash_entry(self
, exclude_list
):
48 get a trash entry excluding entries provided.
50 :praram exclude_list: entries to exclude
53 return self
._get
_single
_dir
_entry
(exclude_list
)
55 def purge(self
, trash_entry
, should_cancel
):
59 :praram trash_entry: the trash entry to purge
60 :praram should_cancel: callback to check if the purge should be aborted
63 def rmtree(root_path
):
64 log
.debug("rmtree {0}".format(root_path
))
66 with self
.fs
.opendir(root_path
) as dir_handle
:
67 d
= self
.fs
.readdir(dir_handle
)
68 while d
and not should_cancel():
69 if d
.d_name
not in (b
".", b
".."):
70 d_full
= os
.path
.join(root_path
, d
.d_name
)
74 self
.fs
.unlink(d_full
)
75 d
= self
.fs
.readdir(dir_handle
)
76 except cephfs
.ObjectNotFound
:
78 except cephfs
.Error
as e
:
79 raise VolumeException(-e
.args
[0], e
.args
[1])
80 # remove the directory only if we were not asked to cancel
81 # (else we would fail to remove this anyway)
82 if not should_cancel():
83 self
.fs
.rmdir(root_path
)
85 trashpath
= os
.path
.join(self
.path
, trash_entry
)
86 # catch any unlink errors
89 except cephfs
.Error
as e
:
90 raise VolumeException(-e
.args
[0], e
.args
[1])
94 move an filesystem entity to trash can.
96 :praram path: the filesystem path to be moved
100 self
.fs
.rename(path
, self
.unique_trash_path
)
101 except cephfs
.Error
as e
:
102 raise VolumeException(-e
.args
[0], e
.args
[1])
104 def create_trashcan(fs
, vol_spec
):
108 :param fs: ceph filesystem handle
109 :param vol_spec: volume specification
112 trashcan
= Trash(fs
, vol_spec
)
114 fs
.mkdirs(trashcan
.path
, 0o700)
115 except cephfs
.Error
as e
:
116 raise VolumeException(-e
.args
[0], e
.args
[1])
119 def open_trashcan(fs
, vol_spec
):
121 open a trash can. This API is to be used as a context manager.
123 :param fs: ceph filesystem handle
124 :param vol_spec: volume specification
125 :return: yields a trash can object (subclass of GroupTemplate)
127 trashcan
= Trash(fs
, vol_spec
)
129 fs
.stat(trashcan
.path
)
130 except cephfs
.Error
as e
:
131 raise VolumeException(-e
.args
[0], e
.args
[1])