]>
git.proxmox.com Git - ceph.git/blob - ceph/src/python-common/ceph/deployment/drive_selection/selector.py
cdc21caa52ff2a6d6622b6f79f9ead16bd023bee
4 from typing
import List
, Optional
8 from ..inventory
import Device
9 from ..drive_group
import DriveGroupSpec
, DeviceSelection
11 from .filter import FilterGenerator
13 logger
= logging
.getLogger(__name__
)
16 class DriveSelection(object):
18 spec
, # type: DriveGroupSpec
19 disks
, # type: List[Device]
21 self
.disks
= disks
.copy()
24 if self
.spec
.data_devices
.paths
: # type: ignore
25 # re: type: ignore there is *always* a path attribute assigned to DeviceSelection
26 # it's just None if actual drivegroups are used
27 self
._data
= self
.spec
.data_devices
.paths
# type: ignore
28 self
._db
= [] # type: List
29 self
._wal
= [] # type: List
30 self
._journal
= [] # type: List
32 self
._data
= self
.assign_devices(self
.spec
.data_devices
)
33 self
._wal
= self
.assign_devices(self
.spec
.wal_devices
)
34 self
._db
= self
.assign_devices(self
.spec
.db_devices
)
35 self
._journal
= self
.assign_devices(self
.spec
.journal_devices
)
37 def data_devices(self
):
38 # type: () -> List[Device]
41 def wal_devices(self
):
42 # type: () -> List[Device]
46 # type: () -> List[Device]
49 def journal_devices(self
):
50 # type: () -> List[Device]
54 def _limit_reached(device_filter
, len_devices
,
56 # type: (DeviceSelection, int, str) -> bool
57 """ Check for the <limit> property and apply logic
59 If a limit is set in 'device_attrs' we have to stop adding
62 If limit is set (>0) and len(devices) >= limit
64 :param int len_devices: Length of the already populated device set/list
65 :param str disk_path: The disk identifier (for logging purposes)
66 :return: True/False if the device should be added to the list of devices
69 limit
= device_filter
.limit
or 0
71 if limit
> 0 and len_devices
>= limit
:
72 logger
.info("Refuse to add {} due to limit policy of <{}>".format(
78 def _has_mandatory_idents(disk
):
79 # type: (Device) -> bool
80 """ Check for mandatory identification fields
83 logger
.debug("Found matching disk: {}".format(disk
.path
))
87 "Disk {} doesn't have a 'path' identifier".format(disk
))
89 def assign_devices(self
, device_filter
):
90 # type: (Optional[DeviceSelection]) -> List[Device]
91 """ Assign drives based on used filters
93 Do not add disks when:
95 1) Filter didn't match
96 2) Disk doesn't have a mandatory identification item (path)
97 3) The set :limit was reached
99 After the disk was added we make sure not to re-assign this disk
100 for another defined type[wal/db/journal devices]
102 return a sorted(by path) list of devices
105 if not device_filter
:
106 logger
.debug('device_filter is None')
109 if not self
.spec
.data_devices
:
110 logger
.debug('data_devices is None')
113 devices
= list() # type: List[Device]
114 for disk
in self
.disks
:
115 logger
.debug("Processing disk {}".format(disk
.path
))
117 if not disk
.available
:
119 "Ignoring disk {}. Disk is not available".format(disk
.path
))
122 if not self
._has
_mandatory
_idents
(disk
):
124 "Ignoring disk {}. Missing mandatory idents".format(
128 # break on this condition.
129 if self
._limit
_reached
(device_filter
, len(devices
), disk
.path
):
130 logger
.debug("Ignoring disk {}. Limit reached".format(
137 if not all(m
.compare(disk
) for m
in FilterGenerator(device_filter
)):
139 "Ignoring disk {}. Filter did not match".format(
143 logger
.debug('Adding disk {}'.format(disk
.path
))
146 # This disk is already taken and must not be re-assigned.
147 for taken_device
in devices
:
148 if taken_device
in self
.disks
:
149 self
.disks
.remove(taken_device
)
151 return sorted([x
for x
in devices
], key
=lambda dev
: dev
.path
)