Total Complexity | 134 |
Total Lines | 809 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Storage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Storage, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class Storage { |
||
14 | /** |
||
15 | * Получение массива подключенныйх HDD. |
||
16 | * @return array |
||
17 | */ |
||
18 | private function disk_get_devices() { |
||
19 | // TODO // Переписать через использование lsblk. |
||
20 | return explode(" ", trim(exec("/bin/ls /dev | grep '^[a-z]d[a-z]' | tr \"\n\" \" \""))); |
||
21 | } |
||
22 | |||
23 | /** |
||
24 | * Получение массива подключенныйх cdrom. |
||
25 | * @return array |
||
26 | */ |
||
27 | private function cdrom_get_devices() { |
||
28 | return explode(" ", trim(exec('/sbin/sysctl -n dev.cdrom.info | /bin/busybox grep "drive name" | /bin/busybox cut -f 3') )); |
||
29 | } |
||
30 | |||
31 | /** |
||
32 | * Получение сведений по диску. |
||
33 | * @param $disk |
||
34 | * @return string |
||
35 | */ |
||
36 | private function get_vendor_disk($disk){ |
||
37 | $temp_vendor = array(); |
||
38 | if( is_file("/sys/block/".$disk."/device/vendor") ){ |
||
39 | $data = trim(file_get_contents("/sys/block/".$disk."/device/vendor")); |
||
40 | if($data != ''){ |
||
41 | $temp_vendor[] = trim(str_replace(',',' ', $data)); |
||
42 | } |
||
43 | } |
||
44 | if( is_file("/sys/block/".$disk."/device/model") ){ |
||
45 | $data = trim(file_get_contents("/sys/block/".$disk."/device/model")); |
||
46 | if($data != ''){ |
||
47 | $temp_vendor[] = trim(str_replace(',',' ', $data)); |
||
48 | } |
||
49 | } |
||
50 | if(count($temp_vendor) == 0){ |
||
51 | $temp_vendor[] = $disk; |
||
52 | } |
||
53 | if(is_file("/sys/block/".$disk."/device/type")){ |
||
54 | $data = trim(file_get_contents("/sys/block/".$disk."/device/type")); |
||
55 | if($data != ''){ |
||
56 | $temp_vendor[] = trim(str_replace(',',' ', $data)); |
||
57 | } |
||
58 | } |
||
59 | return implode(', ', $temp_vendor); |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Проверка, смонтирован ли диск. |
||
64 | * @param $disk |
||
65 | * @param $filter |
||
66 | * @return bool |
||
67 | */ |
||
68 | static function disk_is_mounted($disk, $filter = '/dev/'){ |
||
|
|||
69 | |||
70 | $out = []; |
||
71 | Util::mwexec("mount | grep '{$filter}{$disk}'", $out); |
||
72 | if(count($out)>0){ |
||
73 | $res_out = end($out); |
||
74 | }else{ |
||
75 | $res_out = implode('', $out); |
||
76 | } |
||
77 | $data = explode(' ', trim($res_out)); |
||
78 | |||
79 | $result = (count($data) > 2) ? $data[2] : false; |
||
80 | return $result; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Возвращает директорию для хранения media файлов. |
||
85 | * @return string |
||
86 | */ |
||
87 | static function get_media_dir(){ |
||
88 | $dir = "/var/asterisk/spool"; |
||
89 | if( Storage::is_storage_disk_mounted() ){ |
||
90 | $storage_dev_file = "{$GLOBALS['g']['varetc_path']}/storage_device"; |
||
91 | if(file_exists($storage_dev_file)){ |
||
92 | $dir = file_get_contents($storage_dev_file); |
||
93 | }else{ |
||
94 | $dir = '/storage/usbdisk1'; |
||
95 | } |
||
96 | } |
||
97 | return $dir; |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Возвращает директорию для хранения файлов записей разговоров. |
||
102 | * @return string |
||
103 | */ |
||
104 | static function get_monitor_dir(){ |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Получаем свободное место на диске в Mb. |
||
112 | * @param $hdd |
||
113 | * @return mixed |
||
114 | */ |
||
115 | public function get_free_space($hdd){ |
||
116 | $out = []; |
||
117 | $hdd = escapeshellarg($hdd); |
||
118 | Util::mwexec("df -m | grep {$hdd} | awk '{print $4}'",$out); |
||
119 | $result = 0; |
||
120 | foreach ($out as $res){ |
||
121 | if(!is_numeric($res)){ |
||
122 | continue; |
||
123 | } |
||
124 | $result += (1*$res); |
||
125 | } |
||
126 | return $result; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Проверка свободного места на дисках. Уведомление в случае проблем. |
||
131 | */ |
||
132 | public function check_free_space(){ |
||
133 | $storage = new Storage(); |
||
134 | $util = new Util(); |
||
135 | $hdd = $storage->get_all_hdd( true ); |
||
136 | // Создание больщого файла для тестов. |
||
137 | // head -c 1500MB /dev/urandom > /storage/usbdisk1/big_file.mp3 |
||
138 | foreach ($hdd as $disk){ |
||
139 | if($disk['sys_disk'] === true && !Storage::is_storage_disk_mounted("{$disk['id']}4")){ |
||
140 | // Это системный диск (4ый раздел). Он не смонтирован. |
||
141 | continue; |
||
142 | } |
||
143 | |||
144 | $free = ($disk['free_space'] / $disk['size']*100); |
||
145 | $need_alert = false; $test_alert = ''; |
||
146 | if($free < 5){ |
||
147 | $need_alert = true; |
||
148 | $test_alert = "The {$disk['id']} has less than 5% of free space available."; |
||
149 | } |
||
150 | |||
151 | if($disk['free_space'] < 500){ |
||
152 | $need_alert = true; |
||
153 | $test_alert = "The {$disk['id']} has less than 500MB of free space available."; |
||
154 | } |
||
155 | |||
156 | if($disk['free_space'] < 100){ |
||
157 | $need_alert = true; |
||
158 | $test_alert = "The {$disk['id']} has less than 100MB of free space available. Old call records will be deleted."; |
||
159 | Util::mwexec_bg('/usr/bin/php -f /etc/inc/workers/worker_remove_old_records.php'); |
||
160 | } |
||
161 | |||
162 | if(!$need_alert){ |
||
163 | continue; |
||
164 | } |
||
165 | |||
166 | Util::sys_log_msg("STORAGE", $test_alert); |
||
167 | $data = [ |
||
168 | 'Device - ' => "/dev/{$disk['id']}", |
||
169 | 'Directoire - ' => "{$disk['mounted']}", |
||
170 | 'Desciption - ' => $test_alert, |
||
171 | ]; |
||
172 | // Добавляем задачу на уведомление. |
||
173 | $util->add_job_to_beanstalk('notify_error_storage', $data); |
||
174 | } |
||
175 | |||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Возвращает все подключенные HDD. |
||
180 | * @param bool $mounted_only |
||
181 | * @return array |
||
182 | */ |
||
183 | public function get_all_hdd($mounted_only = false){ |
||
184 | global $g; |
||
185 | $res_disks = []; |
||
186 | |||
187 | $cd_disks= $this->cdrom_get_devices(); |
||
188 | $cd_disks= array_unique($cd_disks); |
||
189 | |||
190 | // TODO Получение данных о дисках в формате JSON: |
||
191 | // lsblk -J -b -o VENDOR,MODEL,SERIAL,LABEL,TYPE,FSTYPE,MOUNTPOINT,SUBSYSTEMS,NAME,UUID |
||
192 | $disks = $this->disk_get_devices(); |
||
193 | $disks = array_unique($disks); |
||
194 | |||
195 | $cf_disk = ''; |
||
196 | if(file_exists($g['varetc_path'].'/cfdevice')){ |
||
197 | $cf_disk = trim(file_get_contents($g['varetc_path'].'/cfdevice')); |
||
198 | } |
||
199 | |||
200 | foreach ($disks as $disk) { |
||
201 | if(in_array($disk, $cd_disks)){ |
||
202 | // Это CD-ROM. |
||
203 | continue; |
||
204 | } |
||
205 | unset($temp_vendor, $temp_size, $original_size); |
||
206 | $mounted = Storage::disk_is_mounted("{$disk}"); |
||
207 | if($mounted_only == true && $mounted == false){ |
||
208 | continue; |
||
209 | } |
||
210 | $sys_disk = ($cf_disk == $disk)? true : false; |
||
211 | |||
212 | $mb_size = 0; |
||
213 | if(is_file("/sys/block/".$disk."/size")){ |
||
214 | $original_size = trim(file_get_contents("/sys/block/".$disk."/size")); |
||
215 | $original_size = ($original_size*512/1024/1024); |
||
216 | $mb_size = $original_size; |
||
217 | } |
||
218 | if($mb_size > 100){ |
||
219 | $temp_size = sprintf("%.0f MB",$mb_size); |
||
220 | $temp_vendor = $this->get_vendor_disk($disk); |
||
221 | $free_space = $this->get_free_space($disk); |
||
222 | |||
223 | $arr_disk_info = $this->determine_format_fs($disk); |
||
224 | if(count($arr_disk_info)>0){ |
||
225 | $used = 0; |
||
226 | foreach ($arr_disk_info as $disk_info){ |
||
227 | $used += $disk_info['used_space']; |
||
228 | } |
||
229 | if($used>0){ |
||
230 | $free_space = $mb_size - $used; |
||
231 | } |
||
232 | } |
||
233 | |||
234 | $res_disks[] = [ |
||
235 | 'id' => $disk, |
||
236 | 'size' => $mb_size, |
||
237 | 'size_text' => $temp_size, |
||
238 | 'vendor' => $temp_vendor, |
||
239 | 'mounted' => $mounted, |
||
240 | 'free_space'=> $free_space, |
||
241 | 'partitions'=> $arr_disk_info, |
||
242 | 'sys_disk' => $sys_disk |
||
243 | ]; |
||
244 | } |
||
245 | |||
246 | } |
||
247 | |||
248 | return $res_disks; |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Проверка, смонтирован ли диск - хранилище. |
||
253 | * @param string $filter |
||
254 | * @param string $mount_dir |
||
255 | * @return bool |
||
256 | */ |
||
257 | static function is_storage_disk_mounted($filter='', & $mount_dir=''){ |
||
258 | if('' == $filter){ |
||
259 | $res_disk = null; |
||
260 | $filename = "{$GLOBALS['g']['varetc_path']}/storage_device"; |
||
261 | if(file_exists($filename)){ |
||
262 | $filter = file_get_contents($filename); |
||
263 | }else{ |
||
264 | $filter = 'usbdisk1'; |
||
265 | } |
||
266 | } |
||
267 | $filter = escapeshellarg($filter); |
||
268 | |||
269 | $out = []; |
||
270 | Util::mwexec("mount | grep {$filter} | awk '{print $3}'", $out); |
||
271 | $mount_dir = trim(implode('', $out)); |
||
272 | |||
273 | return ($mount_dir == '') ? false : true; |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * Получение идентификатора устройства. |
||
278 | * @param $device |
||
279 | * @return bool |
||
280 | */ |
||
281 | public function get_uuid($device){ |
||
282 | if (strlen($device) == 0) { |
||
283 | return false; |
||
284 | } |
||
285 | $res = Util::mwexec("/sbin/blkid -ofull {$device} | /bin/busybox sed -r 's/[[:alnum:]]+=/\\n&/g' | /bin/busybox grep \"^UUID\" | /bin/busybox awk -F \"\\\"\" '{print $2}' | /usr/bin/head -n 1", $output); |
||
286 | if ($res == 0 && count($output)>0) { |
||
287 | $result = $output[0]; |
||
288 | } |
||
289 | else { |
||
290 | $result = false; |
||
291 | } |
||
292 | |||
293 | return $result; |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Форматирование диска. |
||
298 | * @param string $device |
||
299 | * @param bool $bg |
||
300 | * @return mixed |
||
301 | */ |
||
302 | private function format_disk_local_part2($device, $bg = false){ |
||
303 | if (is_numeric(substr($device, -1))) { |
||
304 | $device_id = ""; |
||
305 | }else { |
||
306 | $device_id = "1"; |
||
307 | } |
||
308 | $format = 'ext4'; |
||
309 | $cmd = "/sbin/mkfs.{$format} {$device}{$device_id}"; |
||
310 | if($bg == false){ |
||
311 | openlog("storage_format_disk", LOG_NDELAY, LOG_DAEMON); |
||
312 | Util::mwexec("$cmd 2>&1", $out, $retval); |
||
313 | syslog(LOG_NOTICE, "mkfs.{$format} returned $retval"); |
||
314 | closelog(); |
||
315 | }else{ |
||
316 | usleep(200000); |
||
317 | Util::mwexec_bg("$cmd"); |
||
318 | $retval = true; |
||
319 | } |
||
320 | |||
321 | return $retval; |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * Разметка диска. |
||
326 | * @param string $device |
||
327 | * @param bool $bg |
||
328 | * @return mixed |
||
329 | */ |
||
330 | public function format_disk_local($device, $bg = false){ |
||
331 | openlog("storage", LOG_NDELAY, LOG_DAEMON); |
||
332 | // overwrite with fresh DOS partition table |
||
333 | Util::mwexec("echo \"o\n" . |
||
334 | // create new |
||
335 | "n\n" . |
||
336 | // primary partition |
||
337 | "p\n" . |
||
338 | // number 1 |
||
339 | "1\n" . |
||
340 | // from the beginning |
||
341 | "\n" . |
||
342 | // to the end |
||
343 | "\n" . |
||
344 | // change type |
||
345 | /* |
||
346 | "t\n" . |
||
347 | // to FAT32 |
||
348 | "b\n" . |
||
349 | // set active |
||
350 | "a\n" . |
||
351 | // partition 1 |
||
352 | "1\n" . |
||
353 | */ |
||
354 | // and write changes |
||
355 | "w\n" . |
||
356 | "\" | fdisk " . $device, $out, $retval); |
||
357 | syslog(LOG_NOTICE, "fdisk returned " . $retval); |
||
358 | closelog(); |
||
359 | |||
360 | if(false == $bg){ |
||
361 | sleep(1); |
||
362 | } |
||
363 | return $this->format_disk_local_part2($device, $bg); |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Монтирование разделов диска с базой данных настроек. |
||
368 | */ |
||
369 | public function configure(){ |
||
370 | |||
371 | $cf_disk = ''; |
||
372 | $storage_dev_file = "{$GLOBALS['g']['varetc_path']}/storage_device"; |
||
373 | if(file_exists($storage_dev_file)){ |
||
374 | unlink($storage_dev_file); |
||
375 | } |
||
376 | |||
377 | if(file_exists($GLOBALS['g']['varetc_path'].'/cfdevice')){ |
||
378 | $cf_disk = trim(file_get_contents($GLOBALS['g']['varetc_path'].'/cfdevice')); |
||
379 | } |
||
380 | |||
381 | $disks = $this->get_disk_settings(); |
||
382 | $conf = ''; |
||
383 | foreach ($disks as $disk) { |
||
384 | clearstatcache(); |
||
385 | if( $disk['device'] !== "/dev/{$cf_disk}" ){ |
||
386 | // Если это обычный диск, то раздел 1. |
||
387 | $dev = "{$disk['device']}1"; |
||
388 | }else{ |
||
389 | // Если это системный диск, то пытаемся подключить раздел 4. |
||
390 | $dev = "{$disk['device']}4"; |
||
391 | } |
||
392 | if( !$this->hdd_exists($dev) ){ |
||
393 | // Диск не существует. |
||
394 | continue; |
||
395 | } |
||
396 | if($disk['media'] === '1' || !file_exists($storage_dev_file)){ |
||
397 | file_put_contents($storage_dev_file, "/storage/usbdisk{$disk['id']}"); |
||
398 | } |
||
399 | |||
400 | $str_uid = 'UUID='.$this->get_uuid($dev).''; |
||
401 | $format_p4 = self::get_fs_type($dev); |
||
402 | $conf .= "{$str_uid} /storage/usbdisk{$disk['id']} {$format_p4} async,rw 0 0\n"; |
||
403 | $is_mounted = $this->is_storage_disk_mounted("/storage/usbdisk{$disk['id']}"); |
||
404 | $mount_point = "/storage/usbdisk{$disk['id']}"; |
||
405 | if (!file_exists($mount_point)) { |
||
406 | Util::mwexec("mkdir -p {$mount_point}"); |
||
407 | } |
||
408 | } |
||
409 | $this->save_fstab($conf); |
||
410 | System::setup_php_log(); |
||
411 | |||
412 | $util = new Util(); |
||
413 | $util->create_work_dirs(); |
||
414 | } |
||
415 | |||
416 | public static function disable_need_check_storage():void { |
||
417 | try{ |
||
418 | // Проверка диска не требуется. |
||
419 | $pbxSettings = \Models\Storage::find(); |
||
420 | /** @var \Models\Storage $pbxSettings */ |
||
421 | /** @var \Models\Storage $row */ |
||
422 | foreach ($pbxSettings as $row){ |
||
423 | $row->check_when_booting = 0; |
||
424 | $row->save(); |
||
425 | } |
||
426 | }catch (Exception $e){ |
||
427 | Util::sys_log_msg('Reboot: Storage ', $e->getMessage()); |
||
428 | } |
||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Проверяет, существует ли диск в массиве. |
||
433 | * @param $disk |
||
434 | * @return bool |
||
435 | */ |
||
436 | private function hdd_exists($disk){ |
||
437 | $result = false; |
||
438 | $uid = $this->get_uuid("{$disk}"); |
||
439 | if(file_exists("{$disk}") && $uid !== false){ |
||
440 | $result = true; |
||
441 | } |
||
442 | return $result; |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * Генерация файла fstab. Монтирование разделов. |
||
447 | * @param string $conf |
||
448 | */ |
||
449 | public function save_fstab($conf=''){ |
||
450 | global $g; |
||
451 | // Точка монтирования доп. дисков. |
||
452 | Util::mwexec("mkdir -p /storage/"); |
||
453 | if(! file_exists($g['varetc_path'].'/cfdevice')){ |
||
454 | return; |
||
455 | } |
||
456 | $fstab = ''; |
||
457 | $file_data = file_get_contents($g['varetc_path'].'/cfdevice'); |
||
458 | $cf_disk = trim($file_data); |
||
459 | if('' == $cf_disk){ |
||
460 | return; |
||
461 | } |
||
462 | // $part1 = (strpos($cf_disk, "mmcblk") !== false)?"{$cf_disk}p1":"{$cf_disk}1"; // Boot |
||
463 | $part2 = (strpos($cf_disk, "mmcblk") !== false)?"{$cf_disk}p2":"{$cf_disk}2"; // Offload |
||
464 | $part3 = (strpos($cf_disk, "mmcblk") !== false)?"{$cf_disk}p3":"{$cf_disk}3"; // Conf |
||
465 | |||
466 | |||
467 | $uid_part2 = 'UUID='.$this->get_uuid("/dev/{$part2}").''; |
||
468 | $format_p2 = Storage::get_fs_type($part2); |
||
469 | $uid_part3 = 'UUID='.$this->get_uuid("/dev/{$part3}").''; |
||
470 | $format_p3 = Storage::get_fs_type($part3); |
||
471 | |||
472 | // $fstab .= "/dev/{$part1} {$g['cf_path']} msdos ro 1 1\n"; // НЕ МОНТИРУЕМ! |
||
473 | $fstab .= "{$uid_part2} /offload {$format_p2} ro 0 0\n"; |
||
474 | $fstab .= "{$uid_part3} {$g['cf_path']} {$format_p3} rw 1 1\n"; |
||
475 | $fstab .= $conf; |
||
476 | |||
477 | file_put_contents("/etc/fstab", $fstab); |
||
478 | // Дублируем для работы vmtoolsd. |
||
479 | file_put_contents("/etc/mtab", $fstab); |
||
480 | Util::mwexec("mount -a 2> /dev/null"); |
||
481 | Util::mwexec("chown -R www:www /cf/ > /dev/null 2> /dev/null"); |
||
482 | } |
||
483 | |||
484 | /** |
||
485 | * Получаем настройки диска из базы данных. |
||
486 | * @param string $id |
||
487 | * @return array |
||
488 | */ |
||
489 | public function get_disk_settings($id=''){ |
||
490 | $data = array(); |
||
491 | if('' === $id){ |
||
492 | $pbxSettings = \Models\Storage::find(); |
||
493 | if($pbxSettings){ |
||
494 | // Возвращаем данные до модификации. |
||
495 | $data = $pbxSettings->toArray(); |
||
496 | } |
||
497 | }else{ |
||
498 | $pbxSettings = Models\Storage::findFirst("id='$id'"); |
||
499 | if($pbxSettings){ |
||
500 | $data = $pbxSettings->toArray(); |
||
501 | } |
||
502 | } |
||
503 | return $data; |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Сохраняем новые данные диска. |
||
508 | * @param $data |
||
509 | * @param int $id |
||
510 | */ |
||
511 | public function save_disk_settings($data, $id = '1'){ |
||
512 | if(!is_array($data)) return; |
||
513 | $disk_data = $this->get_disk_settings($id); |
||
514 | if(count($disk_data) === 0){ |
||
515 | $uniqid = strtoupper('STORAGE-DISK-' . md5( time() ) ); |
||
516 | $storage_settings = new Models\Storage(); |
||
517 | foreach ($data as $key => $val) { |
||
518 | $storage_settings->writeAttribute($key, $val); |
||
519 | } |
||
520 | $storage_settings->writeAttribute('uniqid', $uniqid); |
||
521 | $storage_settings->save(); |
||
522 | |||
523 | }else{ |
||
524 | $storage_settings = Models\Storage::findFirst("id = '$id'"); |
||
525 | foreach ($data as $key => $value){ |
||
526 | $storage_settings->writeAttribute($key, $value); |
||
527 | } |
||
528 | $storage_settings->save(); |
||
529 | } |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * Прверяем является ли диск хранилищем. |
||
534 | * @param $device |
||
535 | * @return bool |
||
536 | */ |
||
537 | static function is_storage_disk($device){ |
||
538 | $result = false; |
||
539 | if(!file_exists("{$device}")){ |
||
540 | return $result; |
||
541 | } |
||
542 | |||
543 | $tmp_dir = '/tmp/mnt_'.time(); |
||
544 | |||
545 | if(!file_exists($tmp_dir) && !mkdir($tmp_dir, 0777, true) && !is_dir($tmp_dir)){ |
||
546 | Util::sys_log_msg('Storage', 'Unable to create directory '. $tmp_dir); |
||
547 | return $result; |
||
548 | } |
||
549 | $out = []; |
||
550 | |||
551 | $storage = new Storage(); |
||
552 | $uid_part = 'UUID='.$storage->get_uuid($device).''; |
||
553 | $format = self::get_fs_type($device); |
||
554 | |||
555 | Util::mwexec("mount -t {$format} {$uid_part} {$tmp_dir}", $out); |
||
556 | if(is_dir("{$tmp_dir}/mikopbx") && trim(implode('', $out)) === ''){ |
||
557 | // $out - пустая строка, ошибок нет |
||
558 | // присутствует каталог mikopbx. |
||
559 | $result = true; |
||
560 | } |
||
561 | if(self::is_storage_disk_mounted($device)){ |
||
562 | Util::mwexec("umount {$device}"); |
||
563 | } |
||
564 | |||
565 | if(!self::is_storage_disk_mounted($device)){ |
||
566 | Util::mwexec("rm -rf '{$tmp_dir}'"); |
||
567 | } |
||
568 | return $result; |
||
569 | } |
||
570 | |||
571 | /** |
||
572 | * Определить формат файловой системы и размер дисков. |
||
573 | * @param $device |
||
574 | * @return array|bool |
||
575 | */ |
||
576 | public function determine_format_fs($device){ |
||
577 | $allow_formats = ['ext2', 'ext4', 'fat', 'ntfs', 'msdos']; |
||
578 | $device = str_replace('/dev/', '', $device); |
||
579 | $devices = explode(" ", trim(exec("/bin/ls /dev | grep '{$device}' | tr \"\n\" \" \""))); |
||
580 | |||
581 | $result_data = []; |
||
582 | foreach ($devices as $dev) { |
||
583 | if(empty($dev) || (count($devices)>1 && $device == $dev) || is_dir("/sys/block/{$dev}")){ |
||
584 | continue; |
||
585 | } |
||
586 | $mb_size = 0; |
||
587 | $path_size_info = ''; |
||
588 | $tmp_path = "/sys/block/{$device}/{$dev}/size"; |
||
589 | if(file_exists($tmp_path)) { |
||
590 | $path_size_info = $tmp_path; |
||
591 | } |
||
592 | if(empty($path_size_info)){ |
||
593 | $tmp_path = "/sys/block/".substr($dev,0,3)."/{$dev}/size"; |
||
594 | if(file_exists($tmp_path)) { |
||
595 | $path_size_info = $tmp_path; |
||
596 | } |
||
597 | } |
||
598 | |||
599 | if(!empty($path_size_info)){ |
||
600 | $original_size = trim(file_get_contents($path_size_info)); |
||
601 | $original_size = ($original_size*512/1024/1024); |
||
602 | $mb_size = $original_size; |
||
603 | } |
||
604 | |||
605 | $tmp_dir = "/tmp/{$dev}_" . time(); |
||
606 | $out = []; |
||
607 | |||
608 | $fs = null; |
||
609 | $need_unmount = false; |
||
610 | $mount_dir = ''; |
||
611 | if(Storage::is_storage_disk_mounted("/dev/{$dev} ", $mount_dir)){ |
||
612 | Util::mwexec("mount | grep '/dev/{$dev}' | awk '{print $5}'", $out); |
||
613 | $fs = trim(implode("", $out)); |
||
614 | $fs = ($fs == 'fuseblk')?'ntfs':$fs; |
||
615 | $free_space = $this->get_free_space("/dev/{$dev} "); |
||
616 | $used_space = $mb_size - $free_space; |
||
617 | }else{ |
||
618 | $format = Storage::get_fs_type($device); |
||
619 | if(in_array($format, $allow_formats)){ |
||
620 | $fs = $format; |
||
621 | } |
||
622 | Storage::mount_disk($dev, $format, $tmp_dir); |
||
623 | |||
624 | $need_unmount = true; |
||
625 | $used_space = Util::get_size_file("$tmp_dir"); |
||
626 | } |
||
627 | $result_data[] = [ |
||
628 | "dev" => $dev, |
||
629 | 'size' => round($mb_size, 2), |
||
630 | "used_space" => round($used_space, 2), |
||
631 | "free_space" => round($mb_size - $used_space, 2), |
||
632 | "uuid" => $this->get_uuid("/dev/{$dev} "), |
||
633 | "fs" => $fs, |
||
634 | ]; |
||
635 | if($need_unmount){ |
||
636 | Storage::umount_disk($tmp_dir); |
||
637 | } |
||
638 | } |
||
639 | |||
640 | return $result_data; |
||
641 | } |
||
642 | |||
643 | /** |
||
644 | * Возвращает тип файловой системы блочного устройства. |
||
645 | * @param $device |
||
646 | * @return string |
||
647 | */ |
||
648 | static function get_fs_type($device){ |
||
649 | $device = str_replace('/dev/', '', $device); |
||
650 | $out = []; |
||
651 | Util::mwexec("/sbin/blkid -ofull /dev/{$device} | /bin/busybox sed -r 's/[[:alnum:]]+=/\\n&/g' | /bin/busybox grep \"^TYPE=\" | /bin/busybox awk -F \"\\\"\" '{print $2}'", $out); |
||
652 | $format = implode('', $out); |
||
653 | if($format == 'msdosvfat') $format='msdos'; |
||
654 | return $format; |
||
655 | } |
||
656 | |||
657 | /** |
||
658 | * Монтирует диск в указанный каталог. |
||
659 | * @param $dev |
||
660 | * @param $format |
||
661 | * @param $dir |
||
662 | * @return bool |
||
663 | */ |
||
664 | static function mount_disk($dev, $format, $dir){ |
||
665 | if(Storage::is_storage_disk_mounted("/dev/{$dev} ")){ |
||
666 | return true; |
||
667 | } |
||
668 | if(!file_exists($dir)){ |
||
669 | @mkdir($dir, 0777, true); |
||
670 | } |
||
671 | if(!file_exists($dir)){ |
||
672 | Util::sys_log_msg('Storage', "Unable mount $dev $format to $dir. Unable create dir."); |
||
673 | return false; |
||
674 | } |
||
675 | $dev = str_replace('/dev/', '', $dev); |
||
676 | if('ntfs' == $format){ |
||
677 | Util::mwexec("mount.ntfs-3g /dev/{$dev} {$dir}", $out); |
||
678 | }else{ |
||
679 | $storage = new Storage(); |
||
680 | $uid_part = 'UUID='.$storage->get_uuid("/dev/{$dev}").''; |
||
681 | Util::mwexec("mount -t {$format} {$uid_part} {$dir}", $out); |
||
682 | } |
||
683 | return Storage::is_storage_disk_mounted("/dev/{$dev} "); |
||
684 | } |
||
685 | |||
686 | /** |
||
687 | * Монитирование каталога с удаленного сервера SFTP. |
||
688 | * @param $host |
||
689 | * @param int $port |
||
690 | * @param string $user |
||
691 | * @param string $pass |
||
692 | * @param string $remout_dir |
||
693 | * @param string $local_dir |
||
694 | * @return bool |
||
695 | */ |
||
696 | static function mount_sftp_disk($host, $port, $user, $pass, $remout_dir, $local_dir){ |
||
697 | if(!file_exists($local_dir)){ |
||
698 | mkdir($local_dir, 0777, true); |
||
699 | } |
||
700 | |||
701 | $out = []; |
||
702 | $command = "/usr/bin/timeout -t 3 /usr/bin/sshfs -p {$port} -o nonempty -o password_stdin -o 'StrictHostKeyChecking=no' ". |
||
703 | "{$user}@{$host}:{$remout_dir} {$local_dir} << EOF\n". |
||
704 | "{$pass}\n". |
||
705 | "EOF\n"; |
||
706 | // file_put_contents('/tmp/sshfs_'.$host, $command); |
||
707 | Util::mwexec($command,$out); |
||
708 | $response = trim(implode('', $out)); |
||
709 | if('Terminated' == $response){ |
||
710 | // Удаленный сервер не ответил / или не корректно указан пароль. |
||
711 | unset($response); |
||
712 | } |
||
713 | |||
714 | return Storage::is_storage_disk_mounted("$local_dir "); |
||
715 | } |
||
716 | |||
717 | /** |
||
718 | * Монитирование каталога с удаленного сервера FTP. |
||
719 | * @param $host |
||
720 | * @param $port |
||
721 | * @param $user |
||
722 | * @param $pass |
||
723 | * @param string $remout_dir |
||
724 | * @param $local_dir |
||
725 | * @return bool |
||
726 | */ |
||
727 | static function mount_ftp($host, $port, $user, $pass, $remout_dir, $local_dir){ |
||
728 | if(!file_exists($local_dir)){ |
||
729 | mkdir($local_dir, 0777, true); |
||
730 | } |
||
731 | $out = []; |
||
732 | |||
733 | // Собираем строку подключения к ftp. |
||
734 | $auth_line = ''; |
||
735 | if(!empty($user)){ |
||
736 | $auth_line.='user="'.$user; |
||
737 | if(!empty($pass)){ |
||
738 | $auth_line.=":{$pass}"; |
||
739 | } |
||
740 | $auth_line.='",'; |
||
741 | } |
||
742 | |||
743 | $connect_line = 'ftp://'.$host; |
||
744 | if(!empty($port)){ |
||
745 | $connect_line.=":{$port}"; |
||
746 | } |
||
747 | if(!empty($remout_dir)){ |
||
748 | $connect_line.="$remout_dir"; |
||
749 | } |
||
750 | |||
751 | $command = "/usr/bin/timeout -t 3 /usr/bin/curlftpfs -o allow_other -o {$auth_line}fsname={$host} {$connect_line} {$local_dir}"; |
||
752 | Util::mwexec($command,$out); |
||
753 | $response = trim(implode('', $out)); |
||
754 | if('Terminated' === $response){ |
||
755 | // Удаленный сервер не ответил / или не корректно указан пароль. |
||
756 | unset($response); |
||
757 | } |
||
758 | |||
759 | return Storage::is_storage_disk_mounted("$local_dir "); |
||
760 | } |
||
761 | |||
762 | /** |
||
763 | * Размонтирует диск. Удаляет каталог в случае успеха. |
||
764 | * @param $dir |
||
765 | * @return bool |
||
766 | */ |
||
767 | static function umount_disk($dir){ |
||
778 | } |
||
779 | |||
780 | /** |
||
781 | * Запускает процесс форматирования диска. |
||
782 | * @param $dev |
||
783 | * @return array|bool |
||
784 | */ |
||
785 | static function mkfs_disk($dev){ |
||
805 | } |
||
806 | } |
||
807 | |||
808 | /** |
||
809 | * Возвращает текущий статус форматирования диска. |
||
810 | * @param $dev |
||
811 | * @return string |
||
812 | */ |
||
813 | static function status_mkfs($dev){ |
||
822 | } |
||
823 | } |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.