We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
/ ///////////////////////////////////////////////////////////////////////////////
/**
glued-stor/glued/Controllers/ServiceController.php
Line 210 in 4926e38
} /// /////////////////////////////////////////////////////////////////////////////// /// DEVICES /// /////////////////////////////////////////////////////////////////////////////// /** * @param $d array device config * @return array */ public function device_status(array $d): array { $d['uri'] = $d['path']; $missingKeys = array_diff_key(array_flip(["uuid", "adapter", "uri"]), $d); if (!empty($missingKeys)) { $s = implode(', ', array_keys($missingKeys)); throw new Exception("Device status requested without {$s} defined."); } $msg = []; $s = [ "health" => "unknown", "message" => [] ]; if (!$this->is_uuidv4($d["uuid"])) { $s["health"] = "degraded"; $msg[] = "Device key `{$d["uuid"]}` is not a UUIDv4."; } if ( $d["adapter"] == "filesystem" and PHP_OS == "Linux") { if (is_dir($d["uri"] ?? "")) { $output = json_decode(shell_exec("findmnt -DJv --output fstype,source,target,fsroot,options,size,used,avail,use%,uuid,partuuid --target " . $d["path"])); $s["adapter"] = (array) $output->filesystems[0]; if (is_writable($d["uri"])) { $s["health"] = "online"; $msg[] = "ok"; } else { $s["health"] = "degraded"; $msg[] = "path `{$d["path"]}` is not writable"; } } else { $d["health"] = "offline"; $msg[] = "`{$d["path"]}` is not a directory or is missing"; } } $s['message'] = implode('; ', $msg); if ($s["health"] != "online") { $this->notify->send("Storage device `{$d["uuid"]}` `{$s["health"]}`: {$s["message"]}", notify_admins: true); } return $s; } function findDeviceDgs($data, $uuid) { $res = []; foreach ($data as $item) { foreach (($item['devices'] ?? []) as $k => $device) { if ($device['uuid'] === $uuid) { $subres = $item['devices'][$k]; $subres['uuid'] = $item['uuid']; $res[] = $subres; break; // Stop searching for this device once found } } } return $res; } public function devices($uuid = null, $log = true) { $res = $this->settings["stor"]["devices"]; $dgs = $this->dgs(); $key = "09e0ef57-86e6-4376-b466-a7d2af31474e"; if (array_key_exists($key, $res)) { $res[$key]["path"] = $this->settings["glued"]["datapath"] . "/" . basename(__ROOT__) . "/data"; } $key = "86159ff5-f513-4852-bb3a-7f4657a35301"; if (array_key_exists($key, $res)) { $res[$key]["path"] = sys_get_temp_dir(); } if ($uuid) { if (array_key_exists($uuid,$res)) { $res = array_intersect_key($res, [$uuid => null]); // return $res containing the only key, $uuid } else return []; } foreach ($res as $k=>&$v) { $v["uuid"] = $k; $v["status"] = $this->device_status($v); $v["status"]["dgs"] = $this->findDeviceDgs($dgs, $k); } if ($log == 1) { $q1 = "INSERT INTO `t_stor_devices` (`uuid`, `data`) VALUES (uuid_to_bin(?, true), ?) ON DUPLICATE KEY UPDATE `data` = VALUES(`data`)"; $q2 = "INSERT IGNORE INTO `t_stor_configlog` (`uuid`, `data`) VALUES (uuid_to_bin(?, true), ?) ON DUPLICATE KEY UPDATE `ts_logged` = CURRENT_TIMESTAMP(1)"; $q3 = "INSERT INTO `t_stor_statuslog` (`uuid_dev`, `data`, `uuid_dg`, `role`, `prio`) VALUES (uuid_to_bin(?, true), ?, uuid_to_bin(?, true), ?, ?) ON DUPLICATE KEY UPDATE `ts_updated` = CURRENT_TIMESTAMP(1);"; $s1 = $this->mysqli->prepare($q1); $s2 = $this->mysqli->prepare($q2); $s3 = $this->mysqli->prepare($q3); foreach ($res as $k => $vv) { $s = $vv['status'] ?? []; unset($vv['status']); $vv = json_encode($vv ?? []); $this->mysqli->begin_transaction(); $s1->bind_param("ss", $k, $vv); $s1->execute(); $s2->bind_param("ss", $k, $vv); $s2->execute(); foreach ($s["dgs"] as $dg) { $ss = json_encode($s); $s3->bind_param("ssssd", $k, $ss, $dg['uuid'],$dg['role'],$dg['prio']); $s3->execute(); } $this->mysqli->commit(); } } $res = array_values($res); if (!is_null($uuid)) { return $res[0]; } return $res; } public function devices_r1(Request $request, Response $response, array $args = []): Response { $res = $this->devices($args['id'] ?? null); if ($res == []) { return $response->withJson(['message' => "Not found."])->withStatus(404); } return $response->withJson(['data' => $res]); } /// /////////////////////////////////////////////////////////////////////////////// /// DGS /// /////////////////////////////////////////////////////////////////////////////// function get_dg_uuid($uuid) { //if ($uuid == 'default') { $uuid = $this->get_default_dg(); } if (array_key_exists($uuid, $this->settings['stor']['dgs'])) { return $uuid; } throw new Exception("Dg `{$uuid}` used as device parent but not configured.", 500); // TODO replace with notification } public function dgs($uuid = null, $log = true) { $dgs = $this->settings['stor']['dgs'] ?? []; foreach ($dgs as $key => &$item) { $item['uuid'] = $key; if (!array_key_exists('devices', $item)) { $item['devices'] = []; } // Process each "device" and validate "uuid" foreach ($item['devices'] as $k => &$device) { if (isset($device['uuid'])) { $device['prio'] = isset($device['prio']) ? $device['prio'] : 1000; if (!$this->is_uuidv4($device['uuid'])) { // Handle case where "uuid" is not set or is not a valid UUIDv4 (remove entry) $item['status']['message'][] = "Device UUID {$device['uuid']} is not a valid UUID string."; unset($item['devices'][$k]); if (!array_key_exists($device['uuid'], $this->settings['stor']['devices'])) { $item['status']['message'][] = "Device {$device['uuid']} undefined."; unset($item['devices'][$k]); } } } else { $item['status']['message'][] = "Dg contains a device item without the mandatory uuid."; } } // Remove any null values caused by invalid devices $item['devices'] = array_values(array_filter($item['devices'])); $item['status']['members'] = count($item['devices']); // Sort devices by "prio" if ($item['status']['members'] > 0) { usort($item['devices'], function ($a, $b) { return $a['prio'] - $b['prio']; }); } else { $item['status']['message'][] = "Dg doesn't have any devices configured."; } } if ($log == true) { $q1 = "INSERT INTO `t_stor_dgs` (`uuid`, `data`) VALUES (uuid_to_bin(?, true), ?) ON DUPLICATE KEY UPDATE `data` = VALUES(`data`)"; $q2 = "INSERT IGNORE INTO `t_stor_configlog` (`uuid`, `data`) VALUES (uuid_to_bin(?, true), ?)"; foreach ($dgs as $k => &$v) { $vv = $v; unset($vv['status']); $data = [$k, json_encode($vv ?? [])]; $this->mysqli->begin_transaction(); $this->mysqli->execute_query($q1, $data); if ($this->mysqli->affected_rows > 0) { $v['log'] = "New dg `{$k}` configured."; } $this->mysqli->execute_query($q2, $data); if ($this->mysqli->affected_rows > 0) { $v['log'] = "Dg `{$k}` configuration updated."; } $this->mysqli->commit(); } } $res = array_values($dgs); if (!is_null($uuid)) { return $res[0]; } return $res; } public function dgs_r1(Request $request, Response $response, array $args = []): Response { $res = $this->dgs($args['id'] ?? null); if ($res == []) { return $response->withJson(['message' => "Not found."])->withStatus(404); } return $response->withJson(['data' => $res]); } /// /////////////////////////////////////////////////////////////////////////////// /// BUCKETS /// /////////////////////////////////////////////////////////////////////////////// public function get_buckets($bucket = null): array { $where = ''; if (!is_null($bucket)) { $where = 'WHERE bucket = uuid_to_bin(?, true)'; $arg = [ $bucket ]; } $q = " SELECT bin_to_uuid(b.`uuid`, 1) AS `bucket`, b.name AS `name`, bin_to_uuid(bd.`dg`, 1) AS `dg`, s.dg_health, s.dev_uuid, s.dev_health, s.dev_prio, s.dev_role, s.dev_adapter, s.status_ts as ts FROM `t_stor_buckets` b LEFT JOIN t_stor_bucket_dgs bd ON bd.bucket = b.uuid LEFT JOIN ( SELECT dg_uuid, dg_health, dev_uuid, dev_health, status_ts, dev_prio, dev_role, dev_adapter FROM v_stor_status ) s ON s.dg_uuid = bin_to_uuid(bd.dg, 1) {$where} ORDER BY bucket, CASE WHEN s.dev_health = 'online' THEN 0 ELSE 1 END, dev_prio "; $res = $this->mysqli->execute_query($q, $arg ?? []); $data = $res->fetch_all(MYSQLI_ASSOC); $unflat = []; foreach ($data as $row) { // Check if the bucket already exists in the unflattened result if (!isset($unflat[$row['bucket']])) { // If not, create a new entry for the bucket $unflat[$row['bucket']] = [ 'uuid' => $row['bucket'], 'name' => $row['name'], 'ts' => $row['ts'], 'dgs' => [], 'devices' => [], ]; } // Check if the dg already exists in the dgs array $dgExists = false; foreach ($unflat[$row['bucket']]['dgs'] as &$dgArray) { if ($dgArray['uuid'] === $row['dg']) { $dgExists = true; break; } } // If the dg does not exist, create a new entry for dg if (!$dgExists) { $unflat[$row['bucket']]['dgs'][] = [ 'uuid' => $row['dg'], 'health' => $row['dg_health'], ]; } // Check if the dg already exists in the dgs array $devExists = false; foreach ($unflat[$row['bucket']]['devices'] as &$devArray) { if ($devArray['uuid'] === $row['dev_uuid']) { $devExists = true; break; } } // If the dg does not exist, create a new entry for dg if (!$devExists) { $unflat[$row['bucket']]['devices'][] = [ 'uuid' => $row['dev_uuid'], 'health' => $row['dev_health'], 'role' => $row['dev_role'], 'prio' => $row['dev_prio'], 'adapter' => $row['dev_adapter'], ]; } } $res = array_values($unflat); if (!is_null($bucket)) { $res = $res[0]; } return $res; } public function buckets_r1(Request $request, Response $response, array $args = []): Response { $params = $request->getQueryParams(); $unflat = $this->get_buckets($args['id'] ?? null); $data = [ 'timestamp' => microtime(), 'status' => 'Buckets r1 OK', 'data' => $unflat, 'service' => basename(__ROOT__), ]; return $response->withJson($data); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
/ ///////////////////////////////////////////////////////////////////////////////
/**
glued-stor/glued/Controllers/ServiceController.php
Line 210 in 4926e38
The text was updated successfully, but these errors were encountered: