]>
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
:
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
, trashpath
, 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 # catch any unlink errors
88 except cephfs
.Error
as e
:
89 raise VolumeException(-e
.args
[0], e
.args
[1])
93 move an filesystem entity to trash can.
95 :praram path: the filesystem path to be moved
99 self
.fs
.rename(path
, self
.unique_trash_path
)
100 except cephfs
.Error
as e
:
101 raise VolumeException(-e
.args
[0], e
.args
[1])
103 def link(self
, path
, bname
):
104 pth
= os
.path
.join(self
.path
, bname
)
106 self
.fs
.symlink(path
, pth
)
107 except cephfs
.Error
as e
:
108 raise VolumeException(-e
.args
[0], e
.args
[1])
110 def delink(self
, bname
):
111 pth
= os
.path
.join(self
.path
, bname
)
114 except cephfs
.Error
as e
:
115 raise VolumeException(-e
.args
[0], e
.args
[1])
117 def create_trashcan(fs
, vol_spec
):
121 :param fs: ceph filesystem handle
122 :param vol_spec: volume specification
125 trashcan
= Trash(fs
, vol_spec
)
127 fs
.mkdirs(trashcan
.path
, 0o700)
128 except cephfs
.Error
as e
:
129 raise VolumeException(-e
.args
[0], e
.args
[1])
132 def open_trashcan(fs
, vol_spec
):
134 open a trash can. This API is to be used as a context manager.
136 :param fs: ceph filesystem handle
137 :param vol_spec: volume specification
138 :return: yields a trash can object (subclass of GroupTemplate)
140 trashcan
= Trash(fs
, vol_spec
)
142 fs
.stat(trashcan
.path
)
143 except cephfs
.Error
as e
:
144 raise VolumeException(-e
.args
[0], e
.args
[1])