From aabaaef390b0c6ac4ae05caaac1791ebfe9a0f40 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Tue, 18 Apr 2023 14:02:34 -0700 Subject: [PATCH] admin: include versions of bin Signed-off-by: Varun Patil --- lib/Controller/OtherController.php | 78 +++++++++++++++++++----------- lib/Service/BinExt.php | 35 ++++++++++++-- src/Admin.vue | 26 ++++++---- 3 files changed, 98 insertions(+), 41 deletions(-) diff --git a/lib/Controller/OtherController.php b/lib/Controller/OtherController.php index d5082990..15e9aef9 100644 --- a/lib/Controller/OtherController.php +++ b/lib/Controller/OtherController.php @@ -120,19 +120,16 @@ class OtherController extends GenericApiController $status = []; // Check exiftool version - try { - $s = $this->getExecutableStatus(BinExt::getExiftoolPBin()); - if ('ok' === $s || Util::getSystemConfig('memories.exiftool_no_local')) { - BinExt::testExiftool(); - $s = 'test_ok'; - } - $status['exiftool'] = $s; - } catch (\Exception $e) { - $status['exiftool'] = 'test_fail:'.$e->getMessage(); - } + $exiftoolNoLocal = Util::getSystemConfig('memories.exiftool_no_local'); + $status['exiftool'] = $this->getExecutableStatus( + BinExt::getExiftoolPBin(), + fn ($p) => BinExt::testExiftool(), + !$exiftoolNoLocal, + !$exiftoolNoLocal, + ); // Check for system perl - $status['perl'] = $this->getExecutableStatus(exec('which perl')); + $status['perl'] = $this->getExecutableStatus(exec('which perl'), fn ($p) => BinExt::testSystemPerl($p)); // Check number of indexed files $status['indexed_count'] = $index->getIndexedCount(); @@ -161,20 +158,23 @@ class OtherController extends GenericApiController } // Check ffmpeg and ffprobe binaries - $status['ffmpeg'] = $this->getExecutableStatus(Util::getSystemConfig('memories.vod.ffmpeg')); - $status['ffprobe'] = $this->getExecutableStatus(Util::getSystemConfig('memories.vod.ffprobe')); + $status['ffmpeg'] = $this->getExecutableStatus( + Util::getSystemConfig('memories.vod.ffmpeg'), + fn ($p) => BinExt::testFFmpeg($p, 'ffmpeg'), + ); + $status['ffprobe'] = $this->getExecutableStatus( + Util::getSystemConfig('memories.vod.ffprobe'), + fn ($p) => BinExt::testFFmpeg($p, 'ffprobe'), + ); // Check go-vod binary - try { - $s = $this->getExecutableStatus(BinExt::getGoVodBin()); - if ('ok' === $s || Util::getSystemConfig('memories.vod.external')) { - BinExt::testStartGoVod(); - $s = 'test_ok'; - } - $status['govod'] = $s; - } catch (\Exception $e) { - $status['govod'] = 'test_fail:'.$e->getMessage(); - } + $extGoVod = Util::getSystemConfig('memories.vod.external'); + $status['govod'] = $this->getExecutableStatus( + BinExt::getGoVodBin(), + fn ($p) => BinExt::testStartGoVod(), + !$extGoVod, + !$extGoVod, + ); // Check for VA-API device $devPath = '/dev/dri/renderD128'; @@ -250,16 +250,40 @@ class OtherController extends GenericApiController return $response; } - private function getExecutableStatus(string $path): string - { - if (!is_file($path)) { + /** + * Get the status of an executable. + * + * @param string $path Path to the executable + * @param ?\Closure $testFunction Function to test the executable + * @param bool $testIfFile Test if the path is a file + * @param bool $testIfExecutable Test if the path is executable + */ + private function getExecutableStatus( + $path, + ?\Closure $testFunction = null, + bool $testIfFile = true, + bool $testIfExecutable = true + ): string { + if (!\is_string($path)) { return 'not_found'; } - if (!is_executable($path)) { + if ($testIfFile && !is_file($path)) { + return 'not_found'; + } + + if ($testIfExecutable && !is_executable($path)) { return 'not_executable'; } + if ($testFunction) { + try { + return 'test_ok:'.$testFunction($path); + } catch (\Exception $e) { + return 'test_fail:'.$e->getMessage(); + } + } + return 'ok'; } diff --git a/lib/Service/BinExt.php b/lib/Service/BinExt.php index dd3d659c..ecd973bd 100644 --- a/lib/Service/BinExt.php +++ b/lib/Service/BinExt.php @@ -51,7 +51,7 @@ class BinExt } /** Test configured exiftool binary */ - public static function testExiftool(): bool + public static function testExiftool(): string { $cmd = implode(' ', array_merge(self::getExiftool(), ['-ver'])); $out = shell_exec($cmd); @@ -86,7 +86,7 @@ class BinExt throw new \Exception("Got wrong Exif data from test file {$exp} <==> {$got}"); } - return true; + return $version; } /** Get path to exiftool binary */ @@ -263,7 +263,7 @@ class BinExt /** * Test go-vod and (re)-start if it is not external. */ - public static function testStartGoVod(): bool + public static function testStartGoVod(): string { try { return self::testGoVod(); @@ -280,7 +280,7 @@ class BinExt } /** Test the go-vod instance that is running */ - public static function testGoVod(): bool + public static function testGoVod(): string { // Check if disabled if (Util::getSystemConfig('memories.vod.disable')) { @@ -316,7 +316,7 @@ class BinExt throw new \Exception("version does not match {$version} <==> {$target}"); } - return true; + return $version; } /** POST a new configuration to go-vod */ @@ -398,4 +398,29 @@ class BinExt return $ffmpegPath; } + + public static function testFFmpeg(string $path, string $vername) + { + $version = shell_exec("{$path} -version"); + if (!preg_match("/{$vername} version\\s+([0-9\\.]+)/", $version, $matches)) { + throw new \Exception("failed to detect version, found {$version}"); + } + + $minver = '4.0'; + $semver = $matches[1]; + if (!version_compare($semver, $minver, '>=')) { + throw new \Exception("version must be >= {$minver}, found {$semver}"); + } + + return $semver; + } + + public static function testSystemPerl(string $path): string + { + if (($out = shell_exec("{$path} -e 'print \"OK\";'")) !== 'OK') { + throw new \Exception('Failed to run test perl script: '.$out); + } + + return shell_exec("{$path} -e 'print $^V;'"); + } } diff --git a/src/Admin.vue b/src/Admin.vue index 607f3631..182d4a6d 100644 --- a/src/Admin.vue +++ b/src/Admin.vue @@ -736,6 +736,10 @@ export default defineComponent({ }, binaryStatus(name: string, status: BinaryStatus): string { + const noescape = { + escape: false, + sanitize: false, + }; if (status === "ok") { return this.t("memories", "{name} binary exists and is executable.", { name, @@ -755,15 +759,19 @@ export default defineComponent({ info: status.substring(10), }, 0, - { - escape: false, - sanitize: false, - } + noescape + ); + } else if (status.startsWith("test_ok")) { + return this.t( + "memories", + "{name} binary exists and is usable ({info}).", + { + name, + info: status.substring(8), + }, + 0, + noescape ); - } else if (status === "test_ok") { - return this.t("memories", "{name} binary exists and is usable.", { - name, - }); } else { return this.t("memories", "{name} binary status: {status}.", { name, @@ -773,7 +781,7 @@ export default defineComponent({ }, binaryStatusType(status: BinaryStatus, critical = true): string { - if (status === "ok" || status === "test_ok") { + if (status === "ok" || status.startsWith("test_ok")) { return "success"; } else if ( status === "not_found" ||