Coverage for manila/share/drivers/windows/windows_smb_driver.py: 97%

80 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright (c) 2015 Cloudbase Solutions SRL 

2# All Rights Reserved. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); you may 

5# not use this file except in compliance with the License. You may obtain 

6# a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

13# License for the specific language governing permissions and limitations 

14# under the License. 

15 

16import os 

17 

18from oslo_log import log 

19from oslo_utils import units 

20 

21from manila.share import driver as base_driver 

22from manila.share.drivers import generic 

23from manila.share.drivers.windows import service_instance 

24from manila.share.drivers.windows import windows_smb_helper 

25from manila.share.drivers.windows import windows_utils 

26from manila.share.drivers.windows import winrm_helper 

27 

28 

29LOG = log.getLogger(__name__) 

30 

31 

32class WindowsSMBDriver(generic.GenericShareDriver): 

33 # NOTE(lpetrut): The first partition will be reserved by the OS. 

34 _DEFAULT_SHARE_PARTITION = 2 

35 

36 def __init__(self, *args, **kwargs): 

37 super(WindowsSMBDriver, self).__init__(*args, **kwargs) 

38 LOG.warning('Windows SMB share driver has been deprecated and is ' 

39 'expected to be removed in a future release.') 

40 

41 self._remote_execute = winrm_helper.WinRMHelper( 

42 configuration=self.configuration).execute 

43 self._windows_utils = windows_utils.WindowsUtils( 

44 remote_execute=self._remote_execute) 

45 self._smb_helper = windows_smb_helper.WindowsSMBHelper( 

46 remote_execute=self._remote_execute, 

47 configuration=self.configuration) 

48 

49 def _update_share_stats(self, data=None): 

50 base_driver.ShareDriver._update_share_stats( 

51 self, data=dict(storage_protocol="CIFS")) 

52 

53 def _setup_service_instance_manager(self): 

54 self.service_instance_manager = ( 

55 service_instance.WindowsServiceInstanceManager( 

56 driver_config=self.configuration)) 

57 

58 def _setup_helpers(self): 

59 self._helpers = {key: self._smb_helper for key in ("SMB", "CIFS")} 

60 

61 def _teardown_server(self, server_details, security_services=None): 

62 security_service = ( 

63 self.service_instance_manager.get_valid_security_service( 

64 security_services)) 

65 if server_details.get('joined_domain') and security_service: 65 ↛ 77line 65 didn't jump to line 77 because the condition on line 65 was always true

66 try: 

67 self._windows_utils.unjoin_domain(server_details, 

68 security_service['user'], 

69 security_service['password']) 

70 except Exception as exc: 

71 LOG.warning("Failed to remove service instance " 

72 "%(instance_id)s from domain %(domain)s. " 

73 "Exception: %(exc)s.", 

74 dict(instance_id=server_details['instance_id'], 

75 domain=security_service['domain'], 

76 exc=exc)) 

77 super(WindowsSMBDriver, self)._teardown_server(server_details, 

78 security_services) 

79 

80 def _format_device(self, server_details, volume): 

81 disk_number = self._get_disk_number(server_details, volume) 

82 self._windows_utils.initialize_disk(server_details, disk_number) 

83 self._windows_utils.create_partition(server_details, disk_number) 

84 self._windows_utils.format_partition( 

85 server_details, disk_number, 

86 self._DEFAULT_SHARE_PARTITION) 

87 

88 def _mount_device(self, share, server_details, volume): 

89 mount_path = self._get_mount_path(share) 

90 if not self._is_device_mounted(mount_path, server_details, volume): 90 ↛ exitline 90 didn't return from function '_mount_device' because the condition on line 90 was always true

91 disk_number = self._get_disk_number(server_details, volume) 

92 self._windows_utils.ensure_directory_exists(server_details, 

93 mount_path) 

94 self._ensure_disk_online_and_writable(server_details, disk_number) 

95 self._windows_utils.add_access_path(server_details, 

96 mount_path, 

97 disk_number, 

98 self._DEFAULT_SHARE_PARTITION) 

99 

100 def _unmount_device(self, share, server_details): 

101 mount_path = self._get_mount_path(share) 

102 disk_number = self._windows_utils.get_disk_number_by_mount_path( 

103 server_details, mount_path) 

104 

105 self._windows_utils.remove(server_details, mount_path, 

106 is_junction=True) 

107 if disk_number: 107 ↛ exitline 107 didn't return from function '_unmount_device' because the condition on line 107 was always true

108 self._windows_utils.set_disk_online_status( 

109 server_details, disk_number, online=False) 

110 

111 def _resize_filesystem(self, server_details, volume, new_size=None): 

112 disk_number = self._get_disk_number(server_details, volume) 

113 self._ensure_disk_online_and_writable(server_details, disk_number) 

114 

115 if not new_size: 

116 new_size_bytes = self._windows_utils.get_partition_maximum_size( 

117 server_details, disk_number, self._DEFAULT_SHARE_PARTITION) 

118 else: 

119 new_size_bytes = new_size * units.Gi 

120 

121 self._windows_utils.resize_partition(server_details, 

122 new_size_bytes, 

123 disk_number, 

124 self._DEFAULT_SHARE_PARTITION) 

125 

126 def _ensure_disk_online_and_writable(self, server_details, disk_number): 

127 self._windows_utils.update_disk(server_details, disk_number) 

128 self._windows_utils.set_disk_readonly_status( 

129 server_details, disk_number, readonly=False) 

130 self._windows_utils.set_disk_online_status( 

131 server_details, disk_number, online=True) 

132 

133 def _get_mounted_share_size(self, mount_path, server_details): 

134 total_bytes = self._windows_utils.get_disk_space_by_path( 

135 server_details, mount_path)[0] 

136 return float(total_bytes) / units.Gi 

137 

138 def _get_consumed_space(self, mount_path, server_details): 

139 total_bytes, free_bytes = self._windows_utils.get_disk_space_by_path( 

140 server_details, mount_path) 

141 return float(total_bytes - free_bytes) / units.Gi 

142 

143 def _get_mount_path(self, share): 

144 mount_path = os.path.join(self.configuration.share_mount_path, 

145 share['name']) 

146 return self._windows_utils.normalize_path(mount_path) 

147 

148 def _get_disk_number(self, server_details, volume): 

149 disk_number = self._windows_utils.get_disk_number_by_serial_number( 

150 server_details, volume['id']) 

151 if disk_number is None: 

152 LOG.debug("Could not identify the mounted disk by serial number " 

153 "using the volume id %(volume_id)s. Attempting to " 

154 "retrieve it by the volume mount point %(mountpoint)s.", 

155 dict(volume_id=volume['id'], 

156 mountpoint=volume['mountpoint'])) 

157 # Assumes the mount_point will be something like /dev/hdX 

158 mount_point = volume['mountpoint'] 

159 disk_number = ord(mount_point[-1]) - ord('a') 

160 return disk_number 

161 

162 def _is_device_mounted(self, mount_path, server_details, volume=None): 

163 disk_number = self._windows_utils.get_disk_number_by_mount_path( 

164 server_details, mount_path) 

165 return disk_number is not None